@link-assistant/hive-mind 1.78.0 → 1.78.2
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/CHANGELOG.md +37 -0
- package/package.json +1 -1
- package/src/agent.lib.mjs +2 -1
- package/src/claude.lib.mjs +2 -2
- package/src/claude.runtime-switch.lib.mjs +2 -1
- package/src/codex.lib.mjs +2 -1
- package/src/config.lib.mjs +2 -1
- package/src/contributing-guidelines.lib.mjs +2 -1
- package/src/gemini.lib.mjs +2 -1
- package/src/github-entity-validation.lib.mjs +2 -1
- package/src/github-error-reporter.lib.mjs +2 -1
- package/src/github.batch.lib.mjs +2 -1
- package/src/github.lib.mjs +2 -1
- package/src/handoff-skill.lib.mjs +2 -1
- package/src/hive.mjs +11 -10
- package/src/interactive-codex-events.lib.mjs +167 -0
- package/src/interactive-mode.lib.mjs +62 -152
- package/src/interactive-mode.shared.lib.mjs +1 -0
- package/src/interactive-system-events.lib.mjs +224 -0
- package/src/isolation-runner.lib.mjs +2 -1
- package/src/lenv-reader.lib.mjs +2 -1
- package/src/lib.mjs +2 -1
- package/src/lino.lib.mjs +2 -1
- package/src/local-ci-checks.lib.mjs +2 -1
- package/src/log-upload.lib.mjs +2 -1
- package/src/memory-check.mjs +2 -1
- package/src/models/index.mjs +2 -1
- package/src/npm-global-prefix.lib.mjs +160 -0
- package/src/opencode.lib.mjs +2 -1
- package/src/playwright-mcp.lib.mjs +2 -1
- package/src/protect-branch.mjs +2 -1
- package/src/queue-config.lib.mjs +2 -1
- package/src/qwen.lib.mjs +2 -1
- package/src/review.mjs +2 -1
- package/src/reviewers-hive.mjs +2 -1
- package/src/session-monitor.lib.mjs +82 -22
- package/src/solve.auto-continue.lib.mjs +2 -1
- package/src/solve.auto-ensure.lib.mjs +2 -1
- package/src/solve.auto-merge-helpers.lib.mjs +2 -1
- package/src/solve.auto-merge.lib.mjs +2 -1
- package/src/solve.bootstrap.lib.mjs +2 -1
- package/src/solve.escalate.lib.mjs +2 -1
- package/src/solve.execution.lib.mjs +2 -1
- package/src/solve.fork-detection.lib.mjs +2 -1
- package/src/solve.fork-sync.lib.mjs +2 -1
- package/src/solve.keep-working.lib.mjs +2 -1
- package/src/solve.mjs +2 -2
- package/src/solve.repository.lib.mjs +2 -1
- package/src/solve.restart-shared.lib.mjs +2 -1
- package/src/solve.results.lib.mjs +2 -1
- package/src/solve.validation.lib.mjs +2 -1
- package/src/solve.watch.lib.mjs +2 -1
- package/src/telegram-bot.mjs +2 -1
- package/src/token-sanitization.lib.mjs +2 -1
- package/src/tool-comments.lib.mjs +2 -1
- package/src/use-m-bootstrap.lib.mjs +23 -0
- package/src/useless-tools.lib.mjs +2 -1
- package/src/youtrack/youtrack.lib.mjs +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.78.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 70db26f: Ensure Telegram work-session completion messages recover pull request links from completed solve logs when linked-issue lookup does not return a PR.
|
|
8
|
+
|
|
9
|
+
## 1.78.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- dc8bb99: Group interactive `system.thinking_tokens` events into one editable PR comment and handle observed system lifecycle events without unrecognized-event noise.
|
|
14
|
+
- d704dfc: fix(install): redirect npm global prefix when root-owned to avoid EACCES at startup (#1897)
|
|
15
|
+
|
|
16
|
+
`use-m` loads runtime dependencies (command-stream, getenv, yargs, …) by shelling
|
|
17
|
+
out to `npm install -g <alias>@npm:<pkg>@latest`, which installs into the global
|
|
18
|
+
prefix reported by `npm root -g`. When the CLI was launched under a system-wide
|
|
19
|
+
Node.js whose global `node_modules` is owned by root (e.g.
|
|
20
|
+
`/opt/node-v24.16.0-linux-x64/lib/node_modules`), that install failed with
|
|
21
|
+
`npm error code EACCES … rename … command-stream-v-latest` and the whole process
|
|
22
|
+
crashed at the very first `use()` call (`Error: Failed to install
|
|
23
|
+
command-stream@latest globally.`). This commonly happens when hive-mind was
|
|
24
|
+
installed with `bun add -g` (user-owned `~/.bun/...`) but invoked under a system
|
|
25
|
+
Node whose global prefix needs root.
|
|
26
|
+
|
|
27
|
+
The new `src/npm-global-prefix.lib.mjs` preflight mirrors npm's own documented
|
|
28
|
+
EACCES remedy: before any real `use-m` bootstrap runs, it detects a non-writable
|
|
29
|
+
npm global prefix and redirects `npm_config_prefix` (honoured by both
|
|
30
|
+
`npm install -g` and `npm root -g`) to a user-writable `~/.npm-global`,
|
|
31
|
+
prepending its `bin` to `PATH`. The common case where the prefix is already
|
|
32
|
+
writable stays a no-op with no extra `npm` spawn.
|
|
33
|
+
|
|
34
|
+
Hive Mind now routes direct repository `use-m` bootstraps through
|
|
35
|
+
`src/use-m-bootstrap.lib.mjs`, including CLI entry points, shared source modules,
|
|
36
|
+
scripts, and executable tests. The workaround skips Windows' different global
|
|
37
|
+
layout, skips Bun/Deno runtimes, and respects explicitly preset
|
|
38
|
+
`npm_config_prefix` or `NPM_CONFIG_PREFIX` values.
|
|
39
|
+
|
|
3
40
|
## 1.78.0
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
package/package.json
CHANGED
package/src/agent.lib.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
// Agent-related utility functions
|
|
3
4
|
|
|
4
5
|
// Check if use is already defined (when imported from solve.mjs)
|
|
5
6
|
// If not, fetch it (when running standalone)
|
|
6
7
|
if (typeof globalThis.use === 'undefined') {
|
|
7
|
-
|
|
8
|
+
await ensureUseM();
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const { $ } = await use('command-stream');
|
package/src/claude.lib.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
3
3
|
if (typeof globalThis.use === 'undefined') {
|
|
4
|
-
|
|
4
|
+
await ensureUseM();
|
|
5
5
|
}
|
|
6
6
|
const { $ } = await use('command-stream');
|
|
7
7
|
const fs = (await use('fs')).promises;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
// Claude runtime switching module
|
|
3
4
|
// Extracted from claude.lib.mjs to maintain file line limits
|
|
4
5
|
// See: docs/case-studies/issue-1141
|
|
5
6
|
|
|
6
7
|
// If not, fetch it (when running standalone)
|
|
7
8
|
if (typeof globalThis.use === 'undefined') {
|
|
8
|
-
|
|
9
|
+
await ensureUseM();
|
|
9
10
|
}
|
|
10
11
|
const { $ } = await use('command-stream');
|
|
11
12
|
const fs = (await use('fs')).promises;
|
package/src/codex.lib.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
// Codex CLI-related utility functions
|
|
3
4
|
|
|
4
5
|
// Check if use is already defined (when imported from solve.mjs)
|
|
5
6
|
// If not, fetch it (when running standalone)
|
|
6
7
|
if (typeof globalThis.use === 'undefined') {
|
|
7
|
-
|
|
8
|
+
await ensureUseM();
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const { $ } = await use('command-stream');
|
package/src/config.lib.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Central configuration module for all configurable values
|
|
@@ -8,7 +9,7 @@
|
|
|
8
9
|
// Use use-m to dynamically import modules
|
|
9
10
|
if (typeof globalThis.use === 'undefined') {
|
|
10
11
|
try {
|
|
11
|
-
|
|
12
|
+
await ensureUseM();
|
|
12
13
|
} catch (error) {
|
|
13
14
|
console.error('❌ Fatal error: Failed to load dependencies for configuration');
|
|
14
15
|
console.error(` ${error.message}`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Contributing Guidelines Detection and Fetching
|
|
@@ -6,7 +7,7 @@
|
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
if (typeof globalThis.use === 'undefined') {
|
|
9
|
-
|
|
10
|
+
await ensureUseM();
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
const { $: __rawDollar$ } = await use('command-stream');
|
package/src/gemini.lib.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
// Google Gemini CLI-related utility functions
|
|
3
4
|
|
|
4
5
|
// Check if use is already defined (when imported from solve.mjs)
|
|
5
6
|
// If not, fetch it (when running standalone)
|
|
6
7
|
if (typeof globalThis.use === 'undefined') {
|
|
7
|
-
|
|
8
|
+
await ensureUseM();
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const { $ } = await use('command-stream');
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* GitHub entity existence validation for /solve command.
|
|
3
4
|
* Extracted from github.lib.mjs to keep files under 1500 line limit.
|
|
4
5
|
* @see https://github.com/link-assistant/hive-mind/issues/1552
|
|
5
6
|
*/
|
|
6
|
-
if (typeof globalThis.use === 'undefined')
|
|
7
|
+
if (typeof globalThis.use === 'undefined') await ensureUseM();
|
|
7
8
|
const { $ } = await use('command-stream');
|
|
8
9
|
import { ghCmdRetry } from './lib.mjs';
|
|
9
10
|
import { ghPrView, ghIssueView } from './github.lib.mjs';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* GitHub error reporter - handles error reporting via GitHub issues and comments
|
|
@@ -9,7 +10,7 @@ import { log, cleanErrorMessage, getAbsoluteLogPath } from './lib.mjs';
|
|
|
9
10
|
import { reportError, isSentryEnabled } from './sentry.lib.mjs';
|
|
10
11
|
|
|
11
12
|
if (typeof globalThis.use === 'undefined') {
|
|
12
|
-
|
|
13
|
+
await ensureUseM();
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const fs = (await use('fs')).promises;
|
package/src/github.batch.lib.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
// GitHub batch operations using GraphQL
|
|
3
4
|
|
|
4
5
|
// Check if use is already defined (when imported from solve.mjs)
|
|
5
6
|
// If not, fetch it (when running standalone)
|
|
6
7
|
if (typeof globalThis.use === 'undefined') {
|
|
7
|
-
|
|
8
|
+
await ensureUseM();
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
// Import dependencies
|
package/src/github.lib.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
2
3
|
// GitHub-related utility functions. Check if use is already defined (when imported from solve.mjs), if not, fetch it (when running standalone)
|
|
3
|
-
if (typeof globalThis.use === 'undefined')
|
|
4
|
+
if (typeof globalThis.use === 'undefined') await ensureUseM();
|
|
4
5
|
const { $ } = await use('command-stream'); // Use command-stream for consistent $ behavior
|
|
5
6
|
import { log, maskToken, cleanErrorMessage, isENOSPC, ghCmdRetry } from './lib.mjs';
|
|
6
7
|
import { reportError } from './sentry.lib.mjs';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* HANDOFF.md Agent Skill deployment (issue #1877)
|
|
3
4
|
*
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
|
|
30
31
|
// Fetch use-m if not available (matches the rest of src/*.lib.mjs).
|
|
31
32
|
if (typeof globalThis.use === 'undefined') {
|
|
32
|
-
|
|
33
|
+
await ensureUseM();
|
|
33
34
|
}
|
|
34
35
|
const fs = (await use('fs')).promises;
|
|
35
36
|
const path = (await use('path')).default;
|
package/src/hive.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Import Sentry instrumentation first (must be before other imports)
|
|
3
3
|
import './instrument.mjs';
|
|
4
|
+
import { ensureUseM } from './use-m-bootstrap.lib.mjs';
|
|
4
5
|
import { wrapDollarWithGhRetry as _wrapDollarWithGhRetry, execGhWithRetry } from './github-rate-limit.lib.mjs'; // rate-limit marker (#1726): gh API calls flow through $ wrapped by caller. execGhWithRetry adds transient-network retry (#1756).
|
|
5
6
|
const earlyArgs = process.argv.slice(2);
|
|
6
7
|
if (earlyArgs.includes('--version')) {
|
|
@@ -42,16 +43,17 @@ if (isRunningDirectly) {
|
|
|
42
43
|
console.log(' Initializing...');
|
|
43
44
|
try {
|
|
44
45
|
console.log(' Loading dependencies (this may take a moment)...');
|
|
45
|
-
|
|
46
|
-
if (typeof use === 'undefined') {
|
|
46
|
+
if (typeof globalThis.use === 'undefined') {
|
|
47
47
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
await ensureUseM({
|
|
49
|
+
fetchUseMCode: () =>
|
|
50
|
+
withTimeout(
|
|
51
|
+
fetch('https://unpkg.com/use-m/use.js').then(r => r.text()),
|
|
52
|
+
10000,
|
|
53
|
+
'fetching use-m library'
|
|
54
|
+
),
|
|
55
|
+
log: message => console.log(message),
|
|
56
|
+
});
|
|
55
57
|
} catch (error) {
|
|
56
58
|
console.error('❌ Fatal error: Failed to load dependencies');
|
|
57
59
|
console.error(` ${error.message}`);
|
|
@@ -60,7 +62,6 @@ if (isRunningDirectly) {
|
|
|
60
62
|
process.exit(1);
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
|
-
// Use command-stream for consistent $ behavior across runtimes
|
|
64
65
|
const { $ } = await withTimeout(
|
|
65
66
|
use('command-stream'),
|
|
66
67
|
30000, // 30 second timeout
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createCollapsible, createRawJsonSection, createRedactedRawJsonSection, escapeMarkdown, redactImageData, safeJsonStringify, truncateMiddle } from './interactive-mode.shared.lib.mjs';
|
|
4
|
+
import { INTERACTIVE_SESSION_STARTED_MARKER } from './tool-comments.lib.mjs';
|
|
5
|
+
|
|
6
|
+
export const createCodexEventHandlers = ({ state, postComment, handleAssistantText, imageRenderer }) => {
|
|
7
|
+
const handleCodexThreadStarted = async data => {
|
|
8
|
+
if (state.sessionId) return;
|
|
9
|
+
|
|
10
|
+
state.sessionId = data.thread_id || data.session_id || null;
|
|
11
|
+
state.startTime = Date.now();
|
|
12
|
+
|
|
13
|
+
const comment = `## 🚀 ${INTERACTIVE_SESSION_STARTED_MARKER}
|
|
14
|
+
|
|
15
|
+
| Property | Value |
|
|
16
|
+
|----------|-------|
|
|
17
|
+
| **Session ID** | \`${state.sessionId || 'unknown'}\` |
|
|
18
|
+
| **Model** | \`${data.model || 'unknown'}\` |
|
|
19
|
+
| **Tool** | \`codex\` |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
${createRawJsonSection(data)}`;
|
|
24
|
+
|
|
25
|
+
await postComment(comment);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const handleCodexAgentMessage = async data => {
|
|
29
|
+
const text = data.item?.text;
|
|
30
|
+
if (typeof text !== 'string' || !text.trim()) return;
|
|
31
|
+
await handleAssistantText(data, text);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const handleCodexTodoList = async data => {
|
|
35
|
+
const items = Array.isArray(data.item?.items) ? data.item.items : [];
|
|
36
|
+
const todosPreview = items.length > 0 ? items.map(todo => `- [${todo?.completed ? 'x' : ' '}] ${todo?.text || ''}`).join('\n') : '_No tasks_';
|
|
37
|
+
const completedCount = items.filter(todo => todo?.completed).length;
|
|
38
|
+
|
|
39
|
+
const comment = `## 📋 Codex todo list
|
|
40
|
+
|
|
41
|
+
${createCollapsible(`📋 Todos (${completedCount}/${items.length} items)`, todosPreview, true)}
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
${createRawJsonSection(data)}`;
|
|
46
|
+
|
|
47
|
+
await postComment(comment);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleCodexCommandExecution = async data => {
|
|
51
|
+
const item = data.item || {};
|
|
52
|
+
const command = item.command || '';
|
|
53
|
+
const output = item.aggregated_output || '';
|
|
54
|
+
const status = item.status || (data.type === 'item.completed' ? 'completed' : data.type === 'item.updated' ? 'updated' : 'started');
|
|
55
|
+
const body = `## 💻 Codex command execution
|
|
56
|
+
|
|
57
|
+
**Status:** \`${status}\`
|
|
58
|
+
${command ? '\n' + createCollapsible('📋 Executed command', '```bash\n' + escapeMarkdown(command) + '\n```', true) : ''}
|
|
59
|
+
${output ? '\n\n' + createCollapsible('📤 Output', '```\n' + escapeMarkdown(truncateMiddle(output, { maxLines: 60, keepStart: 25, keepEnd: 25 })) + '\n```', true) : ''}
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
${createRawJsonSection(data)}`;
|
|
64
|
+
await postComment(body);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleCodexMcpToolCall = async data => {
|
|
68
|
+
const item = data.item || {};
|
|
69
|
+
const summary = [`**Server:** \`${item.server || 'unknown'}\``, `**Tool:** \`${item.tool || 'unknown'}\``, `**Status:** \`${item.status || 'unknown'}\``].join('\n');
|
|
70
|
+
const details = item.arguments != null ? createCollapsible('📥 Arguments', '```json\n' + safeJsonStringify(item.arguments, 2) + '\n```', true) : '';
|
|
71
|
+
// Issue #1843: render MCP-result images inline; base64 is redacted from JSON below.
|
|
72
|
+
const imagesSection = await imageRenderer.section([item.result], `${item.tool || 'mcp'} image`);
|
|
73
|
+
const imagesBlock = imagesSection ? '\n\n' + imagesSection : '';
|
|
74
|
+
const resultSection = item.result != null ? '\n\n' + createCollapsible('📤 Result', '```json\n' + safeJsonStringify(redactImageData(item.result), 2) + '\n```', false) : '';
|
|
75
|
+
const errorSection = item.error != null ? '\n\n' + createCollapsible('❌ Error', '```json\n' + safeJsonStringify(item.error, 2) + '\n```', true) : '';
|
|
76
|
+
|
|
77
|
+
await postComment(`## 🔌 Codex MCP tool call
|
|
78
|
+
|
|
79
|
+
${summary}
|
|
80
|
+
${details}${resultSection}${imagesBlock}${errorSection}
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
${createRedactedRawJsonSection(data)}`);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleCodexWebSearch = async data => {
|
|
88
|
+
const item = data.item || {};
|
|
89
|
+
await postComment(`## 🌐 Codex web search
|
|
90
|
+
|
|
91
|
+
**Query:** ${escapeMarkdown(item.query || 'unknown')}
|
|
92
|
+
${item.action ? `\n**Action:** \`${item.action}\`` : ''}
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
${createRawJsonSection(data)}`);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const handleCodexFileChange = async data => {
|
|
100
|
+
const item = data.item || {};
|
|
101
|
+
const changes = Array.isArray(item.changes) ? item.changes.map(change => `- \`${change?.kind || 'change'}\` ${change?.path || ''}`).join('\n') : '_No changes listed_';
|
|
102
|
+
await postComment(`## 📝 Codex file changes
|
|
103
|
+
|
|
104
|
+
**Status:** \`${item.status || 'unknown'}\`
|
|
105
|
+
${createCollapsible('📄 Files', changes, true)}
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
${createRawJsonSection(data)}`);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const handleCodexCollabToolCall = async data => {
|
|
113
|
+
const item = data.item || {};
|
|
114
|
+
const prompt = item.prompt || item.description || `${item.tool || 'collab_tool_call'} via codex`;
|
|
115
|
+
await postComment(`## 🤝 Codex collab/sub-agent call
|
|
116
|
+
|
|
117
|
+
**Tool:** \`${item.tool || 'unknown'}\`
|
|
118
|
+
**Status:** \`${item.status || 'unknown'}\`
|
|
119
|
+
${createCollapsible('📝 Prompt', escapeMarkdown(truncateMiddle(prompt, { maxLines: 30, keepStart: 12, keepEnd: 12 })), true)}
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
${createRawJsonSection(data)}`);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const handleCodexTurnCompleted = async data => {
|
|
127
|
+
const usage = data.usage || {};
|
|
128
|
+
let usageSection = '| Type | Count |\n|------|-------|\n';
|
|
129
|
+
usageSection += `| Input | ${(usage.input_tokens || 0).toLocaleString()} |\n`;
|
|
130
|
+
usageSection += `| Cache Read | ${(usage.cached_input_tokens || 0).toLocaleString()} |\n`;
|
|
131
|
+
usageSection += `| Output | ${(usage.output_tokens || 0).toLocaleString()} |\n`;
|
|
132
|
+
|
|
133
|
+
await postComment(`## ✅ Codex turn completed
|
|
134
|
+
|
|
135
|
+
### 📊 Token Usage
|
|
136
|
+
|
|
137
|
+
${usageSection}
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
${createRawJsonSection(data)}`);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const handleCodexError = async data => {
|
|
145
|
+
const message = data.message || data.error?.message || 'Unknown Codex error';
|
|
146
|
+
await postComment(`## ❌ Codex error
|
|
147
|
+
|
|
148
|
+
${createCollapsible('View error', escapeMarkdown(message), true)}
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
${createRawJsonSection(data)}`);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
handleCodexThreadStarted,
|
|
157
|
+
handleCodexAgentMessage,
|
|
158
|
+
handleCodexTodoList,
|
|
159
|
+
handleCodexCommandExecution,
|
|
160
|
+
handleCodexMcpToolCall,
|
|
161
|
+
handleCodexWebSearch,
|
|
162
|
+
handleCodexFileChange,
|
|
163
|
+
handleCodexCollabToolCall,
|
|
164
|
+
handleCodexTurnCompleted,
|
|
165
|
+
handleCodexError,
|
|
166
|
+
};
|
|
167
|
+
};
|