crewly 1.20.307 → 1.20.309
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 +5 -5
- package/dist/backend/backend/src/constants.d.ts +80 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +80 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +9 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +161 -2
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/board/board-activity.normalizer.d.ts +17 -0
- package/dist/backend/backend/src/services/board/board-activity.normalizer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/board/board-activity.normalizer.js +8 -5
- package/dist/backend/backend/src/services/board/board-activity.normalizer.js.map +1 -1
- package/dist/backend/backend/src/services/board/board-activity.tracker.d.ts +5 -0
- package/dist/backend/backend/src/services/board/board-activity.tracker.d.ts.map +1 -1
- package/dist/backend/backend/src/services/board/board-activity.tracker.js +25 -1
- package/dist/backend/backend/src/services/board/board-activity.tracker.js.map +1 -1
- package/dist/backend/backend/src/services/board/board-interaction-hooks.d.ts +34 -0
- package/dist/backend/backend/src/services/board/board-interaction-hooks.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-interaction-hooks.js +60 -0
- package/dist/backend/backend/src/services/board/board-interaction-hooks.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-interactions.d.ts +54 -0
- package/dist/backend/backend/src/services/board/board-interactions.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-interactions.js +92 -0
- package/dist/backend/backend/src/services/board/board-interactions.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-links.d.ts +51 -0
- package/dist/backend/backend/src/services/board/board-links.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-links.js +168 -0
- package/dist/backend/backend/src/services/board/board-links.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-push.service.d.ts +28 -3
- package/dist/backend/backend/src/services/board/board-push.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/board/board-push.service.js +108 -9
- package/dist/backend/backend/src/services/board/board-push.service.js.map +1 -1
- package/dist/backend/backend/src/services/board/board-snapshot.builder.d.ts +39 -2
- package/dist/backend/backend/src/services/board/board-snapshot.builder.d.ts.map +1 -1
- package/dist/backend/backend/src/services/board/board-snapshot.builder.js +85 -8
- package/dist/backend/backend/src/services/board/board-snapshot.builder.js.map +1 -1
- package/dist/backend/backend/src/services/board/board.sources.d.ts.map +1 -1
- package/dist/backend/backend/src/services/board/board.sources.js +27 -1
- package/dist/backend/backend/src/services/board/board.sources.js.map +1 -1
- package/dist/backend/backend/src/services/board/board.types.d.ts +48 -0
- package/dist/backend/backend/src/services/board/board.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/board/board.types.js +9 -1
- package/dist/backend/backend/src/services/board/board.types.js.map +1 -1
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.d.ts +122 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.js +339 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.d.ts +44 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.js +161 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.d.ts +57 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.js +164 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.d.ts +140 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.js +300 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.d.ts +99 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.js +223 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.d.ts +126 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.js +385 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.d.ts +103 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.js +124 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.d.ts +88 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.js +8 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.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 +2 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +80 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +80 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcript tail for the canvas (crewly#1247 v2): the agent's own short text
|
|
3
|
+
* lines (and, for Codex, its tool calls) from the runtime's own transcript.
|
|
4
|
+
*
|
|
5
|
+
* - Claude Code: `<claude home>/projects/<cwd>/<session id>.jsonl` (located the
|
|
6
|
+
* way the turn-state fallback does). Only `assistant` `text` blocks become
|
|
7
|
+
* steps, reduced by {@link shortAgentLine}; a `tool_result`'s `is_error` flag
|
|
8
|
+
* marks its step failed. Tool inputs, tool OUTPUTS, thinking and user
|
|
9
|
+
* messages are never read into anything.
|
|
10
|
+
* - Codex: `<codex home>/sessions/.../rollout-*-<conversation id>.jsonl`.
|
|
11
|
+
* Assistant `output_text` becomes text steps; shell / exec / apply_patch
|
|
12
|
+
* calls become command / edit steps (reduced to executable + subcommand /
|
|
13
|
+
* file name), paired with their output by call id for the duration. Output
|
|
14
|
+
* bodies are not read.
|
|
15
|
+
*
|
|
16
|
+
* Incremental: a byte cursor per file, only whole new lines, at most
|
|
17
|
+
* {@link CANVAS_CONSTANTS.TAIL_MAX_READ_BYTES} per pass; lines that cannot be
|
|
18
|
+
* a text / error line are skipped by substring before any JSON.parse (tool
|
|
19
|
+
* results are the bulk of a transcript). Nothing is logged or stored beyond
|
|
20
|
+
* the redacted step.
|
|
21
|
+
*
|
|
22
|
+
* @module services/board/canvas/canvas-transcript.tail
|
|
23
|
+
*/
|
|
24
|
+
import type { SecretEnvValue } from '../../../utils/secret-env.js';
|
|
25
|
+
import { relativePath } from '../board-redact.js';
|
|
26
|
+
import { type StepShape } from './canvas-step.normalizer.js';
|
|
27
|
+
import type { StepStream } from './canvas-step.stream.js';
|
|
28
|
+
/** What a chunk of transcript says. */
|
|
29
|
+
export type TailItem = {
|
|
30
|
+
kind: 'text';
|
|
31
|
+
id: string;
|
|
32
|
+
at: number;
|
|
33
|
+
text: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'tool_error';
|
|
36
|
+
toolUseId: string;
|
|
37
|
+
at: number;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'step_start';
|
|
40
|
+
id: string;
|
|
41
|
+
at: number;
|
|
42
|
+
shape: StepShape;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'step_end';
|
|
45
|
+
id: string;
|
|
46
|
+
at: number;
|
|
47
|
+
};
|
|
48
|
+
/** Parse options. */
|
|
49
|
+
export interface TailParseOptions {
|
|
50
|
+
secrets?: readonly SecretEnvValue[];
|
|
51
|
+
roots?: readonly string[];
|
|
52
|
+
/** Drop text older than this (epoch ms) */
|
|
53
|
+
minAt?: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Items from whole lines of a Claude Code transcript.
|
|
57
|
+
*
|
|
58
|
+
* @param text - Whole JSONL lines
|
|
59
|
+
* @param opts - Secrets to mask, oldest text to keep
|
|
60
|
+
* @param now - Fallback time for an entry with no timestamp
|
|
61
|
+
* @returns Items in file order
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseClaudeTail(text: string, opts?: TailParseOptions, now?: number): TailItem[];
|
|
64
|
+
/**
|
|
65
|
+
* Items from whole lines of a Codex rollout.
|
|
66
|
+
*
|
|
67
|
+
* @param text - Whole JSONL lines
|
|
68
|
+
* @param opts - Secrets to mask, project roots, oldest text to keep
|
|
69
|
+
* @param now - Fallback time for an entry with no timestamp
|
|
70
|
+
* @returns Items in file order
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseCodexTail(text: string, opts?: TailParseOptions, now?: number): TailItem[];
|
|
73
|
+
/** Where a session's transcript is. */
|
|
74
|
+
export interface TailTarget {
|
|
75
|
+
kind: 'claude' | 'codex';
|
|
76
|
+
file: string;
|
|
77
|
+
}
|
|
78
|
+
/** Collaborators. */
|
|
79
|
+
export interface TranscriptTailDeps {
|
|
80
|
+
steps: StepStream;
|
|
81
|
+
/** Sessions to follow */
|
|
82
|
+
sessions: () => string[];
|
|
83
|
+
/** The session's transcript, or null (Gemini, agy: none) */
|
|
84
|
+
locate: (session: string) => Promise<TailTarget | null> | TailTarget | null;
|
|
85
|
+
/** Project roots of a session (relative paths) */
|
|
86
|
+
roots?: (session: string) => readonly string[];
|
|
87
|
+
/** Exact secret values to mask */
|
|
88
|
+
secrets?: () => readonly SecretEnvValue[];
|
|
89
|
+
/** Someone is watching: poll faster */
|
|
90
|
+
isLive?: () => boolean;
|
|
91
|
+
now?: () => number;
|
|
92
|
+
setTimeout?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;
|
|
93
|
+
clearTimeout?: (h: ReturnType<typeof setTimeout>) => void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Follows the transcripts of the agents and feeds the step stream.
|
|
97
|
+
*/
|
|
98
|
+
export declare class TranscriptTailService {
|
|
99
|
+
private readonly deps;
|
|
100
|
+
private readonly cursors;
|
|
101
|
+
private readonly located;
|
|
102
|
+
private timer;
|
|
103
|
+
private running;
|
|
104
|
+
private started;
|
|
105
|
+
private readonly now;
|
|
106
|
+
private readonly setTimer;
|
|
107
|
+
private readonly clearTimer;
|
|
108
|
+
constructor(deps: TranscriptTailDeps);
|
|
109
|
+
/** Start polling. Idempotent. */
|
|
110
|
+
start(): void;
|
|
111
|
+
/** Stop polling. */
|
|
112
|
+
stop(): void;
|
|
113
|
+
private schedule;
|
|
114
|
+
/**
|
|
115
|
+
* One pass over every followed session. Never throws.
|
|
116
|
+
*
|
|
117
|
+
* @returns Items fed to the stream
|
|
118
|
+
*/
|
|
119
|
+
tick(): Promise<number>;
|
|
120
|
+
private target;
|
|
121
|
+
private follow;
|
|
122
|
+
private feed;
|
|
123
|
+
}
|
|
124
|
+
/** Re-exported for the wiring: a path made relative to project roots. */
|
|
125
|
+
export { relativePath };
|
|
126
|
+
//# sourceMappingURL=canvas-transcript.tail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-transcript.tail.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/board/canvas/canvas-transcript.tail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcript tail for the canvas (crewly#1247 v2): the agent's own short text
|
|
3
|
+
* lines (and, for Codex, its tool calls) from the runtime's own transcript.
|
|
4
|
+
*
|
|
5
|
+
* - Claude Code: `<claude home>/projects/<cwd>/<session id>.jsonl` (located the
|
|
6
|
+
* way the turn-state fallback does). Only `assistant` `text` blocks become
|
|
7
|
+
* steps, reduced by {@link shortAgentLine}; a `tool_result`'s `is_error` flag
|
|
8
|
+
* marks its step failed. Tool inputs, tool OUTPUTS, thinking and user
|
|
9
|
+
* messages are never read into anything.
|
|
10
|
+
* - Codex: `<codex home>/sessions/.../rollout-*-<conversation id>.jsonl`.
|
|
11
|
+
* Assistant `output_text` becomes text steps; shell / exec / apply_patch
|
|
12
|
+
* calls become command / edit steps (reduced to executable + subcommand /
|
|
13
|
+
* file name), paired with their output by call id for the duration. Output
|
|
14
|
+
* bodies are not read.
|
|
15
|
+
*
|
|
16
|
+
* Incremental: a byte cursor per file, only whole new lines, at most
|
|
17
|
+
* {@link CANVAS_CONSTANTS.TAIL_MAX_READ_BYTES} per pass; lines that cannot be
|
|
18
|
+
* a text / error line are skipped by substring before any JSON.parse (tool
|
|
19
|
+
* results are the bulk of a transcript). Nothing is logged or stored beyond
|
|
20
|
+
* the redacted step.
|
|
21
|
+
*
|
|
22
|
+
* @module services/board/canvas/canvas-transcript.tail
|
|
23
|
+
*/
|
|
24
|
+
import { createHash } from 'crypto';
|
|
25
|
+
import { promises as fs } from 'fs';
|
|
26
|
+
import { CANVAS_CONSTANTS } from '../../../constants.js';
|
|
27
|
+
import { relativePath } from '../board-redact.js';
|
|
28
|
+
import { shortAgentLine } from './canvas-redact.js';
|
|
29
|
+
import { stepOfTool } from './canvas-step.normalizer.js';
|
|
30
|
+
const C = CANVAS_CONSTANTS;
|
|
31
|
+
const toMs = (v, fallback) => {
|
|
32
|
+
const t = typeof v === 'string' ? Date.parse(v) : NaN;
|
|
33
|
+
return Number.isFinite(t) ? t : fallback;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Items from whole lines of a Claude Code transcript.
|
|
37
|
+
*
|
|
38
|
+
* @param text - Whole JSONL lines
|
|
39
|
+
* @param opts - Secrets to mask, oldest text to keep
|
|
40
|
+
* @param now - Fallback time for an entry with no timestamp
|
|
41
|
+
* @returns Items in file order
|
|
42
|
+
*/
|
|
43
|
+
export function parseClaudeTail(text, opts = {}, now = Date.now()) {
|
|
44
|
+
const out = [];
|
|
45
|
+
for (const line of text.split('\n')) {
|
|
46
|
+
if (line.length < 20)
|
|
47
|
+
continue;
|
|
48
|
+
const isAssistantText = line.includes('"type":"assistant"') && line.includes('"type":"text"');
|
|
49
|
+
const isError = line.includes('"is_error":true') && line.includes('"tool_result"');
|
|
50
|
+
if (!isAssistantText && !isError)
|
|
51
|
+
continue;
|
|
52
|
+
let entry;
|
|
53
|
+
try {
|
|
54
|
+
entry = JSON.parse(line);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// A subagent's chatter is not the agent's; meta / API-error entries are not its words
|
|
60
|
+
if (entry.isSidechain === true || entry.isMeta === true || entry.isApiErrorMessage === true)
|
|
61
|
+
continue;
|
|
62
|
+
const message = entry.message;
|
|
63
|
+
const content = message?.content;
|
|
64
|
+
if (!Array.isArray(content))
|
|
65
|
+
continue;
|
|
66
|
+
const at = toMs(entry.timestamp, now);
|
|
67
|
+
if (entry.type === 'assistant') {
|
|
68
|
+
const uuid = typeof entry.uuid === 'string' ? entry.uuid : `${at}`;
|
|
69
|
+
content.forEach((block, i) => {
|
|
70
|
+
const b = block;
|
|
71
|
+
if (b?.type !== 'text')
|
|
72
|
+
return;
|
|
73
|
+
if (opts.minAt !== undefined && at < opts.minAt)
|
|
74
|
+
return;
|
|
75
|
+
const t = shortAgentLine(b.text, opts.secrets ?? []);
|
|
76
|
+
if (t)
|
|
77
|
+
out.push({ kind: 'text', id: `${uuid}:${i}`, at, text: t });
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else if (entry.type === 'user') {
|
|
81
|
+
for (const block of content) {
|
|
82
|
+
const b = block;
|
|
83
|
+
// Only the flag and the id are read; the result's content never is
|
|
84
|
+
if (b?.type === 'tool_result' && b.is_error === true && typeof b.tool_use_id === 'string' && /^[A-Za-z0-9_-]{1,128}$/.test(b.tool_use_id)) {
|
|
85
|
+
out.push({ kind: 'tool_error', toolUseId: b.tool_use_id, at });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
/** The shell command a Codex call runs, from its (JSON) arguments or its JS wrapper. */
|
|
93
|
+
function codexCommand(name, raw) {
|
|
94
|
+
if (typeof raw !== 'string' || raw.length > 20_000)
|
|
95
|
+
return null;
|
|
96
|
+
if (name === 'exec') {
|
|
97
|
+
// The code-mode wrapper: `tools.exec_command({cmd:"..."})`
|
|
98
|
+
const m = /\bcmd\s*:\s*("(?:[^"\\]|\\.)*")/.exec(raw);
|
|
99
|
+
if (!m)
|
|
100
|
+
return null;
|
|
101
|
+
try {
|
|
102
|
+
return JSON.parse(m[1]);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const args = JSON.parse(raw);
|
|
110
|
+
const c = args.command ?? args.cmd;
|
|
111
|
+
if (typeof c === 'string')
|
|
112
|
+
return c;
|
|
113
|
+
if (Array.isArray(c) && c.every((x) => typeof x === 'string')) {
|
|
114
|
+
const words = c;
|
|
115
|
+
// ["bash","-lc","git status"] runs the last word
|
|
116
|
+
return /^(?:ba|z|da)?sh$/.test(words[0] ?? '') && words.length >= 3 ? words[words.length - 1] : words.join(' ');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const PATCH_FILE = /^\*\*\* (?:Update|Add|Delete) File: (.+)$/m;
|
|
125
|
+
/**
|
|
126
|
+
* Items from whole lines of a Codex rollout.
|
|
127
|
+
*
|
|
128
|
+
* @param text - Whole JSONL lines
|
|
129
|
+
* @param opts - Secrets to mask, project roots, oldest text to keep
|
|
130
|
+
* @param now - Fallback time for an entry with no timestamp
|
|
131
|
+
* @returns Items in file order
|
|
132
|
+
*/
|
|
133
|
+
export function parseCodexTail(text, opts = {}, now = Date.now()) {
|
|
134
|
+
const out = [];
|
|
135
|
+
const textId = (t) => `cx-${createHash('sha1').update(t).digest('hex').slice(0, 14)}`;
|
|
136
|
+
for (const line of text.split('\n')) {
|
|
137
|
+
if (line.length < 20)
|
|
138
|
+
continue;
|
|
139
|
+
const interesting = line.includes('"output_text"') || line.includes('"agent_message"') || line.includes('"function_call') || line.includes('"custom_tool_call');
|
|
140
|
+
if (!interesting)
|
|
141
|
+
continue;
|
|
142
|
+
let entry;
|
|
143
|
+
try {
|
|
144
|
+
entry = JSON.parse(line);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const p = entry.payload;
|
|
150
|
+
if (!p || typeof p !== 'object')
|
|
151
|
+
continue;
|
|
152
|
+
const at = toMs(entry.timestamp, now);
|
|
153
|
+
if (entry.type === 'event_msg' && p.type === 'agent_message' && typeof p.message === 'string') {
|
|
154
|
+
if (opts.minAt !== undefined && at < opts.minAt)
|
|
155
|
+
continue;
|
|
156
|
+
const t = shortAgentLine(p.message, opts.secrets ?? []);
|
|
157
|
+
if (t)
|
|
158
|
+
out.push({ kind: 'text', id: textId(t), at, text: t });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (entry.type !== 'response_item')
|
|
162
|
+
continue;
|
|
163
|
+
if (p.type === 'message' && p.role === 'assistant' && Array.isArray(p.content)) {
|
|
164
|
+
if (opts.minAt !== undefined && at < opts.minAt)
|
|
165
|
+
continue;
|
|
166
|
+
for (const block of p.content) {
|
|
167
|
+
if (block?.type !== 'output_text')
|
|
168
|
+
continue;
|
|
169
|
+
const t = shortAgentLine(block.text, opts.secrets ?? []);
|
|
170
|
+
if (t)
|
|
171
|
+
out.push({ kind: 'text', id: textId(t), at, text: t });
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const callId = typeof p.call_id === 'string' && /^[A-Za-z0-9_-]{1,128}$/.test(p.call_id) ? p.call_id : null;
|
|
176
|
+
if (!callId)
|
|
177
|
+
continue;
|
|
178
|
+
if (p.type === 'function_call' || p.type === 'custom_tool_call' || p.type === 'local_shell_call') {
|
|
179
|
+
if (opts.minAt !== undefined && at < opts.minAt)
|
|
180
|
+
continue;
|
|
181
|
+
const name = typeof p.name === 'string' ? p.name : '';
|
|
182
|
+
if (name === 'apply_patch') {
|
|
183
|
+
const file = PATCH_FILE.exec(typeof p.input === 'string' ? p.input : typeof p.arguments === 'string' ? p.arguments : '')?.[1]?.trim();
|
|
184
|
+
const shape = stepOfTool('Edit', file ? { filePath: file } : {}, { roots: opts.roots ?? [] });
|
|
185
|
+
out.push({ kind: 'step_start', id: callId, at, shape });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const command = codexCommand(name, name === 'exec' ? p.input : p.arguments);
|
|
189
|
+
if (command)
|
|
190
|
+
out.push({ kind: 'step_start', id: callId, at, shape: stepOfTool('Bash', { command }, { roots: opts.roots ?? [] }) });
|
|
191
|
+
else if (name && name !== 'exec')
|
|
192
|
+
out.push({ kind: 'step_start', id: callId, at, shape: stepOfTool(name, {}, { roots: opts.roots ?? [] }) });
|
|
193
|
+
}
|
|
194
|
+
else if (p.type === 'function_call_output' || p.type === 'custom_tool_call_output') {
|
|
195
|
+
out.push({ kind: 'step_end', id: callId, at });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Follows the transcripts of the agents and feeds the step stream.
|
|
202
|
+
*/
|
|
203
|
+
export class TranscriptTailService {
|
|
204
|
+
deps;
|
|
205
|
+
cursors = new Map();
|
|
206
|
+
located = new Map();
|
|
207
|
+
timer = null;
|
|
208
|
+
running = false;
|
|
209
|
+
started = false;
|
|
210
|
+
now;
|
|
211
|
+
setTimer;
|
|
212
|
+
clearTimer;
|
|
213
|
+
constructor(deps) {
|
|
214
|
+
this.deps = deps;
|
|
215
|
+
this.now = deps.now ?? Date.now;
|
|
216
|
+
this.setTimer =
|
|
217
|
+
deps.setTimeout ??
|
|
218
|
+
((fn, ms) => {
|
|
219
|
+
const t = setTimeout(fn, ms);
|
|
220
|
+
t.unref?.();
|
|
221
|
+
return t;
|
|
222
|
+
});
|
|
223
|
+
this.clearTimer = deps.clearTimeout ?? ((h) => clearTimeout(h));
|
|
224
|
+
}
|
|
225
|
+
/** Start polling. Idempotent. */
|
|
226
|
+
start() {
|
|
227
|
+
if (this.started)
|
|
228
|
+
return;
|
|
229
|
+
this.started = true;
|
|
230
|
+
this.schedule();
|
|
231
|
+
}
|
|
232
|
+
/** Stop polling. */
|
|
233
|
+
stop() {
|
|
234
|
+
this.started = false;
|
|
235
|
+
if (this.timer)
|
|
236
|
+
this.clearTimer(this.timer);
|
|
237
|
+
this.timer = null;
|
|
238
|
+
}
|
|
239
|
+
schedule() {
|
|
240
|
+
if (!this.started)
|
|
241
|
+
return;
|
|
242
|
+
const live = this.deps.isLive?.() ?? false;
|
|
243
|
+
this.timer = this.setTimer(() => {
|
|
244
|
+
this.timer = null;
|
|
245
|
+
void this.tick().finally(() => this.schedule());
|
|
246
|
+
}, live ? C.TAIL_LIVE_INTERVAL_MS : C.TAIL_IDLE_INTERVAL_MS);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* One pass over every followed session. Never throws.
|
|
250
|
+
*
|
|
251
|
+
* @returns Items fed to the stream
|
|
252
|
+
*/
|
|
253
|
+
async tick() {
|
|
254
|
+
if (this.running)
|
|
255
|
+
return 0;
|
|
256
|
+
this.running = true;
|
|
257
|
+
let fed = 0;
|
|
258
|
+
try {
|
|
259
|
+
const sessions = this.deps.sessions();
|
|
260
|
+
for (const session of sessions) {
|
|
261
|
+
try {
|
|
262
|
+
fed += await this.follow(session);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// one unreadable transcript must not stop the others
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const known = new Set(sessions);
|
|
269
|
+
for (const key of [...this.cursors.keys()])
|
|
270
|
+
if (!known.has(key))
|
|
271
|
+
this.cursors.delete(key);
|
|
272
|
+
for (const key of [...this.located.keys()])
|
|
273
|
+
if (!known.has(key))
|
|
274
|
+
this.located.delete(key);
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
this.running = false;
|
|
278
|
+
}
|
|
279
|
+
return fed;
|
|
280
|
+
}
|
|
281
|
+
async target(session) {
|
|
282
|
+
const now = this.now();
|
|
283
|
+
const hit = this.located.get(session);
|
|
284
|
+
if (hit && now - hit.at < C.TAIL_LOCATE_TTL_MS)
|
|
285
|
+
return hit.target;
|
|
286
|
+
let target = null;
|
|
287
|
+
try {
|
|
288
|
+
target = await this.deps.locate(session);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
target = null;
|
|
292
|
+
}
|
|
293
|
+
this.located.set(session, { at: now, target });
|
|
294
|
+
return target;
|
|
295
|
+
}
|
|
296
|
+
async follow(session) {
|
|
297
|
+
const target = await this.target(session);
|
|
298
|
+
if (!target) {
|
|
299
|
+
this.cursors.delete(session);
|
|
300
|
+
return 0;
|
|
301
|
+
}
|
|
302
|
+
let size;
|
|
303
|
+
try {
|
|
304
|
+
size = (await fs.stat(target.file)).size;
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
this.located.delete(session);
|
|
308
|
+
return 0;
|
|
309
|
+
}
|
|
310
|
+
let cursor = this.cursors.get(session);
|
|
311
|
+
if (!cursor || cursor.file !== target.file || size < cursor.offset) {
|
|
312
|
+
cursor = { file: target.file, kind: target.kind, offset: Math.max(0, size - C.TAIL_FIRST_READ_BYTES), fresh: true };
|
|
313
|
+
this.cursors.set(session, cursor);
|
|
314
|
+
}
|
|
315
|
+
if (size === cursor.offset)
|
|
316
|
+
return 0;
|
|
317
|
+
let from = cursor.offset;
|
|
318
|
+
if (size - from > C.TAIL_MAX_READ_BYTES)
|
|
319
|
+
from = size - C.TAIL_MAX_READ_BYTES;
|
|
320
|
+
const handle = await fs.open(target.file, 'r');
|
|
321
|
+
let buf;
|
|
322
|
+
try {
|
|
323
|
+
buf = Buffer.alloc(size - from);
|
|
324
|
+
await handle.read(buf, 0, buf.length, from);
|
|
325
|
+
}
|
|
326
|
+
finally {
|
|
327
|
+
await handle.close();
|
|
328
|
+
}
|
|
329
|
+
// Work in bytes: a multi-byte character cut at the end must not shift the cursor
|
|
330
|
+
const lastNl = buf.lastIndexOf(0x0a);
|
|
331
|
+
if (lastNl < 0)
|
|
332
|
+
return 0;
|
|
333
|
+
// A read that starts mid-file starts mid-line: skip to the first whole line
|
|
334
|
+
const startedMidFile = from > 0 && (from !== cursor.offset || cursor.fresh);
|
|
335
|
+
const firstNl = startedMidFile ? buf.indexOf(0x0a) : -1;
|
|
336
|
+
if (startedMidFile && firstNl >= lastNl) {
|
|
337
|
+
cursor.offset = from + lastNl + 1;
|
|
338
|
+
return 0;
|
|
339
|
+
}
|
|
340
|
+
const complete = buf.subarray(startedMidFile ? firstNl + 1 : 0, lastNl).toString('utf-8');
|
|
341
|
+
cursor.offset = from + lastNl + 1;
|
|
342
|
+
const now = this.now();
|
|
343
|
+
const opts = {
|
|
344
|
+
secrets: this.deps.secrets?.() ?? [],
|
|
345
|
+
roots: this.deps.roots?.(session) ?? [],
|
|
346
|
+
...(cursor.fresh ? { minAt: now - C.TAIL_FIRST_MAX_AGE_MS } : {}),
|
|
347
|
+
};
|
|
348
|
+
cursor.fresh = false;
|
|
349
|
+
const items = cursor.kind === 'claude' ? parseClaudeTail(complete, opts, now) : parseCodexTail(complete, opts, now);
|
|
350
|
+
return this.feed(session, items, cursor.kind === 'codex');
|
|
351
|
+
}
|
|
352
|
+
feed(session, items, callsAreSteps) {
|
|
353
|
+
let fed = 0;
|
|
354
|
+
const steps = this.deps.steps;
|
|
355
|
+
// A flood of narration (first look, a long pass) keeps the newest lines
|
|
356
|
+
const texts = items.filter((i) => i.kind === 'text');
|
|
357
|
+
const keep = new Set(texts.slice(-10));
|
|
358
|
+
for (const item of items) {
|
|
359
|
+
switch (item.kind) {
|
|
360
|
+
case 'text':
|
|
361
|
+
if (keep.has(item) && steps.text(session, item.id, item.at, item.text))
|
|
362
|
+
fed += 1;
|
|
363
|
+
break;
|
|
364
|
+
case 'tool_error':
|
|
365
|
+
steps.markError(session, item.toolUseId, item.at);
|
|
366
|
+
break;
|
|
367
|
+
case 'step_start':
|
|
368
|
+
// Codex has no hooks: its calls are the steps
|
|
369
|
+
if (callsAreSteps) {
|
|
370
|
+
steps.start(session, item.shape, { id: item.id }, item.at);
|
|
371
|
+
fed += 1;
|
|
372
|
+
}
|
|
373
|
+
break;
|
|
374
|
+
case 'step_end':
|
|
375
|
+
if (callsAreSteps)
|
|
376
|
+
steps.finish(session, item.id, 'done', item.at);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return fed;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/** Re-exported for the wiring: a path made relative to project roots. */
|
|
384
|
+
export { relativePath };
|
|
385
|
+
//# sourceMappingURL=canvas-transcript.tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-transcript.tail.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/board/canvas/canvas-transcript.tail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production pieces of the canvas that need the running machine (crewly#1247
|
|
3
|
+
* v2): where an agent's transcript is, how an owner stop is done, which
|
|
4
|
+
* secrets to mask. Kept out of `index.ts`; each takes its collaborators, so
|
|
5
|
+
* each is tested with fakes.
|
|
6
|
+
*
|
|
7
|
+
* @module services/board/canvas/canvas-wiring
|
|
8
|
+
*/
|
|
9
|
+
import { type SecretEnvValue } from '../../../utils/secret-env.js';
|
|
10
|
+
import type { AgentCapabilities } from './canvas.types.js';
|
|
11
|
+
import type { TailTarget } from './canvas-transcript.tail.js';
|
|
12
|
+
/** What the session registry knows about an agent's runtime conversation. */
|
|
13
|
+
export interface SessionMeta {
|
|
14
|
+
runtimeType?: string;
|
|
15
|
+
claudeSessionId?: string;
|
|
16
|
+
cwd?: string;
|
|
17
|
+
env?: Record<string, string | undefined>;
|
|
18
|
+
}
|
|
19
|
+
/** Collaborators of {@link createTranscriptLocator}. */
|
|
20
|
+
export interface TranscriptLocatorDeps {
|
|
21
|
+
meta: (session: string) => SessionMeta | undefined;
|
|
22
|
+
/** Claude Code homes to look in (the session's CLAUDE_CONFIG_DIR first) */
|
|
23
|
+
claudeHomes: (meta: SessionMeta) => string[];
|
|
24
|
+
findClaude: (args: {
|
|
25
|
+
sessionId: string;
|
|
26
|
+
cwd: string;
|
|
27
|
+
claudeHomes: readonly string[];
|
|
28
|
+
}) => string | null;
|
|
29
|
+
codexHome: () => string;
|
|
30
|
+
findCodex: (codexHome: string, conversationId: string) => Promise<string | null>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Where an agent's transcript is: a Claude Code conversation file or a Codex
|
|
34
|
+
* rollout. Gemini and agy keep none the canvas can read.
|
|
35
|
+
*
|
|
36
|
+
* @param deps - Session registry and the runtimes' finders
|
|
37
|
+
* @returns Locator for {@link TranscriptTailService}
|
|
38
|
+
*/
|
|
39
|
+
export declare function createTranscriptLocator(deps: TranscriptLocatorDeps): (session: string) => Promise<TailTarget | null>;
|
|
40
|
+
/** Secret values of the backend's environment, recomputed at most once a minute. */
|
|
41
|
+
export declare function createSecretsProvider(env?: () => NodeJS.ProcessEnv, ttlMs?: number, now?: () => number): () => SecretEnvValue[];
|
|
42
|
+
/** A team as the stop needs it. */
|
|
43
|
+
export interface StopTeam {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
members: Array<{
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
sessionName?: string;
|
|
50
|
+
agentId?: string;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
/** Collaborators of {@link createStopAgent}. */
|
|
54
|
+
export interface StopAgentDeps {
|
|
55
|
+
webPort: number;
|
|
56
|
+
teams: () => Promise<StopTeam[]>;
|
|
57
|
+
/** Credentials of the owner's own calls (relay credential + API token) */
|
|
58
|
+
headers: () => Record<string, string>;
|
|
59
|
+
fetchImpl?: typeof fetch;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Stop an agent the way the dashboard does: `POST /api/teams/:teamId/members/:memberId/stop`
|
|
63
|
+
* on the local API, with the relay's owner credential.
|
|
64
|
+
*
|
|
65
|
+
* @param deps - Teams, port, credentials
|
|
66
|
+
* @returns Stop function
|
|
67
|
+
*/
|
|
68
|
+
export declare function createStopAgent(deps: StopAgentDeps): (session: string) => Promise<{
|
|
69
|
+
ok: boolean;
|
|
70
|
+
error?: string;
|
|
71
|
+
}>;
|
|
72
|
+
/** The remote-browser session of an agent, as far as capabilities need it. */
|
|
73
|
+
export interface BrowserSessionLike {
|
|
74
|
+
id: string;
|
|
75
|
+
status: string;
|
|
76
|
+
lastActionAt: number;
|
|
77
|
+
}
|
|
78
|
+
/** Collaborators of {@link computeCapabilities}. */
|
|
79
|
+
export interface CapabilityDeps {
|
|
80
|
+
browserSession: (session: string) => BrowserSessionLike | undefined;
|
|
81
|
+
terminalExists: (session: string) => boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* What the owner can do with an agent from the canvas.
|
|
85
|
+
*
|
|
86
|
+
* - browser: the agent's Chrome-extension session (the existing remote-browser
|
|
87
|
+
* session id) while it is live. Headless Playwright runs inside the agent's
|
|
88
|
+
* own runtime as an MCP child process the harness has no handle on, so no
|
|
89
|
+
* `headless` browser is ever offered;
|
|
90
|
+
* - terminal: the agent has a live PTY session;
|
|
91
|
+
* - message: every agent (a sleeping one is woken by the message);
|
|
92
|
+
* - stop: every running agent except the orchestrator.
|
|
93
|
+
*
|
|
94
|
+
* @param session - Agent session
|
|
95
|
+
* @param info - Whether the agent is stopped, and the time
|
|
96
|
+
* @param deps - Browser sessions and the PTY backend
|
|
97
|
+
* @returns Capabilities
|
|
98
|
+
*/
|
|
99
|
+
export declare function computeCapabilities(session: string, info: {
|
|
100
|
+
stopped: boolean;
|
|
101
|
+
now: number;
|
|
102
|
+
}, deps: CapabilityDeps): AgentCapabilities;
|
|
103
|
+
//# sourceMappingURL=canvas-wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-wiring.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/board/canvas/canvas-wiring.ts"],"names":[],"mappings":"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"}
|