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,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lead share of a team's tokens (crewly#1083, specs/2026-10-04-tl-delegation.md §3).
|
|
3
|
+
*
|
|
4
|
+
* A team whose lead burns most of its tokens is a team whose lead does the
|
|
5
|
+
* work. Per team: the lead sessions' tokens over the whole team's, today and
|
|
6
|
+
* over the last week, flagged above {@link TL_DELEGATION_CONSTANTS.FLAG_SHARE}.
|
|
7
|
+
*
|
|
8
|
+
* Pure functions only: the token ledger is passed in as a visitor.
|
|
9
|
+
*
|
|
10
|
+
* @module services/tl-delegation/lead-share
|
|
11
|
+
*/
|
|
12
|
+
import { TL_DELEGATION_CONSTANTS } from '../../constants.js';
|
|
13
|
+
import { getTeamLeads } from '../../utils/team.utils.js';
|
|
14
|
+
import { eventTokens } from '../monitoring/token-usage.service.js';
|
|
15
|
+
/**
|
|
16
|
+
* The ledger keys a member's usage is recorded under: its session name and
|
|
17
|
+
* its permanent agent id (a stopped member has no session name).
|
|
18
|
+
*
|
|
19
|
+
* @param m - Team member
|
|
20
|
+
* @returns Non-empty keys
|
|
21
|
+
*/
|
|
22
|
+
export function memberLedgerKeys(m) {
|
|
23
|
+
return [...new Set([m.sessionName, m.agentId].filter((k) => typeof k === 'string' && k.length > 0))];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Local midnight of a date.
|
|
27
|
+
*
|
|
28
|
+
* @param now - Clock
|
|
29
|
+
* @returns Midnight (local time) of the same day
|
|
30
|
+
*/
|
|
31
|
+
export function startOfLocalDay(now) {
|
|
32
|
+
const d = new Date(now.getTime());
|
|
33
|
+
d.setHours(0, 0, 0, 0);
|
|
34
|
+
return d;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build a period from its totals.
|
|
38
|
+
*
|
|
39
|
+
* @param lead - Lead tokens
|
|
40
|
+
* @param team - Team tokens
|
|
41
|
+
* @param teamBudget - Team cost-weighted tokens, for display
|
|
42
|
+
* @returns The period
|
|
43
|
+
*/
|
|
44
|
+
export function sharePeriod(lead, team, teamBudget) {
|
|
45
|
+
const share = team > 0 ? lead / team : null;
|
|
46
|
+
return {
|
|
47
|
+
lead,
|
|
48
|
+
team,
|
|
49
|
+
share,
|
|
50
|
+
flagged: share !== null && share > TL_DELEGATION_CONSTANTS.FLAG_SHARE && team >= TL_DELEGATION_CONSTANTS.MIN_TEAM_TOKENS,
|
|
51
|
+
...(teamBudget !== undefined ? { teamBudget: Math.round(teamBudget) } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Lead share per team. Teams that are archived, have no lead, or have no
|
|
56
|
+
* other member are left out (a one-person team has no one to delegate to).
|
|
57
|
+
*
|
|
58
|
+
* @param teams - Teams
|
|
59
|
+
* @param forEachEvent - Ledger visitor
|
|
60
|
+
* @param now - Clock
|
|
61
|
+
* @returns One row per team with a lead and at least one other member
|
|
62
|
+
*/
|
|
63
|
+
export function computeLeadShares(teams, forEachEvent, now) {
|
|
64
|
+
const dayStart = startOfLocalDay(now).getTime();
|
|
65
|
+
const weekStart = startOfLocalDay(new Date(now.getTime() - (TL_DELEGATION_CONSTANTS.WEEK_DAYS - 1) * 24 * 60 * 60 * 1000)).getTime();
|
|
66
|
+
const accs = [];
|
|
67
|
+
// ledger key → (team accumulator, is lead)
|
|
68
|
+
const owners = new Map();
|
|
69
|
+
for (const team of teams) {
|
|
70
|
+
if (team.archived)
|
|
71
|
+
continue;
|
|
72
|
+
const members = (team.members ?? []).filter((m) => m.role !== 'orchestrator');
|
|
73
|
+
const leads = getTeamLeads(team);
|
|
74
|
+
if (leads.length === 0 || members.length < 2)
|
|
75
|
+
continue;
|
|
76
|
+
const leadIds = new Set(leads.map((l) => l.id));
|
|
77
|
+
const acc = {
|
|
78
|
+
row: {
|
|
79
|
+
teamId: team.id,
|
|
80
|
+
teamName: team.name,
|
|
81
|
+
leads: leads.map((l) => l.name),
|
|
82
|
+
leadSessions: leads.flatMap((l) => memberLedgerKeys(l)),
|
|
83
|
+
},
|
|
84
|
+
day: { lead: 0, team: 0, budget: 0 },
|
|
85
|
+
week: { lead: 0, team: 0, budget: 0 },
|
|
86
|
+
};
|
|
87
|
+
accs.push(acc);
|
|
88
|
+
for (const m of members) {
|
|
89
|
+
for (const key of memberLedgerKeys(m)) {
|
|
90
|
+
if (!owners.has(key))
|
|
91
|
+
owners.set(key, { acc, lead: leadIds.has(m.id) });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (accs.length === 0)
|
|
96
|
+
return [];
|
|
97
|
+
forEachEvent((session, event) => {
|
|
98
|
+
const owner = owners.get(session);
|
|
99
|
+
if (!owner)
|
|
100
|
+
return;
|
|
101
|
+
const at = Date.parse(event.timestamp);
|
|
102
|
+
if (!Number.isFinite(at) || at < weekStart || at > now.getTime())
|
|
103
|
+
return;
|
|
104
|
+
const et = eventTokens(event);
|
|
105
|
+
const tokens = et.total;
|
|
106
|
+
owner.acc.week.budget += et.budget;
|
|
107
|
+
owner.acc.week.team += tokens;
|
|
108
|
+
if (owner.lead)
|
|
109
|
+
owner.acc.week.lead += tokens;
|
|
110
|
+
if (at >= dayStart) {
|
|
111
|
+
owner.acc.day.budget += et.budget;
|
|
112
|
+
owner.acc.day.team += tokens;
|
|
113
|
+
if (owner.lead)
|
|
114
|
+
owner.acc.day.lead += tokens;
|
|
115
|
+
}
|
|
116
|
+
}, new Date(weekStart));
|
|
117
|
+
return accs.map((a) => ({ ...a.row, today: sharePeriod(a.day.lead, a.day.team, a.day.budget), week: sharePeriod(a.week.lead, a.week.team, a.week.budget) }));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* A share as a whole percentage.
|
|
121
|
+
*
|
|
122
|
+
* @param share - 0..1 or null
|
|
123
|
+
* @returns "63%" or "–"
|
|
124
|
+
*/
|
|
125
|
+
export function formatShare(share) {
|
|
126
|
+
return share === null ? '–' : `${Math.round(share * 100)}%`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Token count, short.
|
|
130
|
+
*
|
|
131
|
+
* @param n - Tokens
|
|
132
|
+
* @returns "306M", "4.2M", "12k", "800"
|
|
133
|
+
*/
|
|
134
|
+
export function formatTokens(n) {
|
|
135
|
+
if (n >= 100_000_000)
|
|
136
|
+
return `${Math.round(n / 1_000_000)}M`;
|
|
137
|
+
if (n >= 1_000_000)
|
|
138
|
+
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
139
|
+
if (n >= 1_000)
|
|
140
|
+
return `${Math.round(n / 1_000)}k`;
|
|
141
|
+
return String(Math.round(n));
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The "Team leads" block of the evening digest. Teams with no tokens today
|
|
145
|
+
* and no records are left out.
|
|
146
|
+
*
|
|
147
|
+
* @param rows - Lead shares
|
|
148
|
+
* @param extras - Team id → nudges / kept-work reasons
|
|
149
|
+
* @returns Block text, or null when there is nothing to say
|
|
150
|
+
*/
|
|
151
|
+
export function buildLeadShareDigest(rows, extras = new Map()) {
|
|
152
|
+
const lines = [];
|
|
153
|
+
for (const r of rows) {
|
|
154
|
+
const x = extras.get(r.teamId) ?? {};
|
|
155
|
+
const kept = x.keptReasons ?? [];
|
|
156
|
+
if (r.today.team === 0 && kept.length === 0 && !x.nudges?.count)
|
|
157
|
+
continue;
|
|
158
|
+
const flag = r.today.flagged || r.week.flagged ? ' — over half: the lead is doing the work' : '';
|
|
159
|
+
const parts = [
|
|
160
|
+
`- *${r.teamName}* (${r.leads.join(', ')}): ${formatShare(r.today.share)} of ${formatTokens(r.today.team)} today${r.today.teamBudget !== undefined ? ` (${formatTokens(r.today.teamBudget)} weighted)` : ''}, ${formatShare(r.week.share)} this week${flag}`,
|
|
161
|
+
];
|
|
162
|
+
if (x.nudges && x.nudges.count > 0)
|
|
163
|
+
parts.push(` nudged to delegate ${x.nudges.count}×, delegated after ${x.nudges.followed}`);
|
|
164
|
+
if (kept.length > 0) {
|
|
165
|
+
const max = 3;
|
|
166
|
+
const shown = kept.slice(0, max).map((k) => `"${k}"`).join('; ');
|
|
167
|
+
parts.push(` kept work, no member fits: ${shown}${kept.length > max ? `; +${kept.length - max} more` : ''}`);
|
|
168
|
+
}
|
|
169
|
+
lines.push(parts.join('\n'));
|
|
170
|
+
}
|
|
171
|
+
if (lines.length === 0)
|
|
172
|
+
return null;
|
|
173
|
+
return ['*Team leads* (lead share of team tokens)', ...lines].join('\n');
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=lead-share.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lead-share.js","sourceRoot":"","sources":["../../../../../../backend/src/services/tl-delegation/lead-share.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "Team leads" block of the evening digest from the process singletons
|
|
3
|
+
* (crewly#1083, specs/2026-10-04-tl-delegation.md §3).
|
|
4
|
+
*
|
|
5
|
+
* @module services/tl-delegation/lead-share.wiring
|
|
6
|
+
*/
|
|
7
|
+
import type { Team } from '../../types/index.js';
|
|
8
|
+
import { type LedgerVisitor } from './lead-share.js';
|
|
9
|
+
import type { TlDelegationService } from './tl-delegation.service.js';
|
|
10
|
+
/** Collaborators of {@link leadShareDigestFor}. */
|
|
11
|
+
export interface LeadShareDigestDeps {
|
|
12
|
+
teams: () => Promise<Team[]>;
|
|
13
|
+
forEachEvent: LedgerVisitor;
|
|
14
|
+
delegation: Pick<TlDelegationService, 'nudgeCounts' | 'keptWorkSince'>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The digest block for today: lead shares, today's nudges and kept work.
|
|
18
|
+
*
|
|
19
|
+
* @param now - Clock
|
|
20
|
+
* @param deps - Collaborators
|
|
21
|
+
* @returns Block text, or null when there is nothing to say
|
|
22
|
+
*/
|
|
23
|
+
export declare function leadShareDigestFor(now: Date, deps: LeadShareDigestDeps): Promise<string | null>;
|
|
24
|
+
/**
|
|
25
|
+
* {@link leadShareDigestFor} over the team store, the token ledger and the
|
|
26
|
+
* delegation service.
|
|
27
|
+
*
|
|
28
|
+
* @param now - Clock
|
|
29
|
+
* @returns Block text, or null
|
|
30
|
+
*/
|
|
31
|
+
export declare function defaultLeadShareDigest(now: Date): Promise<string | null>;
|
|
32
|
+
//# sourceMappingURL=lead-share.wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lead-share.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/tl-delegation/lead-share.wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAmF,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACtI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mDAAmD;AACnD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7B,YAAY,EAAE,aAAa,CAAC;IAC5B,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,aAAa,GAAG,eAAe,CAAC,CAAC;CACxE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWrG;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY9E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "Team leads" block of the evening digest from the process singletons
|
|
3
|
+
* (crewly#1083, specs/2026-10-04-tl-delegation.md §3).
|
|
4
|
+
*
|
|
5
|
+
* @module services/tl-delegation/lead-share.wiring
|
|
6
|
+
*/
|
|
7
|
+
import { buildLeadShareDigest, computeLeadShares, startOfLocalDay } from './lead-share.js';
|
|
8
|
+
/**
|
|
9
|
+
* The digest block for today: lead shares, today's nudges and kept work.
|
|
10
|
+
*
|
|
11
|
+
* @param now - Clock
|
|
12
|
+
* @param deps - Collaborators
|
|
13
|
+
* @returns Block text, or null when there is nothing to say
|
|
14
|
+
*/
|
|
15
|
+
export async function leadShareDigestFor(now, deps) {
|
|
16
|
+
const teams = await deps.teams();
|
|
17
|
+
const rows = computeLeadShares(teams, deps.forEachEvent, now);
|
|
18
|
+
const dayStart = startOfLocalDay(now).getTime();
|
|
19
|
+
const extras = new Map();
|
|
20
|
+
for (const r of rows) {
|
|
21
|
+
const nudges = deps.delegation.nudgeCounts(r.leadSessions, now.getTime()).day;
|
|
22
|
+
const kept = deps.delegation.keptWorkSince(dayStart, { teamId: r.teamId, sessions: r.leadSessions }).map((k) => k.reason);
|
|
23
|
+
extras.set(r.teamId, { nudges, keptReasons: kept });
|
|
24
|
+
}
|
|
25
|
+
return buildLeadShareDigest(rows, extras);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* {@link leadShareDigestFor} over the team store, the token ledger and the
|
|
29
|
+
* delegation service.
|
|
30
|
+
*
|
|
31
|
+
* @param now - Clock
|
|
32
|
+
* @returns Block text, or null
|
|
33
|
+
*/
|
|
34
|
+
export async function defaultLeadShareDigest(now) {
|
|
35
|
+
const [{ StorageService }, { TokenUsageService }, { TlDelegationService }] = await Promise.all([
|
|
36
|
+
import('../core/storage.service.js'),
|
|
37
|
+
import('../monitoring/token-usage.service.js'),
|
|
38
|
+
import('./tl-delegation.service.js'),
|
|
39
|
+
]);
|
|
40
|
+
const usage = TokenUsageService.getInstance();
|
|
41
|
+
return leadShareDigestFor(now, {
|
|
42
|
+
teams: () => StorageService.getInstance().getTeams(),
|
|
43
|
+
forEachEvent: (visit, since) => usage.forEachEvent(visit, since),
|
|
44
|
+
delegation: TlDelegationService.getInstance(),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=lead-share.wiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lead-share.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/tl-delegation/lead-share.wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,eAAe,EAA6C,MAAM,iBAAiB,CAAC;AAUtI;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAS,EAAE,IAAyB;IAC3E,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC;QAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1H,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAS;IACpD,MAAM,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,mBAAmB,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7F,MAAM,CAAC,4BAA4B,CAAC;QACpC,MAAM,CAAC,sCAAsC,CAAC;QAC9C,MAAM,CAAC,4BAA4B,CAAC;KACrC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,kBAAkB,CAAC,GAAG,EAAE;QAC7B,KAAK,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;QACpD,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;QAChE,UAAU,EAAE,mBAAmB,CAAC,WAAW,EAAE;KAC9C,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,207 @@
|
|
|
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 type { Team, TeamMember } from '../../types/index.js';
|
|
16
|
+
import { type ComponentLogger } from '../core/logger.service.js';
|
|
17
|
+
/** A member as the nudge names it. */
|
|
18
|
+
export interface NudgeMember {
|
|
19
|
+
name: string;
|
|
20
|
+
role: string;
|
|
21
|
+
/** idle: free now; stopped: starts when assigned; working: busy */
|
|
22
|
+
availability: 'idle' | 'stopped' | 'working';
|
|
23
|
+
}
|
|
24
|
+
/** The lead's team, for the nudge. */
|
|
25
|
+
export interface LeadContext {
|
|
26
|
+
teamId: string;
|
|
27
|
+
teamName: string;
|
|
28
|
+
/** Members other than the lead(s) */
|
|
29
|
+
members: NudgeMember[];
|
|
30
|
+
}
|
|
31
|
+
/** Work a lead kept because no member fits. */
|
|
32
|
+
export interface KeptWorkRecord {
|
|
33
|
+
at: string;
|
|
34
|
+
/** Lead session */
|
|
35
|
+
session: string;
|
|
36
|
+
teamId?: string;
|
|
37
|
+
reason: string;
|
|
38
|
+
work: string;
|
|
39
|
+
workItemId?: string;
|
|
40
|
+
ticket?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Per-lead nudge counts. */
|
|
43
|
+
export interface NudgeCounts {
|
|
44
|
+
/** Nudges sent */
|
|
45
|
+
count: number;
|
|
46
|
+
/** Nudges followed by a delegation within the follow window */
|
|
47
|
+
followed: number;
|
|
48
|
+
/** Last nudge (epoch ms) */
|
|
49
|
+
lastAt?: number;
|
|
50
|
+
/** A nudge not yet followed (epoch ms), cleared on delegation or when the window passes */
|
|
51
|
+
pendingSince?: number;
|
|
52
|
+
/** Per local day: day key → { count, followed } */
|
|
53
|
+
days?: Record<string, {
|
|
54
|
+
count: number;
|
|
55
|
+
followed: number;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
/** Collaborators. */
|
|
59
|
+
export interface TlDelegationDeps {
|
|
60
|
+
/** The lead's team, or null when the session is not a team lead (or has nobody to delegate to) */
|
|
61
|
+
leadContext: (session: string) => Promise<LeadContext | null>;
|
|
62
|
+
/** State file (default: CREWLY_HOME/tl-delegation.json) */
|
|
63
|
+
statePath?: string;
|
|
64
|
+
/** Clock (epoch ms) */
|
|
65
|
+
now?: () => number;
|
|
66
|
+
logger?: ComponentLogger;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Members best placed to take hands-on work: idle first, then stopped, then
|
|
70
|
+
* working; at most {@link TL_DELEGATION_CONSTANTS.NUDGE_MAX_MEMBERS}.
|
|
71
|
+
*
|
|
72
|
+
* @param members - The lead's members
|
|
73
|
+
* @returns Ranked, capped list
|
|
74
|
+
*/
|
|
75
|
+
export declare function rankMembersForNudge(members: readonly NudgeMember[]): NudgeMember[];
|
|
76
|
+
/**
|
|
77
|
+
* The nudge text (English harness text).
|
|
78
|
+
*
|
|
79
|
+
* @param edits - Edits counted in the window
|
|
80
|
+
* @param members - The lead's members
|
|
81
|
+
* @returns Note
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildNudgeText(edits: number, members: readonly NudgeMember[]): string;
|
|
84
|
+
/**
|
|
85
|
+
* Local date key (YYYY-MM-DD).
|
|
86
|
+
*
|
|
87
|
+
* @param ms - Epoch ms
|
|
88
|
+
* @returns Day key
|
|
89
|
+
*/
|
|
90
|
+
export declare function localDayKey(ms: number): string;
|
|
91
|
+
/**
|
|
92
|
+
* Nudge bookkeeping and kept-work records.
|
|
93
|
+
*/
|
|
94
|
+
export declare class TlDelegationService {
|
|
95
|
+
private static instance;
|
|
96
|
+
private readonly deps;
|
|
97
|
+
private readonly statePath;
|
|
98
|
+
private readonly now;
|
|
99
|
+
private readonly logger;
|
|
100
|
+
/** session → recent edit times (epoch ms), in-memory only */
|
|
101
|
+
private readonly edits;
|
|
102
|
+
private state;
|
|
103
|
+
private writing;
|
|
104
|
+
/**
|
|
105
|
+
* @param deps - Collaborators
|
|
106
|
+
*/
|
|
107
|
+
constructor(deps: TlDelegationDeps);
|
|
108
|
+
/**
|
|
109
|
+
* The process instance (built from the team store on first use).
|
|
110
|
+
*
|
|
111
|
+
* @returns Service
|
|
112
|
+
*/
|
|
113
|
+
static getInstance(): TlDelegationService;
|
|
114
|
+
/**
|
|
115
|
+
* Replace (tests) or clear the process instance.
|
|
116
|
+
*
|
|
117
|
+
* @param service - New instance, or null
|
|
118
|
+
*/
|
|
119
|
+
static setInstance(service: TlDelegationService | null): void;
|
|
120
|
+
/**
|
|
121
|
+
* A tool call finished in `session`. Returns the nudge to show the agent,
|
|
122
|
+
* or null. Never throws.
|
|
123
|
+
*
|
|
124
|
+
* @param session - Agent session
|
|
125
|
+
* @param toolName - Claude Code tool name
|
|
126
|
+
* @returns Nudge text, or null
|
|
127
|
+
*/
|
|
128
|
+
observeToolUse(session: string, toolName: string): Promise<string | null>;
|
|
129
|
+
/**
|
|
130
|
+
* A work item was delegated. Counts as following a nudge when the
|
|
131
|
+
* delegator was nudged within {@link TL_DELEGATION_CONSTANTS.FOLLOW_WINDOW_MS}.
|
|
132
|
+
*
|
|
133
|
+
* @param delegator - Delegating session
|
|
134
|
+
* @param target - Target session
|
|
135
|
+
* @returns True when it followed a nudge
|
|
136
|
+
*/
|
|
137
|
+
recordDelegation(delegator: string | undefined, target: string | undefined): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Record work a lead keeps because no member fits.
|
|
140
|
+
*
|
|
141
|
+
* @param input - Lead session, team, reason, work, optional work item / ticket
|
|
142
|
+
* @returns The stored record
|
|
143
|
+
*/
|
|
144
|
+
recordKeptWork(input: {
|
|
145
|
+
session: string;
|
|
146
|
+
teamId?: string;
|
|
147
|
+
reason: string;
|
|
148
|
+
work: string;
|
|
149
|
+
workItemId?: string;
|
|
150
|
+
ticket?: string;
|
|
151
|
+
}): KeptWorkRecord;
|
|
152
|
+
/**
|
|
153
|
+
* Kept-work records since a time, optionally for one team or set of sessions.
|
|
154
|
+
*
|
|
155
|
+
* @param sinceMs - Lower bound (epoch ms)
|
|
156
|
+
* @param filter - Team id and/or lead sessions (either matches)
|
|
157
|
+
* @returns Records, oldest first
|
|
158
|
+
*/
|
|
159
|
+
keptWorkSince(sinceMs: number, filter?: {
|
|
160
|
+
teamId?: string;
|
|
161
|
+
sessions?: readonly string[];
|
|
162
|
+
}): KeptWorkRecord[];
|
|
163
|
+
/**
|
|
164
|
+
* Nudge counts of some sessions: all-time, and for one local day.
|
|
165
|
+
*
|
|
166
|
+
* @param sessions - Lead sessions
|
|
167
|
+
* @param dayMs - A time on the day to report (default: now)
|
|
168
|
+
* @returns Totals and that day's numbers
|
|
169
|
+
*/
|
|
170
|
+
nudgeCounts(sessions: readonly string[], dayMs?: number): {
|
|
171
|
+
total: {
|
|
172
|
+
count: number;
|
|
173
|
+
followed: number;
|
|
174
|
+
};
|
|
175
|
+
day: {
|
|
176
|
+
count: number;
|
|
177
|
+
followed: number;
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
/** Wait for pending writes (tests, shutdown). */
|
|
181
|
+
flush(): Promise<void>;
|
|
182
|
+
/**
|
|
183
|
+
* Load the state once (a missing or broken file starts empty).
|
|
184
|
+
*
|
|
185
|
+
* @returns State
|
|
186
|
+
*/
|
|
187
|
+
private load;
|
|
188
|
+
/** Write the state (serialized, best-effort). */
|
|
189
|
+
private save;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The availability of a member, as the nudge words it.
|
|
193
|
+
*
|
|
194
|
+
* @param m - Member
|
|
195
|
+
* @returns Availability
|
|
196
|
+
*/
|
|
197
|
+
export declare function memberAvailability(m: Pick<TeamMember, 'agentStatus' | 'workingStatus'>): NudgeMember['availability'];
|
|
198
|
+
/**
|
|
199
|
+
* The lead context of a session among teams: the team it leads, with its
|
|
200
|
+
* other members. Null when it leads no team with other members.
|
|
201
|
+
*
|
|
202
|
+
* @param teams - Teams
|
|
203
|
+
* @param session - Agent session
|
|
204
|
+
* @returns Context, or null
|
|
205
|
+
*/
|
|
206
|
+
export declare function leadContextFromTeams(teams: readonly Team[], session: string): LeadContext | null;
|
|
207
|
+
//# sourceMappingURL=tl-delegation.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tl-delegation.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/tl-delegation/tl-delegation.service.ts"],"names":[],"mappings":"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"}
|