@quantiya/codevibe-codex-plugin 2.0.9 → 2.0.11
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/README.md +24 -3
- package/dist/server.js +32 -31
- package/hooks/common.sh +10 -13
- package/libexec/companion-launcher +21 -17
- package/libexec/pane-mirror-writer.js +127 -0
- package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-flag-locator.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/dispose-watcher-socket.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/appsync/appsync-client.d.ts +62 -0
- package/node_modules/@quantiya/codevibe-core/dist/auth/__tests__/keychain-cli-nudge.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/auth/keychain-cli.d.ts +8 -0
- package/node_modules/@quantiya/codevibe-core/dist/index.js +523 -351
- package/node_modules/@quantiya/codevibe-core/dist/keychain/__tests__/migrate-nudge.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/keychain/keychain-migrate.d.ts +17 -0
- package/node_modules/@quantiya/codevibe-core/dist/keychain/migrate-nudge.d.ts +38 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/protocol-backlog-wiring.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/protocol-backlog.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/workspace-cleanup-audit.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/anchored-fs.d.ts +7 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/bounded-directory.d.ts +14 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/process-identity.d.ts +30 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/process-tree.d.ts +1 -1
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/protocol-backlog.d.ts +62 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/workspace-cleanup-audit.d.ts +3 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/workspace-materializer.d.ts +23 -2
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/workspace-shadow.d.ts +2 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/direct-file-delete.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/flag-command.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/halt-message-wire-content.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/audit-browser.d.ts +54 -1
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.d.ts +10 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +2711 -1474
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/context-items.d.ts +3 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/direct-file-delete.d.ts +22 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/flag-command.d.ts +81 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/gate-prompts.d.ts +41 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/index.d.ts +31 -6
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/quorum-loop.d.ts +42 -1
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-progress.d.ts +3 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/types.d.ts +58 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/workspace-shutdown.d.ts +20 -0
- package/node_modules/@quantiya/codevibe-core/dist/reviewer/providers/codex.d.ts +5 -3
- package/node_modules/@quantiya/codevibe-core/dist/reviewer/token-usage.d.ts +41 -12
- package/node_modules/@quantiya/codevibe-core/dist/reviewer/types.d.ts +3 -0
- package/node_modules/@quantiya/codevibe-core/dist/substrate/__tests__/command-runner.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/substrate/types.d.ts +8 -0
- package/node_modules/@quantiya/codevibe-core/dist/track-presentation.d.ts +2 -0
- package/node_modules/@quantiya/codevibe-core/dist/track-presentation.test.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/package.json +1 -1
- package/node_modules/fs-ext/build/Makefile +2 -2
- package/node_modules/fs-ext/build/Release/fs_ext.node +0 -0
- package/node_modules/fs-ext/build/Release/obj.target/fs_ext/fs-ext.o +0 -0
- package/node_modules/fs-ext/build/config.gypi +1 -1
- package/package.json +2 -2
package/hooks/common.sh
CHANGED
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
# ─── Reviewer-subprocess short-circuit ───────────────────────────────
|
|
7
7
|
#
|
|
8
|
-
# When $QUORUM_REVIEWER_SUBPROCESS is set, the current `codex`
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# primary Codex session state.
|
|
8
|
+
# When $QUORUM_REVIEWER_SUBPROCESS is set, the current `codex` invocation is an
|
|
9
|
+
# internal CodeVibe subprocess and MUST NOT interact with the user's primary
|
|
10
|
+
# Codex session state. This isolation marker is dominant: an inherited
|
|
11
|
+
# $CODEVIBE_CODEX_PRIMARY_COMPANION value must never bypass it. The private
|
|
12
|
+
# launcher removes QUORUM only at the exact primary Codex handoff; reviewers and
|
|
13
|
+
# implementors add/inherit QUORUM again and therefore always stop here.
|
|
15
14
|
#
|
|
16
15
|
# Without this guard, every reviewer spawn would fire SessionStart →
|
|
17
16
|
# the plugin's resume/create logic creates a ghost backend session →
|
|
@@ -23,16 +22,14 @@
|
|
|
23
22
|
# prevents the same bug class for Codex.
|
|
24
23
|
#
|
|
25
24
|
# `common.sh` is sourced by every hook script (session-start.sh,
|
|
26
|
-
# user-prompt.sh, pre-tool-use.sh, post-tool-use.sh, stop.sh), so
|
|
27
|
-
#
|
|
28
|
-
# clean hook success and continues normally. Zero-impact for normal
|
|
29
|
-
# user sessions (the env var is never set in the 1.0 code path).
|
|
25
|
+
# user-prompt.sh, pre-tool-use.sh, post-tool-use.sh, stop.sh), so `exit 0` here
|
|
26
|
+
# propagates to the hook script and Codex sees a clean hook success.
|
|
30
27
|
#
|
|
31
28
|
# This change belongs on 1.0 main because it protects the 1.0
|
|
32
29
|
# primary-session-isolation invariant. The env var name is the same
|
|
33
30
|
# `QUORUM_*` scope used by the Claude and Gemini plugins' matching
|
|
34
31
|
# guards.
|
|
35
|
-
if [ -n "$QUORUM_REVIEWER_SUBPROCESS" ]; then
|
|
32
|
+
if [ -n "${QUORUM_REVIEWER_SUBPROCESS:-}" ]; then
|
|
36
33
|
exit 0
|
|
37
34
|
fi
|
|
38
35
|
|
|
@@ -56,7 +53,7 @@ fi
|
|
|
56
53
|
#
|
|
57
54
|
# The right behavior for an unsupported environment is a silent no-op.
|
|
58
55
|
# `exit 0` propagates a clean hook success to Codex.
|
|
59
|
-
if [ -z "$CODEVIBE_CODEX_TMUX_SESSION" ]; then
|
|
56
|
+
if [ -z "${CODEVIBE_CODEX_TMUX_SESSION:-}" ]; then
|
|
60
57
|
exit 0
|
|
61
58
|
fi
|
|
62
59
|
|
|
@@ -139,7 +139,7 @@ case "${1:-}" in
|
|
|
139
139
|
echo "Install Codex CLI with: npm install -g @openai/codex" >&2
|
|
140
140
|
exit 127
|
|
141
141
|
fi
|
|
142
|
-
exec codex "$@"
|
|
142
|
+
exec env -u QUORUM_REVIEWER_SUBPROCESS codex "$@"
|
|
143
143
|
;;
|
|
144
144
|
esac
|
|
145
145
|
|
|
@@ -379,7 +379,7 @@ if [ -n "$TMUX" ]; then
|
|
|
379
379
|
# leaves _CV_RC at its 0 default. printf's `|| true` keeps a
|
|
380
380
|
# disk-full failure from clobbering diagnostics.
|
|
381
381
|
_CV_RC=0
|
|
382
|
-
codex "$@" || _CV_RC=$?
|
|
382
|
+
env -u QUORUM_REVIEWER_SUBPROCESS codex "$@" || _CV_RC=$?
|
|
383
383
|
printf '%s' "$_CV_RC" > "$_CV_CODEX_EXIT_FILE" 2>/dev/null || true
|
|
384
384
|
exit "$_CV_RC"
|
|
385
385
|
fi
|
|
@@ -390,7 +390,7 @@ if [ ! -t 0 ] || [ ! -t 1 ]; then
|
|
|
390
390
|
_CV_AGENT_INVOKED="true"
|
|
391
391
|
_CV_AGENT_STARTED_AT="$(date +%s)"
|
|
392
392
|
_CV_RC=0
|
|
393
|
-
codex "$@" || _CV_RC=$?
|
|
393
|
+
env -u QUORUM_REVIEWER_SUBPROCESS codex "$@" || _CV_RC=$?
|
|
394
394
|
printf '%s' "$_CV_RC" > "$_CV_CODEX_EXIT_FILE" 2>/dev/null || true
|
|
395
395
|
exit "$_CV_RC"
|
|
396
396
|
fi
|
|
@@ -399,6 +399,7 @@ fi
|
|
|
399
399
|
log "Starting session log watcher server..."
|
|
400
400
|
export CODEX_WORKING_DIRECTORY="$WORKING_DIR"
|
|
401
401
|
export CODEVIBE_CODEX_TMUX_SESSION="$SESSION_NAME"
|
|
402
|
+
export CODEVIBE_CODEX_PRIMARY_COMPANION=1
|
|
402
403
|
export CODEVIBE_CODEX_PLUGIN_DIR="$PLUGIN_DIR"
|
|
403
404
|
|
|
404
405
|
# Install hooks.json for Codex CLI with absolute paths (idempotent)
|
|
@@ -523,11 +524,12 @@ _CV_HOOKS_REASON=""
|
|
|
523
524
|
#
|
|
524
525
|
# Design notes:
|
|
525
526
|
#
|
|
526
|
-
# - "already installed" detection: a structured
|
|
527
|
-
#
|
|
528
|
-
#
|
|
529
|
-
#
|
|
530
|
-
#
|
|
527
|
+
# - "already installed" detection: a structured comparison of the exact
|
|
528
|
+
# current hook commands at every expected event key. An older install path
|
|
529
|
+
# is owned but stale, so it is replaced instead of silently pinning hooks to
|
|
530
|
+
# a prior checkout/package version. This also replaces the former
|
|
531
|
+
# `grep -q "codevibe-codex"` substring test, which false-positived on
|
|
532
|
+
# unrelated user paths containing that string.
|
|
531
533
|
#
|
|
532
534
|
# - Merge dedupe: filters our previously-installed entries out of
|
|
533
535
|
# each event key's array, then appends the fresh template entries.
|
|
@@ -586,12 +588,13 @@ if INSTALLER_OUTPUT=$(CV_EXISTING="$CODEX_HOOKS_FILE" \
|
|
|
586
588
|
if (filtered.length === 0) return null;
|
|
587
589
|
return { ...entry, hooks: filtered };
|
|
588
590
|
};
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
591
|
+
const ownedCommands = (entries) => entries
|
|
592
|
+
.flatMap((entry) => entry && typeof entry === "object" && Array.isArray(entry.hooks)
|
|
593
|
+
? entry.hooks
|
|
594
|
+
: [])
|
|
595
|
+
.map((hook) => hook && hook.command)
|
|
596
|
+
.filter(isOurCommand)
|
|
597
|
+
.sort();
|
|
595
598
|
|
|
596
599
|
let existingObj = null;
|
|
597
600
|
let existed = false;
|
|
@@ -618,8 +621,9 @@ if INSTALLER_OUTPUT=$(CV_EXISTING="$CODEX_HOOKS_FILE" \
|
|
|
618
621
|
nextObj.hooks && typeof nextObj.hooks === "object") ? nextObj.hooks : {};
|
|
619
622
|
let allPresent = existed;
|
|
620
623
|
for (const k of Object.keys(nextHooks)) {
|
|
621
|
-
const
|
|
622
|
-
|
|
624
|
+
const existingArr = Array.isArray(existingHooks[k]) ? existingHooks[k] : [];
|
|
625
|
+
const nextArr = Array.isArray(nextHooks[k]) ? nextHooks[k] : [];
|
|
626
|
+
if (JSON.stringify(ownedCommands(existingArr)) !== JSON.stringify(ownedCommands(nextArr))) {
|
|
623
627
|
allPresent = false;
|
|
624
628
|
break;
|
|
625
629
|
}
|
|
@@ -752,7 +756,7 @@ done
|
|
|
752
756
|
# wrapper's cleanup trap can report it via `wrapper_exited` telemetry —
|
|
753
757
|
# tmux's own attach exit code is independent of the inner process exit.
|
|
754
758
|
tmux new-session -d -s "$SESSION_NAME" -x "$(tput cols)" -y "$(tput lines)" \
|
|
755
|
-
"export CODEVIBE_CODEX_TMUX_SESSION='$SESSION_NAME'; export ENVIRONMENT='$ENVIRONMENT'; $CODEX_CMD; printf '%s' \"\$?\" > '$_CV_CODEX_EXIT_FILE'; exit"
|
|
759
|
+
"unset QUORUM_REVIEWER_SUBPROCESS; export CODEVIBE_CODEX_TMUX_SESSION='$SESSION_NAME'; export CODEVIBE_CODEX_PRIMARY_COMPANION=1; export ENVIRONMENT='$ENVIRONMENT'; $CODEX_CMD; printf '%s' \"\$?\" > '$_CV_CODEX_EXIT_FILE'; exit"
|
|
756
760
|
_CV_TMUX_STARTED="true"
|
|
757
761
|
_CV_AGENT_INVOKED="true"
|
|
758
762
|
_CV_AGENT_STARTED_AT="$(date +%s)"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// tmux pipe-pane must execute a command string in the tmux server. Keep the
|
|
5
|
+
// file-open security and hard byte bound in this tiny helper, independently of
|
|
6
|
+
// the observer's tmux control path. The observer owns both files and passes
|
|
7
|
+
// their expected identities; this process refuses path substitution, reports
|
|
8
|
+
// ready/done through the verified state descriptor, and never grows pane.log
|
|
9
|
+
// past maxBytes even if `tmux pipe-pane -t` later fails.
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
|
|
12
|
+
const [
|
|
13
|
+
, ,
|
|
14
|
+
filePath,
|
|
15
|
+
expectedDevText,
|
|
16
|
+
expectedInoText,
|
|
17
|
+
statePath,
|
|
18
|
+
expectedStateDevText,
|
|
19
|
+
expectedStateInoText,
|
|
20
|
+
token,
|
|
21
|
+
maxBytesText,
|
|
22
|
+
] = process.argv;
|
|
23
|
+
const expectedDev = Number(expectedDevText);
|
|
24
|
+
const expectedIno = Number(expectedInoText);
|
|
25
|
+
const expectedStateDev = Number(expectedStateDevText);
|
|
26
|
+
const expectedStateIno = Number(expectedStateInoText);
|
|
27
|
+
const maxBytes = Number(maxBytesText);
|
|
28
|
+
|
|
29
|
+
if (
|
|
30
|
+
!filePath
|
|
31
|
+
|| !statePath
|
|
32
|
+
|| !/^[a-f0-9]{32}$/.test(token || '')
|
|
33
|
+
|| !Number.isSafeInteger(expectedDev)
|
|
34
|
+
|| !Number.isSafeInteger(expectedIno)
|
|
35
|
+
|| !Number.isSafeInteger(expectedStateDev)
|
|
36
|
+
|| !Number.isSafeInteger(expectedStateIno)
|
|
37
|
+
|| !Number.isSafeInteger(maxBytes)
|
|
38
|
+
|| maxBytes <= 0
|
|
39
|
+
) {
|
|
40
|
+
process.exit(64);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const openVerified = (target, flags, expectedDevice, expectedInode) => {
|
|
44
|
+
const fd = fs.openSync(target, flags | (fs.constants.O_NOFOLLOW || 0));
|
|
45
|
+
const stat = fs.fstatSync(fd);
|
|
46
|
+
if (!stat.isFile() || stat.dev !== expectedDevice || stat.ino !== expectedInode) {
|
|
47
|
+
fs.closeSync(fd);
|
|
48
|
+
throw new Error('identity mismatch');
|
|
49
|
+
}
|
|
50
|
+
return fd;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
let paneFd;
|
|
54
|
+
let stateFd;
|
|
55
|
+
try {
|
|
56
|
+
paneFd = openVerified(
|
|
57
|
+
filePath,
|
|
58
|
+
fs.constants.O_WRONLY | fs.constants.O_APPEND,
|
|
59
|
+
expectedDev,
|
|
60
|
+
expectedIno,
|
|
61
|
+
);
|
|
62
|
+
stateFd = openVerified(
|
|
63
|
+
statePath,
|
|
64
|
+
fs.constants.O_WRONLY,
|
|
65
|
+
expectedStateDev,
|
|
66
|
+
expectedStateIno,
|
|
67
|
+
);
|
|
68
|
+
} catch {
|
|
69
|
+
if (paneFd !== undefined) try { fs.closeSync(paneFd); } catch { /* ignore */ }
|
|
70
|
+
if (stateFd !== undefined) try { fs.closeSync(stateFd); } catch { /* ignore */ }
|
|
71
|
+
process.exit(66);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const writeState = (state, code = '') => {
|
|
75
|
+
const value = Buffer.from(`${state} ${token} ${process.pid}${code === '' ? '' : ` ${code}`}\n`, 'utf8');
|
|
76
|
+
fs.ftruncateSync(stateFd, 0);
|
|
77
|
+
let written = 0;
|
|
78
|
+
while (written < value.length) {
|
|
79
|
+
const count = fs.writeSync(stateFd, value, written, value.length - written, written);
|
|
80
|
+
if (count <= 0) throw new Error('short writer-state write');
|
|
81
|
+
written += count;
|
|
82
|
+
}
|
|
83
|
+
fs.fsyncSync(stateFd);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
let finished = false;
|
|
87
|
+
const finish = (code) => {
|
|
88
|
+
if (finished) return;
|
|
89
|
+
finished = true;
|
|
90
|
+
process.stdin.pause();
|
|
91
|
+
try { fs.closeSync(paneFd); } catch { /* ignore */ }
|
|
92
|
+
try { writeState('done', code); } catch { /* observer will retain the bounded mirror */ }
|
|
93
|
+
try { fs.closeSync(stateFd); } catch { /* ignore */ }
|
|
94
|
+
process.exit(code);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
writeState('ready');
|
|
99
|
+
if (fs.fstatSync(paneFd).size >= maxBytes) finish(0);
|
|
100
|
+
} catch {
|
|
101
|
+
finish(67);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
process.stdin.on('data', (chunk) => {
|
|
105
|
+
if (finished) return;
|
|
106
|
+
try {
|
|
107
|
+
const size = fs.fstatSync(paneFd).size;
|
|
108
|
+
const remaining = Math.max(0, maxBytes - size);
|
|
109
|
+
const input = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
110
|
+
const length = Math.min(remaining, input.length);
|
|
111
|
+
let written = 0;
|
|
112
|
+
while (written < length) {
|
|
113
|
+
const count = fs.writeSync(paneFd, input, written, length - written);
|
|
114
|
+
if (count <= 0) throw new Error('short pane-mirror write');
|
|
115
|
+
written += count;
|
|
116
|
+
}
|
|
117
|
+
if (length < input.length || size + written >= maxBytes) finish(0);
|
|
118
|
+
} catch {
|
|
119
|
+
finish(67);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
process.stdin.on('end', () => finish(0));
|
|
123
|
+
process.stdin.on('close', () => finish(0));
|
|
124
|
+
process.stdin.on('error', () => finish(68));
|
|
125
|
+
process.on('SIGHUP', () => finish(0));
|
|
126
|
+
process.on('SIGINT', () => finish(0));
|
|
127
|
+
process.on('SIGTERM', () => finish(0));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/dispose-watcher-socket.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
1
2
|
import { CreateEventInput, CreateSessionInput, UpdateSessionInput, UpdateEventStatusInput, Event, Session, EventSource, DeviceKey, GrantSessionKeyInput, UpdateReviewerPolicyInput, UserReviewerPolicySnapshot } from '../types';
|
|
2
3
|
import type { PostDecisionAction } from '../orchestration-shell/types';
|
|
4
|
+
import type { InvocationUsageSnapshot } from '../reviewer/token-usage';
|
|
3
5
|
import type { CreateTaskGroupInput, CreateTaskGroupResult, SubmitMergeGateVerdictInput, SubmitMergeGateVerdictResult, SubmitTrackVerificationOutcomeInput, SubmitTrackVerificationOutcomeResult, ClaimGroupDecisionInput, ClaimGroupDecisionResult } from '../local-executor/task-group-types';
|
|
4
6
|
import type { ReviewerVerdict, ReviewerRole, AgentKind as ReviewerAgentKind } from '../reviewer/types';
|
|
5
7
|
import type { PlannerDecision } from '../planner/types';
|
|
8
|
+
/**
|
|
9
|
+
* Dispose a watcher/subscription WebSocket without crashing the process
|
|
10
|
+
* (#657 D-1 fix-forward — the clean-quit session/admission leak).
|
|
11
|
+
*
|
|
12
|
+
* `ws.close()` on a still-CONNECTING socket aborts the handshake and emits an
|
|
13
|
+
* ASYNC 'error' ("WebSocket was closed before the connection was established")
|
|
14
|
+
* on a LATER tick. Every prior disposal site paired `close(1000)` with
|
|
15
|
+
* `removeAllListeners()` — in either order — so that late emission always
|
|
16
|
+
* found a listener-less socket and crashed Node with an unhandled 'error'
|
|
17
|
+
* mid-teardown, BEFORE `retireHostedSession` could land the session INACTIVE
|
|
18
|
+
* mutation. Net effect: every clean `/quit` whose Class B watcher (or any
|
|
19
|
+
* other watcher) was mid-(re)connect leaked an ACTIVE session row AND an
|
|
20
|
+
* `activeSessionAdmissionCount` slot (#101 class), hard-capping the
|
|
21
|
+
* 19-scenario GA baseline after exactly the free headroom.
|
|
22
|
+
*
|
|
23
|
+
* Order is load-bearing: strip stale handlers FIRST, re-arm a swallow-all
|
|
24
|
+
* 'error' handler, THEN close. Exported for the regression test only — not
|
|
25
|
+
* part of the public SDK surface.
|
|
26
|
+
*/
|
|
27
|
+
export declare function disposeWatcherSocket(ws: WebSocket, subscriptionId?: string): void;
|
|
6
28
|
/**
|
|
7
29
|
* One assigned reviewer seat returned by `getInReviewAssignments`. Mirrors the
|
|
8
30
|
* engine `InReviewAssignment` serde (camelCase) in
|
|
@@ -101,6 +123,24 @@ export interface RecordExecutionEventInput {
|
|
|
101
123
|
/** Free-form JSON; encrypted before crossing AppSync. */
|
|
102
124
|
payload: unknown;
|
|
103
125
|
dedupKeyHex: string;
|
|
126
|
+
/**
|
|
127
|
+
* O1 C1 (#652) §3.1 item 3 — the plaintext flag-target locator, REQUIRED
|
|
128
|
+
* when `kind = 'FLAG_BAD_APPROVAL'` and absent otherwise (non-flag events
|
|
129
|
+
* stay byte-identical to the pre-O1-C1 wire). Row COORDINATES only — zero
|
|
130
|
+
* content. Field names mirror the Rust handler DTO
|
|
131
|
+
* (`RecordExecutionEventInput` in core-rs `types.rs`, camelCase serde) —
|
|
132
|
+
* the wire-shape source of truth. The server rejects a request whose
|
|
133
|
+
* `taskId` ≠ `flaggedTaskId` (the per-task dedup-partition pin).
|
|
134
|
+
*/
|
|
135
|
+
flaggedTaskId?: string;
|
|
136
|
+
/**
|
|
137
|
+
* The flagged row's audit-table sort key — the zero-padded 16-digit
|
|
138
|
+
* `seqNum` string exactly as surfaced by `queryAudit`'s additive
|
|
139
|
+
* `AuditEntryWireRow.seqNum` projection.
|
|
140
|
+
*/
|
|
141
|
+
flaggedSeqNum?: string;
|
|
142
|
+
/** The flagged entry's `entry_id` (also the dedup-key derivation input). */
|
|
143
|
+
flaggedEntryId?: string;
|
|
104
144
|
}
|
|
105
145
|
/**
|
|
106
146
|
* PHASE-CP-1-F.1 Part A (LOCK L2) — tolerant `AWSJSON!` object read.
|
|
@@ -180,8 +220,29 @@ export interface TaskReviewSummaryDurations {
|
|
|
180
220
|
}
|
|
181
221
|
export interface TaskReviewSummaryTokenUsage {
|
|
182
222
|
knownTotal?: number;
|
|
223
|
+
knownInput?: number;
|
|
224
|
+
knownOutput?: number;
|
|
225
|
+
knownCachedInput?: number;
|
|
183
226
|
availability: string;
|
|
184
227
|
unavailableRoles: string[];
|
|
228
|
+
invocations?: TaskReviewSummaryTokenInvocation[];
|
|
229
|
+
}
|
|
230
|
+
export interface TaskReviewSummaryTokenInvocation {
|
|
231
|
+
role: string;
|
|
232
|
+
agent: string;
|
|
233
|
+
taskId?: string;
|
|
234
|
+
trackIndex?: number;
|
|
235
|
+
round?: number;
|
|
236
|
+
gateId?: string;
|
|
237
|
+
seatId?: number;
|
|
238
|
+
reviewerRole?: string;
|
|
239
|
+
inputTokens?: number;
|
|
240
|
+
outputTokens?: number;
|
|
241
|
+
cachedInputTokens?: number;
|
|
242
|
+
totalTokens?: number;
|
|
243
|
+
elapsedMs?: number;
|
|
244
|
+
availability: string;
|
|
245
|
+
unavailableReason?: string;
|
|
185
246
|
}
|
|
186
247
|
/** One round in the per-round summary (decrypted). */
|
|
187
248
|
export interface TaskReviewSummaryRound {
|
|
@@ -862,6 +923,7 @@ export declare class AppSyncClient {
|
|
|
862
923
|
sessionId: string;
|
|
863
924
|
roundNumber: number;
|
|
864
925
|
rawOutput: string;
|
|
926
|
+
usage?: InvocationUsageSnapshot;
|
|
865
927
|
}, sessionKeyBase64: string): Promise<{
|
|
866
928
|
gateId: string;
|
|
867
929
|
workflowState: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,3 +4,11 @@
|
|
|
4
4
|
* the raw process argv (node, script, "keychain", subcommand, flags…).
|
|
5
5
|
*/
|
|
6
6
|
export declare function runKeychainCli(argv: string[]): Promise<number>;
|
|
7
|
+
/**
|
|
8
|
+
* Advisory nudge for `codevibe login` / `codevibe status` (GA follow-up to #642):
|
|
9
|
+
* when this machine still holds file-backed credentials, has NOT migrated, and the
|
|
10
|
+
* OS keyring is actually usable, print the `keychain migrate` suggestion. Purely
|
|
11
|
+
* additive output — never throws, never mutates state, silent on any ambiguity
|
|
12
|
+
* (see migrate-nudge.ts invariants).
|
|
13
|
+
*/
|
|
14
|
+
export declare function maybePrintKeychainMigrationNudge(print?: (line: string) => void): Promise<void>;
|