oh-my-codex 0.11.12 → 0.11.13
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/Cargo.lock +5 -5
- package/Cargo.toml +1 -1
- package/README.md +23 -0
- package/README.vi.md +144 -185
- package/crates/omx-runtime-core/src/engine.rs +122 -4
- package/crates/omx-runtime-core/src/lib.rs +17 -0
- package/dist/cli/__tests__/autoresearch.test.js +11 -0
- package/dist/cli/__tests__/autoresearch.test.js.map +1 -1
- package/dist/cli/__tests__/cleanup.test.js +117 -4
- package/dist/cli/__tests__/cleanup.test.js.map +1 -1
- package/dist/cli/__tests__/error-handling-warnings.test.js +13 -0
- package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +6 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +94 -1
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +3 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +10 -0
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/packaged-script-resolution.test.js +4 -3
- package/dist/cli/__tests__/packaged-script-resolution.test.js.map +1 -1
- package/dist/cli/__tests__/resume.test.js +6 -0
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +29 -12
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/star-prompt.test.js +16 -0
- package/dist/cli/__tests__/star-prompt.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +112 -1
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +2 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +1 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +30 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -0
- package/dist/cli/cleanup.d.ts +2 -0
- package/dist/cli/cleanup.d.ts.map +1 -1
- package/dist/cli/cleanup.js +26 -1
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +161 -50
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +15 -14
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/star-prompt.d.ts.map +1 -1
- package/dist/cli/star-prompt.js +1 -0
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +5 -1
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +26 -0
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +1 -0
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +4 -4
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/mcp-registry.test.js +13 -16
- package/dist/config/__tests__/mcp-registry.test.js.map +1 -1
- package/dist/config/mcp-registry.d.ts +1 -0
- package/dist/config/mcp-registry.d.ts.map +1 -1
- package/dist/config/mcp-registry.js +4 -4
- package/dist/config/mcp-registry.js.map +1 -1
- package/dist/config/models.d.ts +1 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +39 -1
- package/dist/config/models.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +12 -1
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +499 -17
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +140 -14
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +5 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +597 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +15 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +73 -53
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +193 -2
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +183 -0
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +255 -97
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +46 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +1 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +48 -0
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1 -0
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +70 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +10 -37
- package/dist/hud/state.js.map +1 -1
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +5 -0
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +46 -0
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +4 -0
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +2 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.js +84 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +1 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js +55 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/notifications/idle-cooldown.d.ts +8 -6
- package/dist/notifications/idle-cooldown.d.ts.map +1 -1
- package/dist/notifications/idle-cooldown.js +53 -22
- package/dist/notifications/idle-cooldown.js.map +1 -1
- package/dist/notifications/notifier.js +1 -1
- package/dist/notifications/notifier.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +1 -0
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/openclaw/config.js +2 -2
- package/dist/openclaw/config.js.map +1 -1
- package/dist/runtime/bridge.d.ts +1 -0
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +2 -6
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +97 -59
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +72 -238
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts +19 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -0
- package/dist/scripts/notify-hook/managed-tmux.js +320 -0
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -0
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +22 -0
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js +277 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -0
- package/dist/scripts/notify-hook/state-io.d.ts +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +2 -10
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +60 -59
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts +2 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +13 -5
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +1 -19
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +4 -4
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +102 -35
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +144 -20
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts +1 -0
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +3 -0
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +96 -4
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/leader-activity.test.js +107 -2
- package/dist/team/__tests__/leader-activity.test.js.map +1 -1
- package/dist/team/__tests__/runtime-cli.test.js +32 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +148 -0
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/shutdown-fallback.test.js +13 -0
- package/dist/team/__tests__/shutdown-fallback.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +11 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +16 -5
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +460 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +34 -7
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/commit-hygiene.d.ts +60 -0
- package/dist/team/commit-hygiene.d.ts.map +1 -0
- package/dist/team/commit-hygiene.js +232 -0
- package/dist/team/commit-hygiene.js.map +1 -0
- package/dist/team/leader-activity.d.ts.map +1 -1
- package/dist/team/leader-activity.js +17 -35
- package/dist/team/leader-activity.js.map +1 -1
- package/dist/team/runtime-cli.d.ts +9 -1
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +15 -6
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts +7 -2
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +391 -63
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/state/dispatch.js +1 -1
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/state/mailbox.d.ts +1 -0
- package/dist/team/state/mailbox.d.ts.map +1 -1
- package/dist/team/state/mailbox.js +54 -8
- package/dist/team/state/mailbox.js.map +1 -1
- package/dist/team/state-root.d.ts +1 -1
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +8 -3
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +66 -3
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +69 -27
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/utils/__tests__/platform-command.test.js +101 -2
- package/dist/utils/__tests__/platform-command.test.js.map +1 -1
- package/dist/utils/git-layout.d.ts +8 -0
- package/dist/utils/git-layout.d.ts.map +1 -0
- package/dist/utils/git-layout.js +58 -0
- package/dist/utils/git-layout.js.map +1 -0
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +32 -1
- package/dist/utils/platform-command.js.map +1 -1
- package/package.json +6 -6
- package/src/scripts/notify-fallback-watcher.ts +96 -58
- package/src/scripts/notify-hook/auto-nudge.ts +75 -230
- package/src/scripts/notify-hook/managed-tmux.ts +324 -0
- package/src/scripts/notify-hook/ralph-session-resume.ts +337 -0
- package/src/scripts/notify-hook/state-io.ts +2 -10
- package/src/scripts/notify-hook/team-dispatch.ts +70 -54
- package/src/scripts/notify-hook/team-leader-nudge.ts +19 -5
- package/src/scripts/notify-hook/team-tmux-guard.ts +0 -20
- package/src/scripts/notify-hook/team-worker.ts +4 -4
- package/src/scripts/notify-hook/tmux-injection.ts +103 -33
- package/src/scripts/notify-hook.ts +150 -21
- package/src/scripts/tmux-hook-engine.ts +4 -0
|
@@ -39,6 +39,10 @@ import { isLeaderStale, resolveLeaderStalenessThresholdMs, maybeNudgeTeamLeader
|
|
|
39
39
|
import { drainPendingTeamDispatch } from './notify-hook/team-dispatch.js';
|
|
40
40
|
import { handleTmuxInjection } from './notify-hook/tmux-injection.js';
|
|
41
41
|
import { maybeAutoNudge, resolveNudgePaneTarget, isDeepInterviewStateActive } from './notify-hook/auto-nudge.js';
|
|
42
|
+
import { isManagedOmxSession } from './notify-hook/managed-tmux.js';
|
|
43
|
+
import { logNotifyHookEvent } from './notify-hook/log.js';
|
|
44
|
+
import { reconcileRalphSessionResume } from './notify-hook/ralph-session-resume.js';
|
|
45
|
+
import { sendPaneInput } from './notify-hook/team-tmux-guard.js';
|
|
42
46
|
import {
|
|
43
47
|
buildOperationalContext,
|
|
44
48
|
deriveAssistantSignalEvents,
|
|
@@ -68,6 +72,79 @@ const RALPH_ACTIVE_PROGRESS_PHASES = new Set([
|
|
|
68
72
|
'fixing',
|
|
69
73
|
]);
|
|
70
74
|
|
|
75
|
+
const IDLE_NOTIFICATION_SUMMARY_MAX_LENGTH = 240;
|
|
76
|
+
|
|
77
|
+
function summarizeIdleNotificationMessage(message: unknown): string {
|
|
78
|
+
const source = safeString(message)
|
|
79
|
+
.split('\n')
|
|
80
|
+
.map((line) => line.trim())
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
const preferred = source.at(-1) || '';
|
|
83
|
+
const normalized = preferred.replace(/\s+/g, ' ').trim();
|
|
84
|
+
if (!normalized) return '';
|
|
85
|
+
return normalized.length > IDLE_NOTIFICATION_SUMMARY_MAX_LENGTH
|
|
86
|
+
? `${normalized.slice(0, IDLE_NOTIFICATION_SUMMARY_MAX_LENGTH - 1)}…`
|
|
87
|
+
: normalized;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function classifyIdleNotificationPhase(message: unknown): 'idle' | 'progress' | 'finished' | 'failed' {
|
|
91
|
+
const lower = safeString(message).toLowerCase();
|
|
92
|
+
if (!lower) return 'idle';
|
|
93
|
+
|
|
94
|
+
if (/(error|failed|exception|invalid|timed out|timeout)/i.test(lower)) {
|
|
95
|
+
return 'failed';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if ([
|
|
99
|
+
'all tests pass',
|
|
100
|
+
'build succeeded',
|
|
101
|
+
'completed',
|
|
102
|
+
'complete',
|
|
103
|
+
'done',
|
|
104
|
+
'final summary',
|
|
105
|
+
'summary',
|
|
106
|
+
].some((pattern) => lower.includes(pattern))) {
|
|
107
|
+
return 'finished';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if ([
|
|
111
|
+
'verify',
|
|
112
|
+
'verified',
|
|
113
|
+
'verification',
|
|
114
|
+
'review',
|
|
115
|
+
'reviewed',
|
|
116
|
+
'diagnostic',
|
|
117
|
+
'typecheck',
|
|
118
|
+
'test',
|
|
119
|
+
'implement',
|
|
120
|
+
'implemented',
|
|
121
|
+
'apply patch',
|
|
122
|
+
'change',
|
|
123
|
+
'fix',
|
|
124
|
+
'update',
|
|
125
|
+
'refactor',
|
|
126
|
+
'resume',
|
|
127
|
+
'resumed',
|
|
128
|
+
'progress',
|
|
129
|
+
'continue',
|
|
130
|
+
'continued',
|
|
131
|
+
].some((pattern) => lower.includes(pattern))) {
|
|
132
|
+
return 'progress';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return 'idle';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function buildIdleNotificationFingerprint(payload: Record<string, unknown>): string {
|
|
139
|
+
const lastAssistantMessage = safeString(payload['last-assistant-message'] || payload.last_assistant_message || '');
|
|
140
|
+
const summary = summarizeIdleNotificationMessage(lastAssistantMessage);
|
|
141
|
+
const phase = classifyIdleNotificationPhase(lastAssistantMessage);
|
|
142
|
+
return JSON.stringify({
|
|
143
|
+
phase,
|
|
144
|
+
...(summary ? { summary } : {}),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
71
148
|
async function main() {
|
|
72
149
|
const rawPayload = process.argv[process.argv.length - 1];
|
|
73
150
|
if (!rawPayload || rawPayload.startsWith('-')) {
|
|
@@ -83,6 +160,9 @@ async function main() {
|
|
|
83
160
|
|
|
84
161
|
const cwd = payload.cwd || payload['cwd'] || process.cwd();
|
|
85
162
|
const payloadSessionId = safeString(payload.session_id || payload['session-id'] || '');
|
|
163
|
+
const payloadThreadId = safeString(payload['thread-id'] || payload.thread_id || '');
|
|
164
|
+
const inputMessages = normalizeInputMessages(payload);
|
|
165
|
+
const latestUserInput = safeString(inputMessages.length > 0 ? inputMessages[inputMessages.length - 1] : '');
|
|
86
166
|
|
|
87
167
|
// Team worker detection via environment variable
|
|
88
168
|
const teamWorkerEnv = process.env.OMX_TEAM_WORKER; // e.g., "fix-ts/worker-1"
|
|
@@ -94,6 +174,7 @@ async function main() {
|
|
|
94
174
|
: join(cwd, '.omx', 'state');
|
|
95
175
|
const logsDir = join(cwd, '.omx', 'logs');
|
|
96
176
|
const omxDir = join(cwd, '.omx');
|
|
177
|
+
let currentOmxSessionId = '';
|
|
97
178
|
|
|
98
179
|
// Ensure directories exist
|
|
99
180
|
await mkdir(logsDir, { recursive: true }).catch(() => {});
|
|
@@ -158,11 +239,45 @@ async function main() {
|
|
|
158
239
|
const logFile = join(logsDir, `turns-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
159
240
|
await appendFile(logFile, JSON.stringify(logEntry) + '\n').catch(() => {});
|
|
160
241
|
|
|
242
|
+
// Reconcile Ralph ownership for same-Codex-session continuation before
|
|
243
|
+
// lifecycle counters or injection read the active scope.
|
|
244
|
+
if (!isTeamWorker) {
|
|
245
|
+
try {
|
|
246
|
+
const resumeResult = await reconcileRalphSessionResume({
|
|
247
|
+
stateDir,
|
|
248
|
+
payloadSessionId,
|
|
249
|
+
payloadThreadId,
|
|
250
|
+
});
|
|
251
|
+
currentOmxSessionId = resumeResult.currentOmxSessionId;
|
|
252
|
+
if (resumeResult.resumed || resumeResult.updatedCurrentOwner) {
|
|
253
|
+
await logNotifyHookEvent(logsDir, {
|
|
254
|
+
timestamp: new Date().toISOString(),
|
|
255
|
+
type: 'ralph_session_resume',
|
|
256
|
+
reason: resumeResult.reason,
|
|
257
|
+
current_omx_session_id: resumeResult.currentOmxSessionId || null,
|
|
258
|
+
payload_codex_session_id: payloadSessionId || null,
|
|
259
|
+
source_path: resumeResult.sourcePath || null,
|
|
260
|
+
target_path: resumeResult.targetPath || null,
|
|
261
|
+
owner_updated: resumeResult.updatedCurrentOwner,
|
|
262
|
+
resumed: resumeResult.resumed,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
} catch (error) {
|
|
266
|
+
await logNotifyHookEvent(logsDir, {
|
|
267
|
+
timestamp: new Date().toISOString(),
|
|
268
|
+
level: 'warn',
|
|
269
|
+
type: 'ralph_session_resume_failure',
|
|
270
|
+
payload_codex_session_id: payloadSessionId || null,
|
|
271
|
+
error: error instanceof Error ? error.message : String(error),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
161
276
|
// 2. Update active mode state (increment iteration)
|
|
162
277
|
// GUARD: Skip when running inside a team worker to prevent state corruption
|
|
163
278
|
if (!isTeamWorker) {
|
|
164
279
|
try {
|
|
165
|
-
const scopedDirs = await getScopedStateDirsForCurrentSession(stateDir
|
|
280
|
+
const scopedDirs = await getScopedStateDirsForCurrentSession(stateDir);
|
|
166
281
|
for (const scopedDir of scopedDirs) {
|
|
167
282
|
const stateFiles = await readdir(scopedDir).catch(() => []);
|
|
168
283
|
for (const f of stateFiles) {
|
|
@@ -298,7 +413,9 @@ async function main() {
|
|
|
298
413
|
if (existsSync(hudStatePath)) {
|
|
299
414
|
hudState = JSON.parse(await readFile(hudStatePath, 'utf-8'));
|
|
300
415
|
}
|
|
301
|
-
|
|
416
|
+
const nowIso = new Date().toISOString();
|
|
417
|
+
hudState.last_turn_at = nowIso;
|
|
418
|
+
(hudState as any).last_progress_at = nowIso;
|
|
302
419
|
hudState.turn_count = (hudState.turn_count || 0) + 1;
|
|
303
420
|
(hudState as any).last_agent_output = (payload['last-assistant-message'] || payload.last_assistant_message || '')
|
|
304
421
|
.slice(0, 100);
|
|
@@ -323,14 +440,12 @@ async function main() {
|
|
|
323
440
|
// 4.45. Skill activation tracking: update skill-active-state.json before any nudge logic.
|
|
324
441
|
try {
|
|
325
442
|
const { recordSkillActivation } = await import('../hooks/keyword-detector.js');
|
|
326
|
-
const inputMessages = normalizeInputMessages(payload);
|
|
327
|
-
const latestUserInput = safeString(inputMessages.length > 0 ? inputMessages[inputMessages.length - 1] : '');
|
|
328
443
|
if (latestUserInput) {
|
|
329
444
|
await recordSkillActivation({
|
|
330
445
|
stateDir,
|
|
331
446
|
text: latestUserInput,
|
|
332
447
|
sessionId: payloadSessionId,
|
|
333
|
-
threadId:
|
|
448
|
+
threadId: payloadThreadId,
|
|
334
449
|
turnId: safeString(payload['turn-id'] || payload.turn_id || ''),
|
|
335
450
|
});
|
|
336
451
|
}
|
|
@@ -443,19 +558,20 @@ async function main() {
|
|
|
443
558
|
const { notifyLifecycle } = await import('../notifications/index.js');
|
|
444
559
|
const { shouldSendIdleNotification, recordIdleNotificationSent } = await import('../notifications/idle-cooldown.js');
|
|
445
560
|
const sessionJsonPath = join(stateDir, 'session.json');
|
|
561
|
+
const idleFingerprint = buildIdleNotificationFingerprint(payload);
|
|
446
562
|
let notifySessionId = '';
|
|
447
563
|
try {
|
|
448
564
|
const sessionData = JSON.parse(await readFile(sessionJsonPath, 'utf-8'));
|
|
449
565
|
notifySessionId = safeString(sessionData && sessionData.session_id ? sessionData.session_id : '');
|
|
450
566
|
} catch { /* no session file */ }
|
|
451
567
|
|
|
452
|
-
if (notifySessionId && shouldSendIdleNotification(stateDir, notifySessionId)) {
|
|
568
|
+
if (notifySessionId && shouldSendIdleNotification(stateDir, notifySessionId, idleFingerprint)) {
|
|
453
569
|
const idleResult = await notifyLifecycle('session-idle', {
|
|
454
570
|
sessionId: notifySessionId,
|
|
455
571
|
projectPath: cwd,
|
|
456
572
|
});
|
|
457
573
|
if (idleResult && idleResult.anySuccess) {
|
|
458
|
-
recordIdleNotificationSent(stateDir, notifySessionId);
|
|
574
|
+
recordIdleNotificationSent(stateDir, notifySessionId, idleFingerprint);
|
|
459
575
|
}
|
|
460
576
|
try {
|
|
461
577
|
const { buildNativeHookEvent } = await import('../hooks/extensibility/events.js');
|
|
@@ -506,7 +622,7 @@ async function main() {
|
|
|
506
622
|
payload,
|
|
507
623
|
stateDir,
|
|
508
624
|
logsDir,
|
|
509
|
-
sessionId: payloadSessionId,
|
|
625
|
+
sessionId: currentOmxSessionId || payloadSessionId,
|
|
510
626
|
turnId: safeString(payload['turn-id'] || payload.turn_id || ''),
|
|
511
627
|
});
|
|
512
628
|
} catch (err) {
|
|
@@ -531,23 +647,36 @@ async function main() {
|
|
|
531
647
|
const { processCodeSimplifier } = await import('../hooks/code-simplifier/index.js');
|
|
532
648
|
const csResult = processCodeSimplifier(cwd, stateDir);
|
|
533
649
|
if (csResult.triggered) {
|
|
534
|
-
const
|
|
535
|
-
if (
|
|
536
|
-
const csText = `${csResult.message} ${DEFAULT_MARKER}`;
|
|
537
|
-
const { runProcess } = await import('./notify-hook/process-runner.js');
|
|
538
|
-
await runProcess('tmux', ['send-keys', '-t', csPaneId, '-l', csText], 3000);
|
|
539
|
-
await new Promise(r => setTimeout(r, 100));
|
|
540
|
-
await runProcess('tmux', ['send-keys', '-t', csPaneId, 'C-m'], 3000);
|
|
541
|
-
await new Promise(r => setTimeout(r, 100));
|
|
542
|
-
await runProcess('tmux', ['send-keys', '-t', csPaneId, 'C-m'], 3000);
|
|
543
|
-
|
|
650
|
+
const managedSession = await isManagedOmxSession(cwd, payload, { allowTeamWorker: false });
|
|
651
|
+
if (!managedSession) {
|
|
544
652
|
const { logTmuxHookEvent } = await import('./notify-hook/log.js');
|
|
545
653
|
await logTmuxHookEvent(logsDir, {
|
|
546
654
|
timestamp: new Date().toISOString(),
|
|
547
|
-
type: '
|
|
548
|
-
|
|
549
|
-
file_count: csResult.message.split('\n').filter(l => l.trimStart().startsWith('- ')).length,
|
|
655
|
+
type: 'code_simplifier_skipped',
|
|
656
|
+
reason: 'unmanaged_session',
|
|
550
657
|
});
|
|
658
|
+
} else {
|
|
659
|
+
const csPaneId = await resolveNudgePaneTarget(stateDir, cwd, payload);
|
|
660
|
+
if (csPaneId) {
|
|
661
|
+
const csText = `${csResult.message} ${DEFAULT_MARKER}`;
|
|
662
|
+
const sendResult = await sendPaneInput({
|
|
663
|
+
paneTarget: csPaneId,
|
|
664
|
+
prompt: csText,
|
|
665
|
+
submitKeyPresses: 2,
|
|
666
|
+
submitDelayMs: 100,
|
|
667
|
+
});
|
|
668
|
+
if (!sendResult.ok) {
|
|
669
|
+
throw new Error(sendResult.error || sendResult.reason || 'send_failed');
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const { logTmuxHookEvent } = await import('./notify-hook/log.js');
|
|
673
|
+
await logTmuxHookEvent(logsDir, {
|
|
674
|
+
timestamp: new Date().toISOString(),
|
|
675
|
+
type: 'code_simplifier_triggered',
|
|
676
|
+
pane_id: csPaneId,
|
|
677
|
+
file_count: csResult.message.split('\n').filter(l => l.trimStart().startsWith('- ')).length,
|
|
678
|
+
});
|
|
679
|
+
}
|
|
551
680
|
}
|
|
552
681
|
}
|
|
553
682
|
} catch {
|
|
@@ -80,6 +80,10 @@ export function normalizeTmuxHookConfig(raw: any): any {
|
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
export function tmuxHookExplicitlyDisablesInjection(raw: any): boolean {
|
|
84
|
+
return Boolean(raw && typeof raw === 'object' && raw.enabled === false);
|
|
85
|
+
}
|
|
86
|
+
|
|
83
87
|
export function pickActiveMode(activeModes: any, allowedModes: any): string | null {
|
|
84
88
|
const activeSet = new Set((activeModes || []).filter((mode: any) => typeof mode === 'string'));
|
|
85
89
|
for (const mode of allowedModes || []) {
|