crewly 1.20.358 → 1.20.360

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/config/roles/developer/prompt.md +3 -1
  2. package/config/skills/registry.json +125 -1
  3. package/dist/backend/backend/src/constants.d.ts +189 -2
  4. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  5. package/dist/backend/backend/src/constants.js +200 -3
  6. package/dist/backend/backend/src/constants.js.map +1 -1
  7. package/dist/backend/backend/src/index.d.ts +58 -0
  8. package/dist/backend/backend/src/index.d.ts.map +1 -1
  9. package/dist/backend/backend/src/index.js +263 -19
  10. package/dist/backend/backend/src/index.js.map +1 -1
  11. package/dist/backend/backend/src/services/agent/boot-pressure.d.ts +147 -0
  12. package/dist/backend/backend/src/services/agent/boot-pressure.d.ts.map +1 -0
  13. package/dist/backend/backend/src/services/agent/boot-pressure.js +212 -0
  14. package/dist/backend/backend/src/services/agent/boot-pressure.js.map +1 -0
  15. package/dist/backend/backend/src/services/agent/restore-queue.d.ts +50 -1
  16. package/dist/backend/backend/src/services/agent/restore-queue.d.ts.map +1 -1
  17. package/dist/backend/backend/src/services/agent/restore-queue.js +100 -5
  18. package/dist/backend/backend/src/services/agent/restore-queue.js.map +1 -1
  19. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts +11 -0
  20. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts.map +1 -1
  21. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js +28 -2
  22. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js.map +1 -1
  23. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts +10 -0
  24. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -1
  25. package/dist/backend/backend/src/services/memory/startup-briefing.service.js +65 -22
  26. package/dist/backend/backend/src/services/memory/startup-briefing.service.js.map +1 -1
  27. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +8 -0
  28. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
  29. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +8 -0
  30. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
  31. package/dist/backend/backend/src/services/session/session-binding.d.ts +25 -2
  32. package/dist/backend/backend/src/services/session/session-binding.d.ts.map +1 -1
  33. package/dist/backend/backend/src/services/session/session-binding.js +32 -4
  34. package/dist/backend/backend/src/services/session/session-binding.js.map +1 -1
  35. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  36. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  37. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  38. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts +27 -2
  39. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js +105 -8
  41. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js.map +1 -1
  42. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts +7 -0
  43. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -1
  44. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js +10 -0
  45. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js.map +1 -1
  46. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts +24 -0
  47. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js +75 -9
  49. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts +19 -0
  51. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts.map +1 -1
  52. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js +23 -2
  53. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js.map +1 -1
  54. package/dist/backend/backend/src/services/wiki/work-record-transcript.d.ts +64 -0
  55. package/dist/backend/backend/src/services/wiki/work-record-transcript.d.ts.map +1 -0
  56. package/dist/backend/backend/src/services/wiki/work-record-transcript.js +194 -0
  57. package/dist/backend/backend/src/services/wiki/work-record-transcript.js.map +1 -0
  58. package/dist/backend/backend/src/services/wiki/work-record.d.ts +239 -0
  59. package/dist/backend/backend/src/services/wiki/work-record.d.ts.map +1 -0
  60. package/dist/backend/backend/src/services/wiki/work-record.js +631 -0
  61. package/dist/backend/backend/src/services/wiki/work-record.js.map +1 -0
  62. package/dist/backend/backend/src/services/wiki/work-record.service.d.ts +231 -0
  63. package/dist/backend/backend/src/services/wiki/work-record.service.d.ts.map +1 -0
  64. package/dist/backend/backend/src/services/wiki/work-record.service.js +542 -0
  65. package/dist/backend/backend/src/services/wiki/work-record.service.js.map +1 -0
  66. package/dist/backend/backend/src/services/worktree/low-disk-guard.d.ts +92 -8
  67. package/dist/backend/backend/src/services/worktree/low-disk-guard.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/worktree/low-disk-guard.js +98 -14
  69. package/dist/backend/backend/src/services/worktree/low-disk-guard.js.map +1 -1
  70. package/dist/backend/backend/src/services/worktree/tmp-janitor.d.ts +138 -0
  71. package/dist/backend/backend/src/services/worktree/tmp-janitor.d.ts.map +1 -0
  72. package/dist/backend/backend/src/services/worktree/tmp-janitor.js +199 -0
  73. package/dist/backend/backend/src/services/worktree/tmp-janitor.js.map +1 -0
  74. package/dist/backend/backend/src/services/worktree/transcript-janitor.d.ts +154 -0
  75. package/dist/backend/backend/src/services/worktree/transcript-janitor.d.ts.map +1 -0
  76. package/dist/backend/backend/src/services/worktree/transcript-janitor.js +357 -0
  77. package/dist/backend/backend/src/services/worktree/transcript-janitor.js.map +1 -0
  78. package/dist/backend/backend/src/services/worktree/workitem-worktree.service.d.ts.map +1 -1
  79. package/dist/backend/backend/src/services/worktree/workitem-worktree.service.js +7 -2
  80. package/dist/backend/backend/src/services/worktree/workitem-worktree.service.js.map +1 -1
  81. package/dist/backend/backend/src/services/worktree/worktree-dirty.d.ts +16 -4
  82. package/dist/backend/backend/src/services/worktree/worktree-dirty.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/worktree/worktree-dirty.js +21 -5
  84. package/dist/backend/backend/src/services/worktree/worktree-dirty.js.map +1 -1
  85. package/dist/backend/backend/src/services/worktree/worktree-git.d.ts +18 -0
  86. package/dist/backend/backend/src/services/worktree/worktree-git.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/worktree/worktree-git.js +60 -0
  88. package/dist/backend/backend/src/services/worktree/worktree-git.js.map +1 -1
  89. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +164 -25
  90. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +494 -55
  92. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/worktree/worktree-tiers.d.ts +186 -0
  94. package/dist/backend/backend/src/services/worktree/worktree-tiers.d.ts.map +1 -0
  95. package/dist/backend/backend/src/services/worktree/worktree-tiers.js +279 -0
  96. package/dist/backend/backend/src/services/worktree/worktree-tiers.js.map +1 -0
  97. package/dist/backend/build-info.json +2 -2
  98. package/dist/cli/backend/src/constants.d.ts +189 -2
  99. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  100. package/dist/cli/backend/src/constants.js +200 -3
  101. package/dist/cli/backend/src/constants.js.map +1 -1
  102. package/dist/cli/backend/src/services/agent/boot-pressure.d.ts +147 -0
  103. package/dist/cli/backend/src/services/agent/boot-pressure.d.ts.map +1 -0
  104. package/dist/cli/backend/src/services/agent/boot-pressure.js +212 -0
  105. package/dist/cli/backend/src/services/agent/boot-pressure.js.map +1 -0
  106. package/dist/cli/backend/src/services/agent/restore-queue.d.ts +50 -1
  107. package/dist/cli/backend/src/services/agent/restore-queue.d.ts.map +1 -1
  108. package/dist/cli/backend/src/services/agent/restore-queue.js +100 -5
  109. package/dist/cli/backend/src/services/agent/restore-queue.js.map +1 -1
  110. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts +10 -0
  111. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -1
  112. package/dist/cli/backend/src/services/memory/startup-briefing.service.js +65 -22
  113. package/dist/cli/backend/src/services/memory/startup-briefing.service.js.map +1 -1
  114. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  115. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  116. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  117. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts +7 -0
  118. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -1
  119. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js +10 -0
  120. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js.map +1 -1
  121. package/dist/cli/backend/src/services/wiki/work-record-transcript.d.ts +64 -0
  122. package/dist/cli/backend/src/services/wiki/work-record-transcript.d.ts.map +1 -0
  123. package/dist/cli/backend/src/services/wiki/work-record-transcript.js +194 -0
  124. package/dist/cli/backend/src/services/wiki/work-record-transcript.js.map +1 -0
  125. package/dist/cli/backend/src/services/wiki/work-record.d.ts +239 -0
  126. package/dist/cli/backend/src/services/wiki/work-record.d.ts.map +1 -0
  127. package/dist/cli/backend/src/services/wiki/work-record.js +631 -0
  128. package/dist/cli/backend/src/services/wiki/work-record.js.map +1 -0
  129. package/dist/cli/backend/src/services/worktree/low-disk-guard.d.ts +92 -8
  130. package/dist/cli/backend/src/services/worktree/low-disk-guard.d.ts.map +1 -1
  131. package/dist/cli/backend/src/services/worktree/low-disk-guard.js +98 -14
  132. package/dist/cli/backend/src/services/worktree/low-disk-guard.js.map +1 -1
  133. package/dist/cli/backend/src/services/worktree/worktree-git.d.ts +18 -0
  134. package/dist/cli/backend/src/services/worktree/worktree-git.d.ts.map +1 -1
  135. package/dist/cli/backend/src/services/worktree/worktree-git.js +60 -0
  136. package/dist/cli/backend/src/services/worktree/worktree-git.js.map +1 -1
  137. package/package.json +1 -1
@@ -0,0 +1,542 @@
1
+ /**
2
+ * WorkRecordService (#1349) — one work record per finished task, written to
3
+ * the project vault log.
4
+ *
5
+ * The vault log only held what agents volunteered. This service writes, for
6
+ * every WorkItem that reaches a terminal state (done, verified, rejected,
7
+ * cancelled, failed) and for every item parked in `blocked` for more than a
8
+ * day, one structured `(record)` entry: who asked, who did it, what came
9
+ * out, what went wrong and how it was resolved, who helped, how it ended.
10
+ * The entry goes through `WikiIngestService` (source type `work_record`) into
11
+ * the project vault's `llm-curated/log.md` and, when the team has a vault,
12
+ * into that too. From there the weekly digest, search, and the startup
13
+ * briefing pick it up.
14
+ *
15
+ * Sources, all already on disk or in memory: the WorkItem, its linked
16
+ * project ticket or Request, its children (delegations, the verify item),
17
+ * the run trace, and a bounded tail of the doer's transcript. No model
18
+ * calls.
19
+ *
20
+ * Idempotent: a `work-record:<id>#<phase>` key is remembered in
21
+ * `CREWLY_HOME/work-records-state.json` (seeded from the vault log) and the
22
+ * ingest path refuses an identical body. A finished item whose ticket still
23
+ * waits for the owner's OK is deferred (the ticket change retries it; after
24
+ * `DEFER_MAX_MS` it is written as "waiting for the owner's OK").
25
+ *
26
+ * Runs on the terminal events with a short delay, plus an hourly tick that
27
+ * catches up on items of the last `CATCHUP_WINDOW_DAYS` without a record
28
+ * (at most `CATCHUP_MAX_PER_PASS`), deferred items and long-blocked items.
29
+ * `CREWLY_WORK_RECORDS=false` disables it.
30
+ *
31
+ * @module services/wiki/work-record.service
32
+ */
33
+ import * as path from 'path';
34
+ import * as fs from 'fs/promises';
35
+ import { existsSync } from 'fs';
36
+ import { LoggerService } from '../core/logger.service.js';
37
+ import { BOOT_PRESSURE_CONSTANTS, ORCHESTRATOR_SESSION_NAME, WIKI_LOG_CONSTANTS, WORK_RECORD_CONSTANTS } from '../../constants.js';
38
+ import { atomicWriteJson, ensureDir, safeReadJson } from '../../utils/file-io.utils.js';
39
+ import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
40
+ import { isLeadRole } from '../../utils/team.utils.js';
41
+ import { collectSecretEnvValues } from '../../utils/secret-env.js';
42
+ import { redactSecrets } from '../../utils/secret-redactor.js';
43
+ import { readProjectTicketLink } from '../../types/project-ticket.types.js';
44
+ import { listTicketPrefixes } from '../project-tickets/ticket-prefixes.js';
45
+ import { memberName } from '../messaging/agent-ask-ledger.service.js';
46
+ import { WikiIngestService } from './wiki-ingest.service.js';
47
+ import { redactSensitive } from './wiki-redaction.js';
48
+ import { parseLogEntries } from './wiki-log-entries.js';
49
+ import { assembleWorkRecord, isRecordableWorkItem, isWorkRecordEntry, renderWorkRecordBody, workItemEndedAt, workRecordRef, } from './work-record.js';
50
+ import { parseClaudeTranscriptWindow, readTranscriptTail, transcriptWorthReading } from './work-record-transcript.js';
51
+ const C = WORK_RECORD_CONSTANTS;
52
+ /** Statuses that close a task and get a `final` record. */
53
+ export const FINAL_RECORD_STATUSES = new Set(['done', 'verified', 'rejected', 'cancelled', 'failed']);
54
+ /** Events that announce a terminal transition. */
55
+ export const WORK_RECORD_EVENT_TYPES = ['task:done', 'task:verified', 'task:rejected', 'task:cancelled', 'task:failed'];
56
+ /**
57
+ * Per-task work records. Start at boot, stop at shutdown.
58
+ */
59
+ export class WorkRecordService {
60
+ static instance = null;
61
+ logger;
62
+ deps;
63
+ ingest;
64
+ statePath;
65
+ globalVaultPath;
66
+ teamsRoot;
67
+ intervalMs;
68
+ bootDelayMs;
69
+ bootGate;
70
+ reducedMaxPerPass;
71
+ eventDelayMs;
72
+ nowFn;
73
+ timer = null;
74
+ bootTimer = null;
75
+ pending = new Map();
76
+ unsubscribers = [];
77
+ running = false;
78
+ state = { recorded: {} };
79
+ stateLoaded = false;
80
+ seededVaults = new Set();
81
+ /** Transcript facts cache for the current pass: session → file text. */
82
+ transcriptCache = new Map();
83
+ /** Ticket prefixes of the registered projects, refreshed once per pass. */
84
+ prefixCache = null;
85
+ constructor(deps) {
86
+ this.logger = LoggerService.getInstance().createComponentLogger('WorkRecord');
87
+ this.deps = deps;
88
+ this.ingest = deps.ingest ?? WikiIngestService.getInstance();
89
+ this.statePath = deps.statePath === null ? null : deps.statePath ?? path.join(getCrewlyHomePath(), C.STATE_FILE);
90
+ this.globalVaultPath = deps.globalVaultPath ?? path.join(getCrewlyHomePath(), 'global-wiki');
91
+ this.teamsRoot = deps.teamsRoot ?? path.join(getCrewlyHomePath(), 'teams');
92
+ this.intervalMs = deps.intervalMs ?? C.TICK_MS;
93
+ this.bootDelayMs = deps.bootDelayMs ?? C.BOOT_DELAY_MS;
94
+ this.bootGate = deps.bootGate ?? null;
95
+ this.reducedMaxPerPass = deps.reducedMaxPerPass ?? BOOT_PRESSURE_CONSTANTS.WORK_RECORD_REDUCED_BATCH;
96
+ this.eventDelayMs = deps.eventDelayMs ?? C.EVENT_DELAY_MS;
97
+ this.nowFn = deps.now ?? (() => Date.now());
98
+ }
99
+ static getInstance() {
100
+ return this.instance;
101
+ }
102
+ /** Wire / detach the production singleton. */
103
+ static setInstance(next) {
104
+ if (this.instance && this.instance !== next)
105
+ this.instance.stop();
106
+ this.instance = next;
107
+ }
108
+ /**
109
+ * Subscribe to the terminal events and the ticket feed, schedule the boot
110
+ * catch-up and the hourly tick. Idempotent. Returns false when the kill
111
+ * switch is set.
112
+ *
113
+ * @returns Whether the service started
114
+ */
115
+ start() {
116
+ if (this.timer)
117
+ return true;
118
+ if (process.env[C.ENV_KILL_SWITCH] === 'false') {
119
+ this.logger.warn(`WorkRecord disabled via ${C.ENV_KILL_SWITCH}=false — not starting`);
120
+ return false;
121
+ }
122
+ if (this.deps.eventBus) {
123
+ this.unsubscribers.push(this.deps.eventBus.onInProcess([...WORK_RECORD_EVENT_TYPES], (e) => {
124
+ if (typeof e.workItemId === 'string' && e.workItemId)
125
+ this.schedule(e.workItemId);
126
+ }));
127
+ }
128
+ if (this.deps.onTicketSettled) {
129
+ this.unsubscribers.push(this.deps.onTicketSettled((workItemId) => this.schedule(workItemId)));
130
+ }
131
+ this.bootTimer = setTimeout(() => {
132
+ this.bootTimer = null;
133
+ void this.bootPass();
134
+ }, this.bootDelayMs);
135
+ this.bootTimer.unref?.();
136
+ this.timer = setInterval(() => void this.runOnce(), this.intervalMs);
137
+ this.timer.unref?.();
138
+ this.logger.info('WorkRecord started', { intervalMs: this.intervalMs, bootDelayMs: this.bootDelayMs, events: !!this.deps.eventBus, bootGate: !!this.bootGate });
139
+ return true;
140
+ }
141
+ /**
142
+ * The boot catch-up: waits at the boot gate when one is wired; when the
143
+ * gate gave up waiting (the machine stayed busy) the pass is reduced to
144
+ * `reducedMaxPerPass` records. Public for tests.
145
+ *
146
+ * @returns Pass result
147
+ */
148
+ async bootPass() {
149
+ let maxPerPass;
150
+ if (this.bootGate) {
151
+ try {
152
+ const gate = await this.bootGate();
153
+ if (gate.reduced)
154
+ maxPerPass = this.reducedMaxPerPass;
155
+ if (gate.waitedMs > 0)
156
+ this.logger.info('WorkRecord boot pass waited for a quiet machine', { waitedMs: gate.waitedMs, reduced: gate.reduced, reason: gate.reason, maxPerPass: maxPerPass ?? C.CATCHUP_MAX_PER_PASS });
157
+ }
158
+ catch (err) {
159
+ this.logger.warn('WorkRecord boot gate failed (running anyway)', { error: err instanceof Error ? err.message : String(err) });
160
+ }
161
+ }
162
+ return this.runOnce({ maxPerPass });
163
+ }
164
+ /** Stop timers and subscriptions. Safe to call more than once. */
165
+ stop() {
166
+ if (this.bootTimer) {
167
+ clearTimeout(this.bootTimer);
168
+ this.bootTimer = null;
169
+ }
170
+ if (this.timer) {
171
+ clearInterval(this.timer);
172
+ this.timer = null;
173
+ }
174
+ for (const t of this.pending.values())
175
+ clearTimeout(t);
176
+ this.pending.clear();
177
+ for (const u of this.unsubscribers.splice(0)) {
178
+ try {
179
+ u();
180
+ }
181
+ catch {
182
+ // detached already
183
+ }
184
+ }
185
+ }
186
+ /**
187
+ * Record one item soon (coalesced per id): the ticket sync, the verify
188
+ * item and the evidence land in the seconds after the event.
189
+ *
190
+ * @param workItemId - WorkItem id
191
+ */
192
+ schedule(workItemId) {
193
+ if (this.pending.has(workItemId))
194
+ return;
195
+ const t = setTimeout(() => {
196
+ this.pending.delete(workItemId);
197
+ void this.recordById(workItemId).catch((err) => {
198
+ this.logger.warn('WorkRecord: event-driven record failed (non-fatal)', { workItemId, error: err instanceof Error ? err.message : String(err) });
199
+ });
200
+ }, this.eventDelayMs);
201
+ t.unref?.();
202
+ this.pending.set(workItemId, t);
203
+ }
204
+ /** Items waiting for their event delay (tests). */
205
+ pendingCount() {
206
+ return this.pending.size;
207
+ }
208
+ /**
209
+ * Record one item by id if it is terminal.
210
+ *
211
+ * @param workItemId - WorkItem id
212
+ * @returns What happened
213
+ */
214
+ async recordById(workItemId) {
215
+ const wi = await this.deps.findWorkItem(workItemId);
216
+ if (!wi)
217
+ return { workItemId, phase: 'final', result: 'missing' };
218
+ if (!FINAL_RECORD_STATUSES.has(wi.status))
219
+ return { workItemId, phase: 'final', result: 'not_terminal' };
220
+ await this.loadState();
221
+ const all = await this.deps.listWorkItems();
222
+ const attempt = await this.recordItem(wi, 'final', all);
223
+ await this.saveState();
224
+ return attempt;
225
+ }
226
+ /**
227
+ * One pass: finished items of the window without a record (newest first,
228
+ * capped), then long-blocked items. Public for tests and an on-demand run.
229
+ *
230
+ * @param opts - `maxPerPass` caps the records written (default CATCHUP_MAX_PER_PASS)
231
+ * @returns Counts
232
+ */
233
+ async runOnce(opts = {}) {
234
+ const result = { candidates: 0, written: 0, deferred: 0, blocked: 0, refused: 0 };
235
+ if (this.running)
236
+ return result;
237
+ this.running = true;
238
+ this.transcriptCache = new Map();
239
+ this.prefixCache = null;
240
+ try {
241
+ await this.loadState();
242
+ const now = this.nowFn();
243
+ const all = await this.deps.listWorkItems();
244
+ const cutoff = now - C.CATCHUP_WINDOW_DAYS * 86_400_000;
245
+ const finals = all
246
+ .filter((wi) => FINAL_RECORD_STATUSES.has(wi.status) && isRecordableWorkItem(wi))
247
+ .filter((wi) => Date.parse(workItemEndedAt(wi)) >= cutoff)
248
+ .filter((wi) => !this.state.recorded[workRecordRef(wi.id, 'final')])
249
+ .sort((a, b) => Date.parse(workItemEndedAt(b)) - Date.parse(workItemEndedAt(a)));
250
+ const blocked = all
251
+ .filter((wi) => wi.status === 'blocked' && isRecordableWorkItem(wi))
252
+ .filter((wi) => now - Date.parse(wi.statusChangedAt ?? wi.createdAt) >= C.BLOCKED_AFTER_MS)
253
+ .filter((wi) => !this.state.recorded[workRecordRef(wi.id, 'blocked')]);
254
+ result.candidates = finals.length + blocked.length;
255
+ let budget = opts.maxPerPass ?? C.CATCHUP_MAX_PER_PASS;
256
+ for (const wi of finals) {
257
+ if (budget <= 0)
258
+ break;
259
+ const a = await this.safeRecord(wi, 'final', all);
260
+ if (a.result === 'written') {
261
+ result.written++;
262
+ budget--;
263
+ }
264
+ else if (a.result === 'deferred')
265
+ result.deferred++;
266
+ else if (a.result === 'refused' || a.result === 'no_vault')
267
+ result.refused++;
268
+ }
269
+ for (const wi of blocked) {
270
+ if (budget <= 0)
271
+ break;
272
+ const a = await this.safeRecord(wi, 'blocked', all);
273
+ if (a.result === 'written') {
274
+ result.blocked++;
275
+ budget--;
276
+ }
277
+ else if (a.result === 'refused' || a.result === 'no_vault')
278
+ result.refused++;
279
+ }
280
+ await this.saveState();
281
+ if (result.candidates > 0)
282
+ this.logger.info('WorkRecord pass', { ...result, remaining: Math.max(0, result.candidates - result.written - result.blocked - result.deferred - result.refused) });
283
+ return result;
284
+ }
285
+ finally {
286
+ this.running = false;
287
+ this.transcriptCache = new Map();
288
+ }
289
+ }
290
+ /**
291
+ * Assemble and write one record. Public for tests.
292
+ *
293
+ * @param wi - The WorkItem (terminal, or blocked for a `blocked` record)
294
+ * @param phase - Record phase
295
+ * @param all - Every WorkItem (children are looked up here)
296
+ * @returns What happened, with the record and body when assembled
297
+ */
298
+ async recordItem(wi, phase, all) {
299
+ const key = workRecordRef(wi.id, phase);
300
+ const base = { workItemId: wi.id, phase, result: 'written' };
301
+ if (!isRecordableWorkItem(wi))
302
+ return { ...base, result: 'not_recordable' };
303
+ if (this.state.recorded[key])
304
+ return { ...base, result: 'already_recorded' };
305
+ const [teams, projects] = await Promise.all([this.deps.listTeams(), this.deps.listProjects()]);
306
+ const { projectPath, teamId } = this.resolveProject(wi, teams, projects);
307
+ const vaults = await this.resolveVaults(projectPath, teamId);
308
+ if (vaults.length === 0)
309
+ return { ...base, result: 'no_vault' };
310
+ await this.seedFromVault(vaults[0]);
311
+ if (this.state.recorded[key])
312
+ return { ...base, result: 'already_recorded' };
313
+ const link = readProjectTicketLink(wi.metadata);
314
+ const [ticket, request, trace] = await Promise.all([
315
+ link && this.deps.getTicket ? this.deps.getTicket(link.projectPath, link.id).catch(() => null) : Promise.resolve(null),
316
+ wi.requestId && this.deps.getRequest ? this.deps.getRequest(wi.requestId).catch(() => null) : Promise.resolve(null),
317
+ this.deps.readTrace ? this.deps.readTrace(wi).catch(() => []) : Promise.resolve([]),
318
+ ]);
319
+ const children = all.filter((c) => c.id !== wi.id && (c.parentWorkItemId === wi.id || c.metadata?.verifyOf === wi.id || c.id.startsWith(`${wi.id}:verify:`) || (!!wi.target && c.metadata?.delegatedBy === wi.target)));
320
+ const transcript = phase === 'final' ? await this.transcriptFacts(wi, projectPath) : null;
321
+ const names = this.nameResolvers(teams);
322
+ const record = assembleWorkRecord({
323
+ workItem: wi,
324
+ phase,
325
+ ticket,
326
+ request,
327
+ children,
328
+ trace: trace.slice(0, C.TRACE_MAX_EVENTS),
329
+ transcript,
330
+ nameOf: names.nameOf,
331
+ kindOf: names.kindOf,
332
+ ticketPrefixes: await this.ticketPrefixes(all, projects),
333
+ now: this.nowFn(),
334
+ });
335
+ if (record.outcome === 'waiting_owner' && this.nowFn() - Date.parse(workItemEndedAt(wi)) < C.DEFER_MAX_MS) {
336
+ return { ...base, result: 'deferred', record };
337
+ }
338
+ const body = this.redact(renderWorkRecordBody(record));
339
+ let written = 0;
340
+ for (const vault of vaults) {
341
+ const outcome = await this.ingest.ingest({
342
+ vaultPath: vault,
343
+ sourceType: C.SOURCE_TYPE,
344
+ sourceRef: key,
345
+ sourceBody: body,
346
+ callerSession: wi.target ?? 'system:work-record',
347
+ });
348
+ if (outcome.ok || outcome.reason === 'duplicate')
349
+ written++;
350
+ else
351
+ this.logger.debug('WorkRecord: ingest refused', { vault, workItemId: wi.id, reason: outcome.reason });
352
+ }
353
+ if (written === 0)
354
+ return { ...base, result: 'refused', record, body, vaults };
355
+ this.remember(key);
356
+ this.logger.info('WorkRecord written', { workItemId: wi.id, phase, outcome: record.outcome, doneBy: record.doneBy.name, vaults: vaults.length, chars: body.length });
357
+ return { ...base, result: 'written', record, body, vaults };
358
+ }
359
+ // ---------------------------------------------------------------------------
360
+ async safeRecord(wi, phase, all) {
361
+ try {
362
+ return await this.recordItem(wi, phase, all);
363
+ }
364
+ catch (err) {
365
+ this.logger.warn('WorkRecord: record failed (non-fatal)', { workItemId: wi.id, phase, error: err instanceof Error ? err.message : String(err) });
366
+ return { workItemId: wi.id, phase, result: 'refused' };
367
+ }
368
+ }
369
+ /**
370
+ * The project the item belongs to: `metadata.projectPath`, the ticket's
371
+ * project, else the first project of the doer's (or `metadata.teamId`) team.
372
+ */
373
+ resolveProject(wi, teams, projects) {
374
+ const metaTeam = typeof wi.metadata?.teamId === 'string' ? wi.metadata.teamId : null;
375
+ const team = teams.find((t) => t.id === metaTeam) ?? teams.find((t) => (t.members ?? []).some((m) => m.sessionName === wi.target || m.agentId === wi.target)) ?? null;
376
+ const link = readProjectTicketLink(wi.metadata);
377
+ let projectPath = typeof wi.metadata?.projectPath === 'string' ? wi.metadata.projectPath : link?.projectPath ?? null;
378
+ if (!projectPath && team) {
379
+ const p = (team.projectIds ?? []).map((id) => projects.find((pr) => pr.id === id)).find((pr) => !!pr);
380
+ projectPath = p?.path ?? null;
381
+ }
382
+ if (!projectPath && typeof wi.metadata?.projectId === 'string') {
383
+ projectPath = projects.find((p) => p.id === wi.metadata?.projectId)?.path ?? null;
384
+ }
385
+ return { projectPath, teamId: team?.id ?? metaTeam };
386
+ }
387
+ /**
388
+ * Vaults to write: the project vault (falling back to the global vault
389
+ * when the project has none) and the team vault when it exists.
390
+ */
391
+ async resolveVaults(projectPath, teamId) {
392
+ const out = [];
393
+ const projectVault = projectPath ? path.join(projectPath, '.crewly', 'wiki') : null;
394
+ if (projectVault && existsSync(path.join(projectVault, 'SCHEMA.md')))
395
+ out.push(projectVault);
396
+ else if (existsSync(path.join(this.globalVaultPath, 'SCHEMA.md')))
397
+ out.push(this.globalVaultPath);
398
+ if (teamId) {
399
+ const teamVault = path.join(this.teamsRoot, teamId, 'wiki');
400
+ if (existsSync(path.join(teamVault, 'SCHEMA.md')) && !out.includes(teamVault))
401
+ out.push(teamVault);
402
+ }
403
+ return out;
404
+ }
405
+ nameResolvers(teams) {
406
+ const bySession = new Map();
407
+ for (const team of teams) {
408
+ const leadIds = new Set([team.leaderId, ...(team.leaderIds ?? [])].filter(Boolean));
409
+ for (const m of team.members ?? []) {
410
+ const info = { name: m.name, role: m.role, lead: leadIds.has(m.id) || isLeadRole(m.role) };
411
+ if (m.sessionName)
412
+ bySession.set(m.sessionName, info);
413
+ if (m.agentId)
414
+ bySession.set(m.agentId, info);
415
+ }
416
+ }
417
+ const nameOf = (s) => {
418
+ if (s === ORCHESTRATOR_SESSION_NAME)
419
+ return 'the orchestrator';
420
+ return bySession.get(s)?.name ?? memberName(s);
421
+ };
422
+ const kindOf = (s) => {
423
+ if (s === ORCHESTRATOR_SESSION_NAME)
424
+ return 'orchestrator';
425
+ const info = bySession.get(s);
426
+ if (!info)
427
+ return 'agent';
428
+ return info.lead ? 'lead' : 'agent';
429
+ };
430
+ return { nameOf, kindOf };
431
+ }
432
+ /**
433
+ * Ticket prefixes to strip from owner-facing text: every registered
434
+ * project's ticket counter (one small file each, read once per pass) plus
435
+ * the prefixes seen on pool items.
436
+ */
437
+ async ticketPrefixes(all, projects) {
438
+ const out = new Set();
439
+ for (const wi of all) {
440
+ const link = readProjectTicketLink(wi.metadata);
441
+ const dash = link?.id.indexOf('-') ?? -1;
442
+ if (link && dash > 0)
443
+ out.add(link.id.slice(0, dash));
444
+ }
445
+ const paths = projects.map((p) => p.path).filter((p) => typeof p === 'string' && p.length > 0);
446
+ this.prefixCache ??= (this.deps.listTicketPrefixes ?? ((roots) => listTicketPrefixes({ listProjectPaths: async () => [...roots] })))(paths).catch(() => []);
447
+ for (const p of await this.prefixCache)
448
+ out.add(p);
449
+ return [...out];
450
+ }
451
+ /**
452
+ * Facts from the doer's transcript for the task window, when the item is
453
+ * recent enough for the window to be in the tail. One tail read per
454
+ * session per pass.
455
+ */
456
+ async transcriptFacts(wi, projectPath) {
457
+ if (!this.deps.locateTranscript || !wi.target)
458
+ return null;
459
+ const endedMs = Date.parse(workItemEndedAt(wi));
460
+ if (!transcriptWorthReading(endedMs, this.nowFn()))
461
+ return null;
462
+ const session = wi.target;
463
+ let cached = this.transcriptCache.get(session);
464
+ if (!cached) {
465
+ const locate = this.deps.locateTranscript;
466
+ cached = (async () => {
467
+ try {
468
+ const target = await locate(session);
469
+ if (!target || target.kind !== 'claude')
470
+ return null;
471
+ return { kind: target.kind, text: await readTranscriptTail(target.file) };
472
+ }
473
+ catch {
474
+ return null;
475
+ }
476
+ })();
477
+ this.transcriptCache.set(session, cached);
478
+ }
479
+ const loaded = await cached;
480
+ if (!loaded)
481
+ return null;
482
+ const fromMs = Date.parse(wi.startedAt ?? wi.createdAt);
483
+ return parseClaudeTranscriptWindow(loaded.text, { fromMs: Number.isFinite(fromMs) ? fromMs : endedMs, toMs: endedMs }, projectPath ? [projectPath] : []);
484
+ }
485
+ /** Pattern-based redaction plus the process's known secret values. */
486
+ redact(body) {
487
+ const secrets = this.deps.secrets ? this.deps.secrets() : collectSecretEnvValues(process.env);
488
+ return redactSecrets(redactSensitive(body), secrets);
489
+ }
490
+ /** Seed the recorded set from a vault's log once, so a lost state file does not double-write. */
491
+ async seedFromVault(vault) {
492
+ if (this.seededVaults.has(vault))
493
+ return;
494
+ this.seededVaults.add(vault);
495
+ try {
496
+ const raw = await fs.readFile(path.join(vault, WIKI_LOG_CONSTANTS.LOG_RELATIVE_PATH), 'utf8');
497
+ for (const e of parseLogEntries(raw)) {
498
+ if (isWorkRecordEntry(e) && e.ref && !this.state.recorded[e.ref])
499
+ this.state.recorded[e.ref] = e.timestamp;
500
+ }
501
+ }
502
+ catch {
503
+ // no log yet
504
+ }
505
+ }
506
+ remember(key) {
507
+ this.state.recorded[key] = new Date(this.nowFn()).toISOString();
508
+ const keys = Object.keys(this.state.recorded);
509
+ if (keys.length > C.STATE_MAX_KEYS) {
510
+ const sorted = keys.sort((a, b) => Date.parse(this.state.recorded[a]) - Date.parse(this.state.recorded[b]));
511
+ for (const k of sorted.slice(0, keys.length - C.STATE_MAX_KEYS))
512
+ delete this.state.recorded[k];
513
+ }
514
+ }
515
+ async loadState() {
516
+ if (this.stateLoaded)
517
+ return;
518
+ this.stateLoaded = true;
519
+ if (!this.statePath)
520
+ return;
521
+ try {
522
+ const data = await safeReadJson(this.statePath, null);
523
+ if (data?.recorded && typeof data.recorded === 'object')
524
+ this.state = { recorded: { ...data.recorded } };
525
+ }
526
+ catch (err) {
527
+ this.logger.warn('WorkRecord: failed to load state (non-fatal)', { error: err instanceof Error ? err.message : String(err) });
528
+ }
529
+ }
530
+ async saveState() {
531
+ if (!this.statePath)
532
+ return;
533
+ try {
534
+ await ensureDir(path.dirname(this.statePath));
535
+ await atomicWriteJson(this.statePath, this.state);
536
+ }
537
+ catch (err) {
538
+ this.logger.warn('WorkRecord: failed to persist state (non-fatal)', { error: err instanceof Error ? err.message : String(err) });
539
+ }
540
+ }
541
+ }
542
+ //# sourceMappingURL=work-record.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-record.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/work-record.service.ts"],"names":[],"mappings":"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"}