crewly 1.20.215 → 1.20.217
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/hooks/agent-status/report.sh +45 -6
- package/config/roles/team-leader/fragments/role-boundary.md +2 -1
- package/config/roles/team-leader/prompt.md +9 -5
- package/config/roles/team-leader/role-boundaries.md +3 -2
- package/config/roles/team-leader/tl-addon.md +9 -5
- package/config/skills/agent/core/ask-owner/SKILL.md +9 -2
- package/config/skills/agent/core/ask-owner/execute.sh +1 -1
- package/config/skills/agent/core/project-tickets/SKILL.md +2 -2
- package/config/skills/agent/core/project-tickets/execute.sh +1 -1
- package/config/skills/agent/core/publish-app/SKILL.md +18 -11
- package/config/skills/agent/core/publish-app/execute.sh +1 -1
- package/config/skills/team-leader/delegate-task/SKILL.md +40 -0
- package/config/skills/team-leader/delegate-task/execute.sh +39 -1
- package/dist/backend/backend/src/constants.d.ts +46 -2
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +46 -2
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts +2 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +26 -3
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +1 -1
- 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 +4 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +32 -0
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-lead-share.controller.d.ts +27 -0
- package/dist/backend/backend/src/controllers/team/team-lead-share.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team/team-lead-share.controller.js +92 -0
- package/dist/backend/backend/src/controllers/team/team-lead-share.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +4 -0
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +6 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision-contract.d.ts +25 -1
- package/dist/backend/backend/src/services/decisions/decision-contract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision-contract.js +39 -2
- package/dist/backend/backend/src/services/decisions/decision-contract.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +17 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +67 -9
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js +57 -10
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-item-card.d.ts +26 -0
- package/dist/backend/backend/src/services/open-items/open-item-card.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-item-card.js +71 -1
- package/dist/backend/backend/src/services/open-items/open-item-card.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.js +6 -3
- package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +46 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts +35 -0
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.js +75 -2
- package/dist/backend/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +10 -6
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +16 -10
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.d.ts +6 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.js +4 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +28 -5
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +42 -20
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +2 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +10 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +7 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +25 -2
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts +5 -1
- package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/spend/spend-cap.service.js +3 -1
- package/dist/backend/backend/src/services/spend/spend-cap.service.js.map +1 -1
- package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts +21 -7
- package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/spend/spend-ledger.service.js +35 -17
- package/dist/backend/backend/src/services/spend/spend-ledger.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +23 -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 +74 -2
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/tl-delegation/lead-share.d.ts +115 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.d.ts.map +1 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.js +175 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.js.map +1 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.wiring.d.ts +32 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.wiring.js +47 -0
- package/dist/backend/backend/src/services/tl-delegation/lead-share.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/tl-delegation/tl-delegation.service.d.ts +207 -0
- package/dist/backend/backend/src/services/tl-delegation/tl-delegation.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/tl-delegation/tl-delegation.service.js +377 -0
- package/dist/backend/backend/src/services/tl-delegation/tl-delegation.service.js.map +1 -0
- package/dist/backend/backend/src/types/decision.types.d.ts +6 -1
- package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/decision.types.js +1 -1
- package/dist/backend/backend/src/utils/defaultPrompts.js +3 -3
- package/dist/backend/backend/src/utils/defaultPrompts.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +46 -2
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +46 -2
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +6 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision-contract.d.ts +25 -1
- package/dist/cli/backend/src/services/decisions/decision-contract.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision-contract.js +39 -2
- package/dist/cli/backend/src/services/decisions/decision-contract.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +17 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +67 -9
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js +57 -10
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-item-card.d.ts +26 -0
- package/dist/cli/backend/src/services/open-items/open-item-card.d.ts.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-item-card.js +71 -1
- package/dist/cli/backend/src/services/open-items/open-item-card.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-items.service.js +6 -3
- package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts +35 -0
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.js +75 -2
- package/dist/cli/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +2 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +7 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +25 -2
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +23 -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 +74 -2
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/types/decision.types.d.ts +6 -1
- package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/decision.types.js +1 -1
- package/frontend/dist/assets/{index-839f4374.js → index-bc4e2a93.js} +260 -260
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-lead delegation: the execution nudge, its counts, and "no member
|
|
3
|
+
* fits" records (crewly#1083, specs/2026-10-04-tl-delegation.md §2, §4).
|
|
4
|
+
*
|
|
5
|
+
* The nudge rides on the Claude Code agent-status hook: each `PostToolUse`
|
|
6
|
+
* reports the tool name, and a lead that edited files
|
|
7
|
+
* {@link TL_DELEGATION_CONSTANTS.EDIT_THRESHOLD} times within
|
|
8
|
+
* {@link TL_DELEGATION_CONSTANTS.WINDOW_MS} gets one note back as hook
|
|
9
|
+
* `additionalContext` — at most once per
|
|
10
|
+
* {@link TL_DELEGATION_CONSTANTS.NUDGE_COOLDOWN_MS}. It never blocks: the
|
|
11
|
+
* tool already ran, and any failure means no note.
|
|
12
|
+
*
|
|
13
|
+
* @module services/tl-delegation/tl-delegation.service
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { TL_DELEGATION_CONSTANTS } from '../../constants.js';
|
|
18
|
+
import { getTeamLeads } from '../../utils/team.utils.js';
|
|
19
|
+
import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
|
|
20
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
21
|
+
import { memberLedgerKeys } from './lead-share.js';
|
|
22
|
+
const AVAILABILITY_ORDER = { idle: 0, stopped: 1, working: 2 };
|
|
23
|
+
const AVAILABILITY_WORDS = {
|
|
24
|
+
idle: 'idle',
|
|
25
|
+
stopped: 'stopped — starts when assigned',
|
|
26
|
+
working: 'working',
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Members best placed to take hands-on work: idle first, then stopped, then
|
|
30
|
+
* working; at most {@link TL_DELEGATION_CONSTANTS.NUDGE_MAX_MEMBERS}.
|
|
31
|
+
*
|
|
32
|
+
* @param members - The lead's members
|
|
33
|
+
* @returns Ranked, capped list
|
|
34
|
+
*/
|
|
35
|
+
export function rankMembersForNudge(members) {
|
|
36
|
+
return [...members]
|
|
37
|
+
.sort((a, b) => AVAILABILITY_ORDER[a.availability] - AVAILABILITY_ORDER[b.availability])
|
|
38
|
+
.slice(0, TL_DELEGATION_CONSTANTS.NUDGE_MAX_MEMBERS);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The nudge text (English harness text).
|
|
42
|
+
*
|
|
43
|
+
* @param edits - Edits counted in the window
|
|
44
|
+
* @param members - The lead's members
|
|
45
|
+
* @returns Note
|
|
46
|
+
*/
|
|
47
|
+
export function buildNudgeText(edits, members) {
|
|
48
|
+
const minutes = Math.round(TL_DELEGATION_CONSTANTS.WINDOW_MS / 60000);
|
|
49
|
+
const named = rankMembersForNudge(members)
|
|
50
|
+
.map((m) => `${m.name} (${m.role}, ${AVAILABILITY_WORDS[m.availability]})`)
|
|
51
|
+
.join(', ');
|
|
52
|
+
return (`${TL_DELEGATION_CONSTANTS.NUDGE_TAG} You have edited files ${edits} times in the last ${minutes} minutes. ` +
|
|
53
|
+
`As team lead, hand hands-on work to a member: ${named}. ` +
|
|
54
|
+
'Any member can do any work that needs no special account, tool or permission — role is a preference, not a limit. ' +
|
|
55
|
+
'Delegate with delegate-task (pass --thread <key> for an owner request, so the member answers the owner in that thread). ' +
|
|
56
|
+
'Keep it only if the change is tiny, every member is busy, or it needs your own judgment — then record why: ' +
|
|
57
|
+
'delegate-task --no-member-fits "<what is missing>" --task "<the work>".');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Local date key (YYYY-MM-DD).
|
|
61
|
+
*
|
|
62
|
+
* @param ms - Epoch ms
|
|
63
|
+
* @returns Day key
|
|
64
|
+
*/
|
|
65
|
+
export function localDayKey(ms) {
|
|
66
|
+
const d = new Date(ms);
|
|
67
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
68
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Trim a free-text field to one line within the cap.
|
|
72
|
+
*
|
|
73
|
+
* @param text - Any text
|
|
74
|
+
* @returns One line, capped
|
|
75
|
+
*/
|
|
76
|
+
function oneLine(text) {
|
|
77
|
+
const flat = text.replace(/\s+/g, ' ').trim();
|
|
78
|
+
const max = TL_DELEGATION_CONSTANTS.MAX_TEXT_CHARS;
|
|
79
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Nudge bookkeeping and kept-work records.
|
|
83
|
+
*/
|
|
84
|
+
export class TlDelegationService {
|
|
85
|
+
static instance = null;
|
|
86
|
+
deps;
|
|
87
|
+
statePath;
|
|
88
|
+
now;
|
|
89
|
+
logger;
|
|
90
|
+
/** session → recent edit times (epoch ms), in-memory only */
|
|
91
|
+
edits = new Map();
|
|
92
|
+
state = null;
|
|
93
|
+
writing = Promise.resolve();
|
|
94
|
+
/**
|
|
95
|
+
* @param deps - Collaborators
|
|
96
|
+
*/
|
|
97
|
+
constructor(deps) {
|
|
98
|
+
this.deps = deps;
|
|
99
|
+
this.statePath = deps.statePath ?? path.join(getCrewlyHomePath(), TL_DELEGATION_CONSTANTS.STATE_FILENAME);
|
|
100
|
+
this.now = deps.now ?? (() => Date.now());
|
|
101
|
+
this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('TlDelegation');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The process instance (built from the team store on first use).
|
|
105
|
+
*
|
|
106
|
+
* @returns Service
|
|
107
|
+
*/
|
|
108
|
+
static getInstance() {
|
|
109
|
+
if (!TlDelegationService.instance) {
|
|
110
|
+
TlDelegationService.instance = new TlDelegationService({ leadContext: cachedLeadContext() });
|
|
111
|
+
}
|
|
112
|
+
return TlDelegationService.instance;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Replace (tests) or clear the process instance.
|
|
116
|
+
*
|
|
117
|
+
* @param service - New instance, or null
|
|
118
|
+
*/
|
|
119
|
+
static setInstance(service) {
|
|
120
|
+
TlDelegationService.instance = service;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A tool call finished in `session`. Returns the nudge to show the agent,
|
|
124
|
+
* or null. Never throws.
|
|
125
|
+
*
|
|
126
|
+
* @param session - Agent session
|
|
127
|
+
* @param toolName - Claude Code tool name
|
|
128
|
+
* @returns Nudge text, or null
|
|
129
|
+
*/
|
|
130
|
+
async observeToolUse(session, toolName) {
|
|
131
|
+
try {
|
|
132
|
+
if (!TL_DELEGATION_CONSTANTS.EDIT_TOOLS.includes(toolName))
|
|
133
|
+
return null;
|
|
134
|
+
const now = this.now();
|
|
135
|
+
const recent = (this.edits.get(session) ?? []).filter((t) => now - t < TL_DELEGATION_CONSTANTS.WINDOW_MS);
|
|
136
|
+
recent.push(now);
|
|
137
|
+
this.edits.set(session, recent);
|
|
138
|
+
if (recent.length < TL_DELEGATION_CONSTANTS.EDIT_THRESHOLD)
|
|
139
|
+
return null;
|
|
140
|
+
const state = this.load();
|
|
141
|
+
const counts = state.nudges[session];
|
|
142
|
+
if (counts?.lastAt !== undefined && now - counts.lastAt < TL_DELEGATION_CONSTANTS.NUDGE_COOLDOWN_MS)
|
|
143
|
+
return null;
|
|
144
|
+
const lead = await this.deps.leadContext(session);
|
|
145
|
+
if (!lead || lead.members.length === 0) {
|
|
146
|
+
// Not a lead: stop counting for it until the window passes.
|
|
147
|
+
this.edits.set(session, []);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const text = buildNudgeText(recent.length, lead.members);
|
|
151
|
+
this.edits.set(session, []);
|
|
152
|
+
const next = { ...(counts ?? { count: 0, followed: 0 }) };
|
|
153
|
+
next.count += 1;
|
|
154
|
+
next.lastAt = now;
|
|
155
|
+
next.pendingSince = now;
|
|
156
|
+
const day = localDayKey(now);
|
|
157
|
+
const days = { ...(next.days ?? {}) };
|
|
158
|
+
days[day] = { count: (days[day]?.count ?? 0) + 1, followed: days[day]?.followed ?? 0 };
|
|
159
|
+
next.days = pruneDays(days, now);
|
|
160
|
+
state.nudges[session] = next;
|
|
161
|
+
this.save();
|
|
162
|
+
this.logger.info('Team lead nudged to delegate', { session, teamId: lead.teamId, edits: recent.length });
|
|
163
|
+
return text;
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
this.logger.debug('Nudge check failed — no nudge', { session, error: err instanceof Error ? err.message : String(err) });
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A work item was delegated. Counts as following a nudge when the
|
|
172
|
+
* delegator was nudged within {@link TL_DELEGATION_CONSTANTS.FOLLOW_WINDOW_MS}.
|
|
173
|
+
*
|
|
174
|
+
* @param delegator - Delegating session
|
|
175
|
+
* @param target - Target session
|
|
176
|
+
* @returns True when it followed a nudge
|
|
177
|
+
*/
|
|
178
|
+
recordDelegation(delegator, target) {
|
|
179
|
+
try {
|
|
180
|
+
if (!delegator || !target || delegator === target)
|
|
181
|
+
return false;
|
|
182
|
+
const state = this.load();
|
|
183
|
+
const counts = state.nudges[delegator];
|
|
184
|
+
if (!counts?.pendingSince)
|
|
185
|
+
return false;
|
|
186
|
+
const now = this.now();
|
|
187
|
+
if (now - counts.pendingSince > TL_DELEGATION_CONSTANTS.FOLLOW_WINDOW_MS) {
|
|
188
|
+
delete counts.pendingSince;
|
|
189
|
+
this.save();
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
counts.followed += 1;
|
|
193
|
+
const day = localDayKey(counts.pendingSince);
|
|
194
|
+
if (counts.days?.[day])
|
|
195
|
+
counts.days[day].followed += 1;
|
|
196
|
+
delete counts.pendingSince;
|
|
197
|
+
this.save();
|
|
198
|
+
this.logger.info('Team lead delegated after a nudge', { delegator, target });
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Record work a lead keeps because no member fits.
|
|
207
|
+
*
|
|
208
|
+
* @param input - Lead session, team, reason, work, optional work item / ticket
|
|
209
|
+
* @returns The stored record
|
|
210
|
+
*/
|
|
211
|
+
recordKeptWork(input) {
|
|
212
|
+
const record = {
|
|
213
|
+
at: new Date(this.now()).toISOString(),
|
|
214
|
+
session: input.session,
|
|
215
|
+
...(input.teamId ? { teamId: input.teamId } : {}),
|
|
216
|
+
reason: oneLine(input.reason),
|
|
217
|
+
work: oneLine(input.work),
|
|
218
|
+
...(input.workItemId ? { workItemId: input.workItemId } : {}),
|
|
219
|
+
...(input.ticket ? { ticket: input.ticket } : {}),
|
|
220
|
+
};
|
|
221
|
+
const state = this.load();
|
|
222
|
+
state.records.push(record);
|
|
223
|
+
if (state.records.length > TL_DELEGATION_CONSTANTS.MAX_RECORDS) {
|
|
224
|
+
state.records.splice(0, state.records.length - TL_DELEGATION_CONSTANTS.MAX_RECORDS);
|
|
225
|
+
}
|
|
226
|
+
this.save();
|
|
227
|
+
this.logger.info('Team lead kept work: no member fits', { session: input.session, teamId: input.teamId });
|
|
228
|
+
return record;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Kept-work records since a time, optionally for one team or set of sessions.
|
|
232
|
+
*
|
|
233
|
+
* @param sinceMs - Lower bound (epoch ms)
|
|
234
|
+
* @param filter - Team id and/or lead sessions (either matches)
|
|
235
|
+
* @returns Records, oldest first
|
|
236
|
+
*/
|
|
237
|
+
keptWorkSince(sinceMs, filter) {
|
|
238
|
+
const sessions = new Set(filter?.sessions ?? []);
|
|
239
|
+
return this.load().records.filter((r) => {
|
|
240
|
+
if ((Date.parse(r.at) || 0) < sinceMs)
|
|
241
|
+
return false;
|
|
242
|
+
if (!filter)
|
|
243
|
+
return true;
|
|
244
|
+
return (filter.teamId !== undefined && r.teamId === filter.teamId) || sessions.has(r.session);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Nudge counts of some sessions: all-time, and for one local day.
|
|
249
|
+
*
|
|
250
|
+
* @param sessions - Lead sessions
|
|
251
|
+
* @param dayMs - A time on the day to report (default: now)
|
|
252
|
+
* @returns Totals and that day's numbers
|
|
253
|
+
*/
|
|
254
|
+
nudgeCounts(sessions, dayMs) {
|
|
255
|
+
const state = this.load();
|
|
256
|
+
const day = localDayKey(dayMs ?? this.now());
|
|
257
|
+
const out = { total: { count: 0, followed: 0 }, day: { count: 0, followed: 0 } };
|
|
258
|
+
for (const s of new Set(sessions)) {
|
|
259
|
+
const c = state.nudges[s];
|
|
260
|
+
if (!c)
|
|
261
|
+
continue;
|
|
262
|
+
out.total.count += c.count;
|
|
263
|
+
out.total.followed += c.followed;
|
|
264
|
+
out.day.count += c.days?.[day]?.count ?? 0;
|
|
265
|
+
out.day.followed += c.days?.[day]?.followed ?? 0;
|
|
266
|
+
}
|
|
267
|
+
return out;
|
|
268
|
+
}
|
|
269
|
+
/** Wait for pending writes (tests, shutdown). */
|
|
270
|
+
async flush() {
|
|
271
|
+
await this.writing;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Load the state once (a missing or broken file starts empty).
|
|
275
|
+
*
|
|
276
|
+
* @returns State
|
|
277
|
+
*/
|
|
278
|
+
load() {
|
|
279
|
+
if (this.state)
|
|
280
|
+
return this.state;
|
|
281
|
+
let parsed = null;
|
|
282
|
+
try {
|
|
283
|
+
parsed = JSON.parse(fs.readFileSync(this.statePath, 'utf8'));
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
parsed = null;
|
|
287
|
+
}
|
|
288
|
+
this.state = {
|
|
289
|
+
version: 1,
|
|
290
|
+
nudges: parsed && typeof parsed.nudges === 'object' && parsed.nudges ? parsed.nudges : {},
|
|
291
|
+
records: Array.isArray(parsed?.records) ? parsed.records : [],
|
|
292
|
+
};
|
|
293
|
+
return this.state;
|
|
294
|
+
}
|
|
295
|
+
/** Write the state (serialized, best-effort). */
|
|
296
|
+
save() {
|
|
297
|
+
const snapshot = JSON.stringify(this.state, null, 2);
|
|
298
|
+
this.writing = this.writing
|
|
299
|
+
.then(async () => {
|
|
300
|
+
await fs.promises.mkdir(path.dirname(this.statePath), { recursive: true });
|
|
301
|
+
const tmp = `${this.statePath}.tmp`;
|
|
302
|
+
await fs.promises.writeFile(tmp, snapshot, 'utf8');
|
|
303
|
+
await fs.promises.rename(tmp, this.statePath);
|
|
304
|
+
})
|
|
305
|
+
.catch((err) => {
|
|
306
|
+
this.logger.warn('Could not save team-lead delegation state', { error: err instanceof Error ? err.message : String(err) });
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Keep only the last 14 days of per-day counts.
|
|
312
|
+
*
|
|
313
|
+
* @param days - Day key → counts
|
|
314
|
+
* @param now - Clock
|
|
315
|
+
* @returns Pruned map
|
|
316
|
+
*/
|
|
317
|
+
function pruneDays(days, now) {
|
|
318
|
+
const oldest = localDayKey(now - 14 * 24 * 60 * 60 * 1000);
|
|
319
|
+
return Object.fromEntries(Object.entries(days).filter(([k]) => k >= oldest));
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The availability of a member, as the nudge words it.
|
|
323
|
+
*
|
|
324
|
+
* @param m - Member
|
|
325
|
+
* @returns Availability
|
|
326
|
+
*/
|
|
327
|
+
export function memberAvailability(m) {
|
|
328
|
+
if (m.agentStatus === 'inactive' || m.agentStatus === 'suspended')
|
|
329
|
+
return 'stopped';
|
|
330
|
+
return m.workingStatus === 'in_progress' ? 'working' : 'idle';
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* The lead context of a session among teams: the team it leads, with its
|
|
334
|
+
* other members. Null when it leads no team with other members.
|
|
335
|
+
*
|
|
336
|
+
* @param teams - Teams
|
|
337
|
+
* @param session - Agent session
|
|
338
|
+
* @returns Context, or null
|
|
339
|
+
*/
|
|
340
|
+
export function leadContextFromTeams(teams, session) {
|
|
341
|
+
for (const team of teams) {
|
|
342
|
+
if (team.archived)
|
|
343
|
+
continue;
|
|
344
|
+
const leads = getTeamLeads(team);
|
|
345
|
+
if (!leads.some((l) => memberLedgerKeys(l).includes(session)))
|
|
346
|
+
continue;
|
|
347
|
+
const leadIds = new Set(leads.map((l) => l.id));
|
|
348
|
+
const members = (team.members ?? [])
|
|
349
|
+
.filter((m) => !leadIds.has(m.id) && m.role !== 'orchestrator')
|
|
350
|
+
.map((m) => ({ name: m.name, role: String(m.role), availability: memberAvailability(m) }));
|
|
351
|
+
if (members.length === 0)
|
|
352
|
+
continue;
|
|
353
|
+
return { teamId: team.id, teamName: team.name, members };
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Lead context from the team store, cached per session for a minute (the
|
|
359
|
+
* hook calls this on every file edit).
|
|
360
|
+
*
|
|
361
|
+
* @returns Lookup
|
|
362
|
+
*/
|
|
363
|
+
function cachedLeadContext() {
|
|
364
|
+
const cache = new Map();
|
|
365
|
+
const TTL = 60 * 1000;
|
|
366
|
+
return async (session) => {
|
|
367
|
+
const hit = cache.get(session);
|
|
368
|
+
if (hit && Date.now() - hit.at < TTL)
|
|
369
|
+
return hit.value;
|
|
370
|
+
const { StorageService } = await import('../core/storage.service.js');
|
|
371
|
+
const teams = await StorageService.getInstance().getTeams().catch(() => []);
|
|
372
|
+
const value = leadContextFromTeams(teams, session);
|
|
373
|
+
cache.set(session, { at: Date.now(), value });
|
|
374
|
+
return value;
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=tl-delegation.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tl-delegation.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/tl-delegation/tl-delegation.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Decision cards — structured owner questions (specs/2026-10-01-decision-cards.md).
|
|
3
3
|
*
|
|
4
|
-
* An agent that needs the owner asks ONE question with 2–
|
|
4
|
+
* An agent that needs the owner asks ONE question with 2–5 options, a default
|
|
5
5
|
* and a deadline. The responsible agent's own Slack bot posts it as a card in
|
|
6
6
|
* the team channel (ticket thread, or a new thread), and the owner answers
|
|
7
7
|
* with a button, a reaction or a thread reply. The decision is stored here
|
|
@@ -71,6 +71,11 @@ export interface DecisionOption {
|
|
|
71
71
|
label: string;
|
|
72
72
|
/** Optional one-line detail shown under the question */
|
|
73
73
|
detail?: string;
|
|
74
|
+
/**
|
|
75
|
+
* The agent's full question this option stands for (either/or cards derived
|
|
76
|
+
* from consecutive reply questions): quoted back to the agent when chosen.
|
|
77
|
+
*/
|
|
78
|
+
question?: string;
|
|
74
79
|
}
|
|
75
80
|
/** Lifecycle of a decision. */
|
|
76
81
|
export type DecisionStatus =
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decision.types.d.ts","sourceRoot":"","sources":["../../../../../backend/src/types/decision.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAElH;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,GAAG,WAAW,GAAG,sBAAsB,GAAG,oBAAoB,CAAC;AAE/I,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjD,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,oEAAoE;AACpE,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"decision.types.d.ts","sourceRoot":"","sources":["../../../../../backend/src/types/decision.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Decision cards — structured owner questions (specs/2026-10-01-decision-cards.md).
|
|
3
3
|
*
|
|
4
|
-
* An agent that needs the owner asks ONE question with 2–
|
|
4
|
+
* An agent that needs the owner asks ONE question with 2–5 options, a default
|
|
5
5
|
* and a deadline. The responsible agent's own Slack bot posts it as a card in
|
|
6
6
|
* the team channel (ticket thread, or a new thread), and the owner answers
|
|
7
7
|
* with a button, a reaction or a thread reply. The decision is stored here
|
|
@@ -32,9 +32,9 @@ Communication style:
|
|
|
32
32
|
|
|
33
33
|
Your responsibilities:
|
|
34
34
|
- Make the technical decisions and review your team's work
|
|
35
|
-
- Delegate each task to
|
|
36
|
-
- Keep the owner informed and unblock the team
|
|
37
|
-
- Write code yourself only when
|
|
35
|
+
- Delegate each task to an available member (idle first); role is a preference, not a limit — every member can code
|
|
36
|
+
- Keep the owner informed and unblock the team; a member you delegate an owner request to answers the owner itself
|
|
37
|
+
- Write code yourself only for lead-level work, when every member is busy, or when it truly needs your judgment`,
|
|
38
38
|
tpm: `You are an AI Technical Product Manager (TPM) responsible for scoping projects and translating business logic into technical requirements.
|
|
39
39
|
|
|
40
40
|
Your responsibilities:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultPrompts.js","sourceRoot":"","sources":["../../../../../backend/src/utils/defaultPrompts.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,YAAY,EAAE;;;;;;;;;;;;;oDAaoC;IAElD,aAAa,EAAE;;;;;;;;;;;;;;wCAcuB;IAEtC,WAAW,EAAE;;;;;;
|
|
1
|
+
{"version":3,"file":"defaultPrompts.js","sourceRoot":"","sources":["../../../../../backend/src/utils/defaultPrompts.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,YAAY,EAAE;;;;;;;;;;;;;oDAaoC;IAElD,aAAa,EAAE;;;;;;;;;;;;;;wCAcuB;IAEtC,WAAW,EAAE;;;;;;gHAMiG;IAE9G,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;6DAsBsD;IAE3D,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;2DAsBoD;IAEzD,SAAS,EAAE;;;;;;;;;;;;;2CAa8B;IAEzC,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;2DAmBmC;IAEzD,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;yDAmBkC;IAEvD,EAAE,EAAE;;;;;;;;;;;;;0CAaoC;IAExC,MAAM,EAAE;;;;;;;;;;;;;8CAaoC;IAE5C,QAAQ,EAAE;;;;;;;;;;;;;6CAaiC;IAE3C,SAAS,EAAE;;;;;;;;;;;;;;;;;;;8DAmBiD;IAE5D,eAAe,EAAE;;;;;;;;;;;;;;;;;;;wDAmBqC;IAEtD,aAAa,EAAE;;;;;;;;;;;;;;;;;;;6CAmB4B;IAE3C,iBAAiB,EAAE;;;;;;;;;;;;;0CAaqB;IAExC,KAAK,EAAE;;;;;;;;;;;;;wDAa+C;IAEtD,OAAO,EAAE;;;;;;;;;;;;;uDAa4C;CACtD,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,IAAoB;IACnD,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAoB,EAAE,QAAgB,CAAC;IAC9E,MAAM,SAAS,GAAmC;QAChD,YAAY,EAAE,cAAc;QAC5B,aAAa,EAAE,aAAa;QAC5B,WAAW,EAAE,WAAW;QACxB,GAAG,EAAE,2BAA2B;QAChC,SAAS,EAAE,WAAW;QACtB,GAAG,EAAE,iBAAiB;QACtB,SAAS,EAAE,WAAW;QACtB,oBAAoB,EAAE,oBAAoB;QAC1C,mBAAmB,EAAE,mBAAmB;QACxC,eAAe,EAAE,sBAAsB;QACvC,EAAE,EAAE,aAAa;QACjB,aAAa,EAAE,aAAa;QAC5B,MAAM,EAAE,eAAe;QACvB,QAAQ,EAAE,UAAU;QACpB,iBAAiB,EAAE,iBAAiB;QACpC,KAAK,EAAE,sBAAsB;QAC7B,OAAO,EAAE,kBAAkB;KAC5B,CAAC;IAEF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;AAC7D,CAAC"}
|
|
@@ -6050,7 +6050,9 @@ export declare const DECISION_CONSTANTS: {
|
|
|
6050
6050
|
readonly QUESTION_MIN_CHARS: 8;
|
|
6051
6051
|
/** Allowed option count */
|
|
6052
6052
|
readonly MIN_OPTIONS: 2;
|
|
6053
|
-
readonly MAX_OPTIONS:
|
|
6053
|
+
readonly MAX_OPTIONS: 5;
|
|
6054
|
+
/** Two yes/no asks on one ticket this close together that read as either/or are rejected (ms) */
|
|
6055
|
+
readonly EITHER_OR_WINDOW_MS: number;
|
|
6054
6056
|
/** Max characters of an option label (Slack button text max is 75) */
|
|
6055
6057
|
readonly OPTION_LABEL_MAX_CHARS: 40;
|
|
6056
6058
|
/** Max characters of an option's optional detail line */
|
|
@@ -6203,6 +6205,47 @@ export declare const WORK_ITEM_DESTINATION_CONSTANTS: {
|
|
|
6203
6205
|
/** The one line every prompt carries about where to answer */
|
|
6204
6206
|
readonly PROMPT_LINE: "Answer where you were asked; a new topic goes in a new thread.";
|
|
6205
6207
|
};
|
|
6208
|
+
/**
|
|
6209
|
+
* Team leads delegate instead of doing the work (crewly#1083,
|
|
6210
|
+
* specs/2026-10-04-tl-delegation.md): owner-thread hand-over, the execution
|
|
6211
|
+
* nudge, lead share of team tokens, and "no member fits" records.
|
|
6212
|
+
*/
|
|
6213
|
+
export declare const TL_DELEGATION_CONSTANTS: {
|
|
6214
|
+
/** WorkItem.metadata / add-body field: the owner's Slack thread key a delegation answers */
|
|
6215
|
+
readonly OWNER_THREAD_FIELD: "ownerThread";
|
|
6216
|
+
/** A done item still lets its agent post in the owner's thread this long (ms) */
|
|
6217
|
+
readonly DONE_THREAD_GRACE_MS: number;
|
|
6218
|
+
/** Claude Code tools that count as hands-on file edits */
|
|
6219
|
+
readonly EDIT_TOOLS: readonly string[];
|
|
6220
|
+
/** Edits in the window that trigger a nudge */
|
|
6221
|
+
readonly EDIT_THRESHOLD: 6;
|
|
6222
|
+
/** Sliding window for counting edits (ms) */
|
|
6223
|
+
readonly WINDOW_MS: number;
|
|
6224
|
+
/** At most one nudge per lead per this long (ms) */
|
|
6225
|
+
readonly NUDGE_COOLDOWN_MS: number;
|
|
6226
|
+
/** A delegation this soon after a nudge counts as following it (ms) */
|
|
6227
|
+
readonly FOLLOW_WINDOW_MS: number;
|
|
6228
|
+
/** Members named in a nudge */
|
|
6229
|
+
readonly NUDGE_MAX_MEMBERS: 3;
|
|
6230
|
+
/** Tag that opens the nudge text */
|
|
6231
|
+
readonly NUDGE_TAG: "[CREWLY-NUDGE]";
|
|
6232
|
+
/** Note tag on a WorkItem the lead kept because no member fits */
|
|
6233
|
+
readonly NO_MEMBER_FITS_TAG: "[NO-MEMBER-FITS]";
|
|
6234
|
+
/** A lead share above this is flagged */
|
|
6235
|
+
readonly FLAG_SHARE: 0.5;
|
|
6236
|
+
/** Below this many team tokens in the period a share is not flagged (too little to judge) */
|
|
6237
|
+
readonly MIN_TEAM_TOKENS: 1000000;
|
|
6238
|
+
/** "This week" = the last N days */
|
|
6239
|
+
readonly WEEK_DAYS: 7;
|
|
6240
|
+
/** State file in CREWLY_HOME (nudge counts, kept-work records) */
|
|
6241
|
+
readonly STATE_FILENAME: "tl-delegation.json";
|
|
6242
|
+
/** Kept-work records retained */
|
|
6243
|
+
readonly MAX_RECORDS: 500;
|
|
6244
|
+
/** Max characters of a recorded reason / work line */
|
|
6245
|
+
readonly MAX_TEXT_CHARS: 300;
|
|
6246
|
+
/** Accepted tool_name from the hook */
|
|
6247
|
+
readonly TOOL_NAME_PATTERN: RegExp;
|
|
6248
|
+
};
|
|
6206
6249
|
/**
|
|
6207
6250
|
* Harness-owned reply routing (specs/2026-10-02-harness-owned-routing.md).
|
|
6208
6251
|
*/
|
|
@@ -6239,7 +6282,8 @@ export declare const USAGE_BACKFILL_CONSTANTS: {
|
|
|
6239
6282
|
/**
|
|
6240
6283
|
* Daily token caps with a hard stop, team caps and temporary boosts
|
|
6241
6284
|
* (specs/2026-10-02-spend-cap.md). The unit is TOKENS, not dollars (owner,
|
|
6242
|
-
* 2026-10-02):
|
|
6285
|
+
* 2026-10-02): caps compare cost-weighted budget tokens (cache reads x0.1,
|
|
6286
|
+
* crewly#1090); the raw total is input (fresh + cached) + output — see
|
|
6243
6287
|
* `eventTokens` in token-usage.service. Caps are OFF until the owner sets
|
|
6244
6288
|
* one. All owner-facing text is English.
|
|
6245
6289
|
*/
|