@remnic/plugin-codex 9.3.572 → 9.3.574
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/hooks/bin/post-tool-observe.sh +124 -8
- package/hooks/bin/session-end.sh +158 -41
- package/package.json +2 -2
|
@@ -62,31 +62,147 @@ CWD="$(node -e "const d=JSON.parse(process.argv[1]); process.stdout.write(d.cwd|
|
|
|
62
62
|
TOOL_NAME="$(node -e "const d=JSON.parse(process.argv[1]); process.stdout.write(d.tool_name||'')" "$INPUT" 2>/dev/null || echo "")"
|
|
63
63
|
PROJECT_NAME="$(basename "$CWD" 2>/dev/null || echo "unknown")"
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
case "$SESSION_ID" in
|
|
66
|
+
""|*[!A-Za-z0-9._-]*)
|
|
67
|
+
log "invalid session id: $SESSION_ID"
|
|
68
|
+
exit 0
|
|
69
|
+
;;
|
|
70
|
+
esac
|
|
66
71
|
{ [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; } && exit 0
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
STATE_HOME="${XDG_STATE_HOME:-${HOME}/.local/state}"
|
|
74
|
+
STATE_DIR="${STATE_HOME}/remnic/hooks"
|
|
75
|
+
|
|
76
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || exit 0
|
|
77
|
+
if ! node - "$STATE_DIR" <<'NODE'
|
|
78
|
+
const fs = require('fs');
|
|
79
|
+
const stateDir = process.argv[2];
|
|
80
|
+
try {
|
|
81
|
+
const info = fs.lstatSync(stateDir);
|
|
82
|
+
if (info.isSymbolicLink() || !info.isDirectory()) process.exit(1);
|
|
83
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
84
|
+
if ((info.mode & 0o077) !== 0) fs.chmodSync(stateDir, 0o700);
|
|
85
|
+
} catch {
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
NODE
|
|
89
|
+
then
|
|
90
|
+
log "unsafe state directory $STATE_DIR"
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
CURSOR_FILE="${STATE_DIR}/remnic-cursor-${SESSION_ID}"
|
|
95
|
+
LOCK_DIR="${STATE_DIR}/remnic-lock-${SESSION_ID}.d"
|
|
96
|
+
LEGACY_CURSOR_FILE="${STATE_DIR}/engram-cursor-${SESSION_ID}"
|
|
97
|
+
LEGACY_LOCK_DIR="${STATE_DIR}/engram-lock-${SESSION_ID}.d"
|
|
72
98
|
|
|
73
99
|
if [ ! -f "$CURSOR_FILE" ] && { [ -f "$LEGACY_CURSOR_FILE" ] || [ -d "$LEGACY_LOCK_DIR" ]; }; then
|
|
74
100
|
CURSOR_FILE="$LEGACY_CURSOR_FILE"
|
|
75
101
|
LOCK_DIR="$LEGACY_LOCK_DIR"
|
|
76
102
|
fi
|
|
77
103
|
|
|
104
|
+
validate_cursor_file() {
|
|
105
|
+
node - "$CURSOR_FILE" <<'NODE'
|
|
106
|
+
const fs = require('fs');
|
|
107
|
+
const cursorFile = process.argv[2];
|
|
108
|
+
try {
|
|
109
|
+
const info = fs.lstatSync(cursorFile);
|
|
110
|
+
if (info.isSymbolicLink() || !info.isFile()) process.exit(1);
|
|
111
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error && error.code === 'ENOENT') process.exit(0);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
NODE
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
read_cursor_file() {
|
|
120
|
+
validate_cursor_file || {
|
|
121
|
+
log "unsafe cursor file $CURSOR_FILE"
|
|
122
|
+
return 1
|
|
123
|
+
}
|
|
124
|
+
[ -f "$CURSOR_FILE" ] && cat "$CURSOR_FILE" 2>/dev/null || echo 0
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
write_cursor_file() {
|
|
128
|
+
NEW_CURSOR_VALUE="$1"
|
|
129
|
+
validate_cursor_file || {
|
|
130
|
+
log "refusing unsafe cursor file $CURSOR_FILE"
|
|
131
|
+
return 1
|
|
132
|
+
}
|
|
133
|
+
TEMP_CURSOR="$(mktemp "${CURSOR_FILE}.tmp.XXXXXX" 2>/dev/null)" || return 1
|
|
134
|
+
if ! printf '%s\n' "$NEW_CURSOR_VALUE" > "$TEMP_CURSOR"; then
|
|
135
|
+
rm -f "$TEMP_CURSOR"
|
|
136
|
+
return 1
|
|
137
|
+
fi
|
|
138
|
+
chmod 600 "$TEMP_CURSOR" 2>/dev/null || true
|
|
139
|
+
mv -f "$TEMP_CURSOR" "$CURSOR_FILE"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
migrate_tmp_cursor_file() {
|
|
143
|
+
for TMP_CURSOR_FILE in "/tmp/remnic-cursor-${SESSION_ID}" "/tmp/engram-cursor-${SESSION_ID}"; do
|
|
144
|
+
[ ! -e "$TMP_CURSOR_FILE" ] && continue
|
|
145
|
+
TMP_CURSOR_VALUE="$(node - "$TMP_CURSOR_FILE" <<'NODE'
|
|
146
|
+
const fs = require('fs');
|
|
147
|
+
const cursorFile = process.argv[2];
|
|
148
|
+
try {
|
|
149
|
+
const info = fs.lstatSync(cursorFile);
|
|
150
|
+
if (info.isSymbolicLink() || !info.isFile()) process.exit(1);
|
|
151
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
152
|
+
const value = fs.readFileSync(cursorFile, 'utf8').trim();
|
|
153
|
+
if (!/^\d+$/.test(value)) process.exit(1);
|
|
154
|
+
process.stdout.write(value);
|
|
155
|
+
} catch {
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
NODE
|
|
159
|
+
)" || continue
|
|
160
|
+
CURRENT_CURSOR_VALUE=""
|
|
161
|
+
if validate_cursor_file; then
|
|
162
|
+
CURRENT_CURSOR_VALUE="$([ -f "$CURSOR_FILE" ] && cat "$CURSOR_FILE" 2>/dev/null || echo "")"
|
|
163
|
+
fi
|
|
164
|
+
case "$CURRENT_CURSOR_VALUE" in
|
|
165
|
+
""|*[!0-9]*) CURRENT_CURSOR_VALUE="-1" ;;
|
|
166
|
+
esac
|
|
167
|
+
if [ "$TMP_CURSOR_VALUE" -gt "$CURRENT_CURSOR_VALUE" ]; then
|
|
168
|
+
write_cursor_file "$TMP_CURSOR_VALUE" || continue
|
|
169
|
+
fi
|
|
170
|
+
rm -f "$TMP_CURSOR_FILE" 2>/dev/null
|
|
171
|
+
done
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
remove_stale_lock_dir() {
|
|
175
|
+
node - "$LOCK_DIR" <<'NODE'
|
|
176
|
+
const fs = require('fs');
|
|
177
|
+
const lockDir = process.argv[2];
|
|
178
|
+
try {
|
|
179
|
+
const info = fs.lstatSync(lockDir);
|
|
180
|
+
if (info.isSymbolicLink() || !info.isDirectory()) process.exit(1);
|
|
181
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
182
|
+
if (Date.now() - info.mtimeMs < 10 * 60 * 1000) process.exit(0);
|
|
183
|
+
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
184
|
+
} catch (error) {
|
|
185
|
+
if (error && error.code === 'ENOENT') process.exit(0);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
NODE
|
|
189
|
+
}
|
|
190
|
+
|
|
78
191
|
(
|
|
79
192
|
# Acquire exclusive lock
|
|
80
193
|
ACQUIRED=0
|
|
81
194
|
for _i in $(seq 1 50); do
|
|
82
195
|
if mkdir "$LOCK_DIR" 2>/dev/null; then ACQUIRED=1; break; fi
|
|
196
|
+
[ "$_i" -eq 1 ] && remove_stale_lock_dir >/dev/null 2>&1
|
|
83
197
|
sleep 0.1
|
|
84
198
|
done
|
|
85
199
|
trap 'rmdir "$LOCK_DIR" 2>/dev/null' EXIT INT TERM
|
|
86
200
|
[ "$ACQUIRED" -eq 0 ] && exit 0
|
|
87
201
|
|
|
202
|
+
migrate_tmp_cursor_file
|
|
203
|
+
|
|
88
204
|
LAST_COUNT=0
|
|
89
|
-
|
|
205
|
+
LAST_COUNT="$(read_cursor_file)" || exit 0
|
|
90
206
|
|
|
91
207
|
PAYLOAD="$(node -e "
|
|
92
208
|
const fs = require('fs');
|
|
@@ -131,7 +247,7 @@ fi
|
|
|
131
247
|
[ -z "$PAYLOAD" ] && { log "parse failed for $SESSION_ID"; exit 0; }
|
|
132
248
|
|
|
133
249
|
if echo "$PAYLOAD" | grep -q "^CURSOR:"; then
|
|
134
|
-
|
|
250
|
+
write_cursor_file "${PAYLOAD#CURSOR:}" || log "cursor write failed for $SESSION_ID"
|
|
135
251
|
exit 0
|
|
136
252
|
fi
|
|
137
253
|
|
|
@@ -154,7 +270,7 @@ fi
|
|
|
154
270
|
|
|
155
271
|
if [ $CURL_EXIT -eq 0 ] && [[ "$HTTP_STATUS" =~ ^2 ]]; then
|
|
156
272
|
log "observe OK for $SESSION_ID"
|
|
157
|
-
|
|
273
|
+
write_cursor_file "$TOTAL" || log "cursor write failed for $SESSION_ID"
|
|
158
274
|
else
|
|
159
275
|
log "observe failed (curl=$CURL_EXIT http=$HTTP_STATUS) — cursor not advanced"
|
|
160
276
|
fi
|
package/hooks/bin/session-end.sh
CHANGED
|
@@ -53,55 +53,172 @@ TRANSCRIPT_PATH="$(node -e "const d=JSON.parse(process.argv[1]); process.stdout.
|
|
|
53
53
|
|
|
54
54
|
echo '{"continue":true}'
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
if [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
SESSION_ID_SAFE=0
|
|
57
|
+
if [[ "$SESSION_ID" != "" && ! "$SESSION_ID" =~ [^A-Za-z0-9._-] ]]; then
|
|
58
|
+
SESSION_ID_SAFE=1
|
|
59
|
+
STATE_HOME="${XDG_STATE_HOME:-${HOME}/.local/state}"
|
|
60
|
+
STATE_DIR="${STATE_HOME}/remnic/hooks"
|
|
61
|
+
CURSOR_FILE="${STATE_DIR}/remnic-cursor-${SESSION_ID}"
|
|
62
|
+
LOCK_DIR="${STATE_DIR}/remnic-lock-${SESSION_ID}.d"
|
|
63
|
+
LEGACY_CURSOR_FILE="${STATE_DIR}/engram-cursor-${SESSION_ID}"
|
|
64
|
+
LEGACY_LOCK_DIR="${STATE_DIR}/engram-lock-${SESSION_ID}.d"
|
|
65
|
+
|
|
66
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || SESSION_ID_SAFE=0
|
|
67
|
+
if [ "$SESSION_ID_SAFE" -eq 1 ]; then
|
|
68
|
+
if ! node - "$STATE_DIR" <<'NODE'
|
|
69
|
+
const fs = require('fs');
|
|
70
|
+
const stateDir = process.argv[2];
|
|
71
|
+
try {
|
|
72
|
+
const info = fs.lstatSync(stateDir);
|
|
73
|
+
if (info.isSymbolicLink() || !info.isDirectory()) process.exit(1);
|
|
74
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
75
|
+
if ((info.mode & 0o077) !== 0) fs.chmodSync(stateDir, 0o700);
|
|
76
|
+
} catch {
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
NODE
|
|
80
|
+
then
|
|
81
|
+
log "unsafe state directory $STATE_DIR"
|
|
82
|
+
SESSION_ID_SAFE=0
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
if [ "$SESSION_ID_SAFE" -eq 1 ] && [ ! -f "$CURSOR_FILE" ] && { [ -f "$LEGACY_CURSOR_FILE" ] || [ -d "$LEGACY_LOCK_DIR" ]; }; then
|
|
61
86
|
CURSOR_FILE="$LEGACY_CURSOR_FILE"
|
|
87
|
+
LOCK_DIR="$LEGACY_LOCK_DIR"
|
|
62
88
|
fi
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
validate_cursor_file() {
|
|
92
|
+
node - "$CURSOR_FILE" <<'NODE'
|
|
93
|
+
const fs = require('fs');
|
|
94
|
+
const cursorFile = process.argv[2];
|
|
95
|
+
try {
|
|
96
|
+
const info = fs.lstatSync(cursorFile);
|
|
97
|
+
if (info.isSymbolicLink() || !info.isFile()) process.exit(1);
|
|
98
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error && error.code === 'ENOENT') process.exit(0);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
NODE
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
read_cursor_file() {
|
|
107
|
+
validate_cursor_file || {
|
|
108
|
+
log "unsafe cursor file $CURSOR_FILE"
|
|
109
|
+
return 1
|
|
110
|
+
}
|
|
111
|
+
[ -f "$CURSOR_FILE" ] && cat "$CURSOR_FILE" 2>/dev/null || echo 0
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
write_cursor_file() {
|
|
115
|
+
NEW_CURSOR_VALUE="$1"
|
|
116
|
+
validate_cursor_file || {
|
|
117
|
+
log "refusing unsafe cursor file $CURSOR_FILE"
|
|
118
|
+
return 1
|
|
119
|
+
}
|
|
120
|
+
TEMP_CURSOR="$(mktemp "${CURSOR_FILE}.tmp.XXXXXX" 2>/dev/null)" || return 1
|
|
121
|
+
if ! printf '%s\n' "$NEW_CURSOR_VALUE" > "$TEMP_CURSOR"; then
|
|
122
|
+
rm -f "$TEMP_CURSOR"
|
|
123
|
+
return 1
|
|
124
|
+
fi
|
|
125
|
+
chmod 600 "$TEMP_CURSOR" 2>/dev/null || true
|
|
126
|
+
mv -f "$TEMP_CURSOR" "$CURSOR_FILE"
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
migrate_tmp_cursor_file() {
|
|
130
|
+
for TMP_CURSOR_FILE in "/tmp/remnic-cursor-${SESSION_ID}" "/tmp/engram-cursor-${SESSION_ID}"; do
|
|
131
|
+
[ ! -e "$TMP_CURSOR_FILE" ] && continue
|
|
132
|
+
TMP_CURSOR_VALUE="$(node - "$TMP_CURSOR_FILE" <<'NODE'
|
|
133
|
+
const fs = require('fs');
|
|
134
|
+
const cursorFile = process.argv[2];
|
|
135
|
+
try {
|
|
136
|
+
const info = fs.lstatSync(cursorFile);
|
|
137
|
+
if (info.isSymbolicLink() || !info.isFile()) process.exit(1);
|
|
138
|
+
if (typeof process.getuid === 'function' && info.uid !== process.getuid()) process.exit(1);
|
|
139
|
+
const value = fs.readFileSync(cursorFile, 'utf8').trim();
|
|
140
|
+
if (!/^\d+$/.test(value)) process.exit(1);
|
|
141
|
+
process.stdout.write(value);
|
|
142
|
+
} catch {
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
NODE
|
|
146
|
+
)" || continue
|
|
147
|
+
CURRENT_CURSOR_VALUE=""
|
|
148
|
+
if validate_cursor_file; then
|
|
149
|
+
CURRENT_CURSOR_VALUE="$([ -f "$CURSOR_FILE" ] && cat "$CURSOR_FILE" 2>/dev/null || echo "")"
|
|
150
|
+
fi
|
|
151
|
+
case "$CURRENT_CURSOR_VALUE" in
|
|
152
|
+
""|*[!0-9]*) CURRENT_CURSOR_VALUE="-1" ;;
|
|
153
|
+
esac
|
|
154
|
+
if [ "$TMP_CURSOR_VALUE" -gt "$CURRENT_CURSOR_VALUE" ]; then
|
|
155
|
+
write_cursor_file "$TMP_CURSOR_VALUE" || continue
|
|
156
|
+
fi
|
|
157
|
+
rm -f "$TMP_CURSOR_FILE" 2>/dev/null
|
|
158
|
+
done
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
remove_cursor_file() {
|
|
162
|
+
validate_cursor_file || {
|
|
163
|
+
log "refusing unsafe cursor file $CURSOR_FILE"
|
|
164
|
+
return 1
|
|
165
|
+
}
|
|
166
|
+
rm -f "$CURSOR_FILE"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Final observe flush if we have transcript
|
|
170
|
+
if [ -n "$REMNIC_TOKEN" ] && [ "$SESSION_ID_SAFE" -eq 1 ] && [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
|
|
63
171
|
LAST_COUNT=0
|
|
64
|
-
|
|
172
|
+
migrate_tmp_cursor_file
|
|
173
|
+
if LAST_COUNT="$(read_cursor_file)"; then
|
|
174
|
+
PAYLOAD="$(node -e "
|
|
175
|
+
const fs = require('fs');
|
|
176
|
+
const lines = fs.readFileSync(process.argv[1], 'utf8').split('\n').filter(Boolean);
|
|
177
|
+
const messages = [];
|
|
178
|
+
for (const line of lines) {
|
|
179
|
+
try {
|
|
180
|
+
const entry = JSON.parse(line);
|
|
181
|
+
if (entry.type !== 'user' && entry.type !== 'assistant') continue;
|
|
182
|
+
const msg = entry.message;
|
|
183
|
+
if (!msg || typeof msg !== 'object') continue;
|
|
184
|
+
const role = msg.role;
|
|
185
|
+
if (role !== 'user' && role !== 'assistant') continue;
|
|
186
|
+
let text = typeof msg.content === 'string' ? msg.content.trim() :
|
|
187
|
+
Array.isArray(msg.content) ? msg.content.filter(b => b.type === 'text' && b.text).map(b => b.text.trim()).join('\n').trim() : '';
|
|
188
|
+
if (text) messages.push({ role, content: text });
|
|
189
|
+
} catch {}
|
|
190
|
+
}
|
|
191
|
+
const newMessages = messages.slice(parseInt(process.argv[3], 10) || 0);
|
|
192
|
+
if (newMessages.length) {
|
|
193
|
+
process.stdout.write(JSON.stringify({ sessionKey: process.argv[2], messages: newMessages }));
|
|
194
|
+
}
|
|
195
|
+
" "$TRANSCRIPT_PATH" "$SESSION_ID" "$LAST_COUNT" 2>/dev/null)"
|
|
65
196
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (role !== 'user' && role !== 'assistant') continue;
|
|
78
|
-
let text = typeof msg.content === 'string' ? msg.content.trim() :
|
|
79
|
-
Array.isArray(msg.content) ? msg.content.filter(b => b.type === 'text' && b.text).map(b => b.text.trim()).join('\n').trim() : '';
|
|
80
|
-
if (text) messages.push({ role, content: text });
|
|
81
|
-
} catch {}
|
|
82
|
-
}
|
|
83
|
-
const newMessages = messages.slice(parseInt(process.argv[3], 10) || 0);
|
|
84
|
-
if (newMessages.length) {
|
|
85
|
-
process.stdout.write(JSON.stringify({ sessionKey: process.argv[2], messages: newMessages }));
|
|
86
|
-
}
|
|
87
|
-
" "$TRANSCRIPT_PATH" "$SESSION_ID" "$LAST_COUNT" 2>/dev/null)"
|
|
88
|
-
|
|
89
|
-
if [ -n "$PAYLOAD" ]; then
|
|
90
|
-
log "final flush for $SESSION_ID"
|
|
91
|
-
curl -s --max-time 30 \
|
|
92
|
-
-X POST "$REMNIC_URL" \
|
|
93
|
-
-H "Authorization: Bearer ${REMNIC_TOKEN}" \
|
|
94
|
-
-H "Content-Type: application/json" \
|
|
95
|
-
-H "X-Engram-Client-Id: codex" \
|
|
96
|
-
-d "$PAYLOAD" >/dev/null 2>&1 || log "final flush failed"
|
|
197
|
+
if [ -n "$PAYLOAD" ]; then
|
|
198
|
+
log "final flush for $SESSION_ID"
|
|
199
|
+
curl -s --max-time 30 \
|
|
200
|
+
-X POST "$REMNIC_URL" \
|
|
201
|
+
-H "Authorization: Bearer ${REMNIC_TOKEN}" \
|
|
202
|
+
-H "Content-Type: application/json" \
|
|
203
|
+
-H "X-Engram-Client-Id: codex" \
|
|
204
|
+
-d "$PAYLOAD" >/dev/null 2>&1 || log "final flush failed"
|
|
205
|
+
fi
|
|
206
|
+
else
|
|
207
|
+
log "final flush skipped for $SESSION_ID due to unsafe cursor"
|
|
97
208
|
fi
|
|
98
209
|
fi
|
|
99
210
|
|
|
100
211
|
# Cleanup
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
212
|
+
if [ "$SESSION_ID_SAFE" -eq 1 ]; then
|
|
213
|
+
remove_cursor_file || true
|
|
214
|
+
rmdir "$LOCK_DIR" 2>/dev/null || true
|
|
215
|
+
if [ "$CURSOR_FILE" != "$LEGACY_CURSOR_FILE" ] && [ -e "$LEGACY_CURSOR_FILE" ] && [ ! -L "$LEGACY_CURSOR_FILE" ]; then
|
|
216
|
+
rm -f "$LEGACY_CURSOR_FILE" 2>/dev/null || true
|
|
217
|
+
fi
|
|
218
|
+
if [ "$LOCK_DIR" != "$LEGACY_LOCK_DIR" ]; then
|
|
219
|
+
rmdir "$LEGACY_LOCK_DIR" 2>/dev/null || true
|
|
220
|
+
fi
|
|
221
|
+
fi
|
|
105
222
|
|
|
106
223
|
# Codex-native memory materialization (#378). The script honors the
|
|
107
224
|
# `codexMaterializeMemories` config flag and the `.remnic-managed` sentinel,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/plugin-codex",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.574",
|
|
4
4
|
"description": "Remnic memory plugin for Codex CLI — hooks, skills, MCP integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
".mcp.json"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@remnic/core": "^9.3.
|
|
33
|
+
"@remnic/core": "^9.3.574"
|
|
34
34
|
}
|
|
35
35
|
}
|