specmem-hardwicksoftware 3.7.6 → 3.7.7
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.
|
@@ -4014,9 +4014,23 @@ def main():
|
|
|
4014
4014
|
|
|
4015
4015
|
# Signal handling for graceful shutdown
|
|
4016
4016
|
import signal
|
|
4017
|
+
import traceback
|
|
4017
4018
|
def handle_signal(signum, frame):
|
|
4018
4019
|
sig_name = signal.Signals(signum).name
|
|
4020
|
+
# DEBUG: Log who sent the signal for troubleshooting
|
|
4021
|
+
my_pid = os.getpid()
|
|
4022
|
+
my_ppid = os.getppid()
|
|
4019
4023
|
print(f"\n⚡ Received {sig_name} - shutting down gracefully...", file=sys.stderr)
|
|
4024
|
+
print(f" DEBUG: my_pid={my_pid}, my_ppid={my_ppid}", file=sys.stderr)
|
|
4025
|
+
# Try to identify caller via /proc
|
|
4026
|
+
try:
|
|
4027
|
+
with open(f'/proc/{my_ppid}/cmdline', 'r') as f:
|
|
4028
|
+
parent_cmd = f.read().replace('\x00', ' ').strip()
|
|
4029
|
+
print(f" DEBUG: parent_cmd={parent_cmd[:200]}", file=sys.stderr)
|
|
4030
|
+
except Exception as e:
|
|
4031
|
+
print(f" DEBUG: could not read parent cmdline: {e}", file=sys.stderr)
|
|
4032
|
+
print(f" DEBUG: stack trace:", file=sys.stderr)
|
|
4033
|
+
traceback.print_stack(frame, file=sys.stderr)
|
|
4020
4034
|
server.shutdown_requested = True
|
|
4021
4035
|
# Stop QQMS v2 drain thread if enabled
|
|
4022
4036
|
if qqms_v2_instance:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specmem-hardwicksoftware",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Persistent memory system for coding sessions - semantic search with pgvector, token compression, team coordination, file watching. Needs root: installs system-wide hooks, manages docker/PostgreSQL, writes global configs, handles screen sessions. justcalljon.pro",
|
|
6
6
|
"main": "dist/index.js",
|
package/scripts/specmem-init.cjs
CHANGED
|
@@ -3659,15 +3659,18 @@ async function indexCodebase(projectPath, ui, embeddingResult) {
|
|
|
3659
3659
|
try { fs.unlinkSync(projectSocketPath); } catch { /* ignore */ }
|
|
3660
3660
|
}
|
|
3661
3661
|
const pythonPath = getPythonPath();
|
|
3662
|
+
// CRITICAL: Use file descriptor stdio, NOT pipes. Piped stdio causes SIGTERM
|
|
3663
|
+
// when parent event loop is under heavy load during batch indexing.
|
|
3664
|
+
const revalLogPath = path.join(projectPath, 'specmem', 'sockets', 'embedding-autostart.log');
|
|
3665
|
+
const revalLogFd = fs.openSync(revalLogPath, 'a');
|
|
3662
3666
|
const proc = spawn(pythonPath, [embeddingScript], {
|
|
3663
3667
|
cwd: path.dirname(embeddingScript),
|
|
3664
3668
|
env: { ...process.env, SPECMEM_SOCKET_PATH: projectSocketPath, SPECMEM_PROJECT_PATH: projectPath },
|
|
3665
3669
|
detached: true,
|
|
3666
|
-
stdio: ['ignore',
|
|
3670
|
+
stdio: ['ignore', revalLogFd, revalLogFd]
|
|
3667
3671
|
});
|
|
3668
|
-
proc.stdout.on('data', () => {});
|
|
3669
|
-
proc.stderr.on('data', () => {});
|
|
3670
3672
|
proc.on('error', () => {});
|
|
3673
|
+
fs.closeSync(revalLogFd);
|
|
3671
3674
|
proc.unref();
|
|
3672
3675
|
// Wait up to 15s for socket to appear
|
|
3673
3676
|
for (let i = 0; i < 30; i++) {
|
|
@@ -4867,6 +4870,10 @@ async function extractSessions(projectPath, ui, embeddingResult = null) {
|
|
|
4867
4870
|
|
|
4868
4871
|
// Task #22 fix: Use getPythonPath() instead of hardcoded 'python3'
|
|
4869
4872
|
const pythonPath = getPythonPath();
|
|
4873
|
+
// CRITICAL: Use file descriptor stdio, NOT pipes. Piped stdio causes SIGTERM
|
|
4874
|
+
// when parent event loop is under heavy load during batch indexing.
|
|
4875
|
+
const sessEmbedLogPath = path.join(projectPath, 'specmem', 'sockets', 'embedding-autostart.log');
|
|
4876
|
+
const sessEmbedLogFd = fs.openSync(sessEmbedLogPath, 'a');
|
|
4870
4877
|
const embeddingProcess = spawn(pythonPath, [embeddingScript], {
|
|
4871
4878
|
cwd: path.dirname(embeddingScript),
|
|
4872
4879
|
env: {
|
|
@@ -4875,7 +4882,7 @@ async function extractSessions(projectPath, ui, embeddingResult = null) {
|
|
|
4875
4882
|
SPECMEM_PROJECT_PATH: projectPath
|
|
4876
4883
|
},
|
|
4877
4884
|
detached: true,
|
|
4878
|
-
stdio: ['ignore',
|
|
4885
|
+
stdio: ['ignore', sessEmbedLogFd, sessEmbedLogFd]
|
|
4879
4886
|
});
|
|
4880
4887
|
|
|
4881
4888
|
// error handler BEFORE unref - prevents silent spawn failures
|
|
@@ -4883,14 +4890,7 @@ async function extractSessions(projectPath, ui, embeddingResult = null) {
|
|
|
4883
4890
|
ui.setSubStatus('Embedding spawn error: ' + err.message);
|
|
4884
4891
|
});
|
|
4885
4892
|
|
|
4886
|
-
|
|
4887
|
-
embeddingProcess.stdout.on('data', (chunk) => {
|
|
4888
|
-
initLog('[EMBED-STDOUT] ' + chunk.toString().trim());
|
|
4889
|
-
});
|
|
4890
|
-
embeddingProcess.stderr.on('data', (chunk) => {
|
|
4891
|
-
initLog('[EMBED-STDERR] ' + chunk.toString().trim());
|
|
4892
|
-
});
|
|
4893
|
-
|
|
4893
|
+
fs.closeSync(sessEmbedLogFd);
|
|
4894
4894
|
embeddingProcess.unref();
|
|
4895
4895
|
|
|
4896
4896
|
// Wait for socket to appear (up to 30s)
|