@geravant/sinain 1.23.1 → 1.23.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/package.json
CHANGED
|
@@ -212,6 +212,8 @@ export class AudioPipeline extends EventEmitter {
|
|
|
212
212
|
|
|
213
213
|
let headerSkipped = name !== "sox";
|
|
214
214
|
let headerBuf = Buffer.alloc(0);
|
|
215
|
+
let stderrAccum = "";
|
|
216
|
+
const spawnTime = Date.now();
|
|
215
217
|
|
|
216
218
|
proc.stdout?.on("data", (data: Buffer) => {
|
|
217
219
|
if (!this.running) return;
|
|
@@ -237,6 +239,12 @@ export class AudioPipeline extends EventEmitter {
|
|
|
237
239
|
if (msg && !/^In:.*Out:/.test(msg)) {
|
|
238
240
|
log(TAG, `${name} stderr: ${msg.slice(0, 200)}`);
|
|
239
241
|
}
|
|
242
|
+
// Accumulate stderr for TCC detection on exit
|
|
243
|
+
stderrAccum += data.toString();
|
|
244
|
+
// Cap accumulation to avoid unbounded growth (4KB is enough for any TCC message)
|
|
245
|
+
if (stderrAccum.length > 4096) {
|
|
246
|
+
stderrAccum = stderrAccum.slice(-4096);
|
|
247
|
+
}
|
|
240
248
|
});
|
|
241
249
|
|
|
242
250
|
proc.on("error", (err) => {
|
|
@@ -252,6 +260,45 @@ export class AudioPipeline extends EventEmitter {
|
|
|
252
260
|
if (this.running && code !== 0) {
|
|
253
261
|
this.errorCount++;
|
|
254
262
|
this.profiler?.gauge("audio.errors", this.errorCount);
|
|
263
|
+
|
|
264
|
+
// Detect TCC (macOS Screen Recording / Microphone) permission denial.
|
|
265
|
+
// sck-capture logs "declined TCCs" to stderr when the entitlement is
|
|
266
|
+
// missing. The chicken-and-egg: clicking "Allow" on the prompt doesn't
|
|
267
|
+
// apply to a running process — the user must restart Terminal and
|
|
268
|
+
// re-run. We print a prominent banner and request graceful shutdown
|
|
269
|
+
// so users aren't left wondering why the agent never escalates.
|
|
270
|
+
const elapsedMs = Date.now() - spawnTime;
|
|
271
|
+
const isTccDenial = stderrAccum.includes("declined TCCs");
|
|
272
|
+
if (isTccDenial && elapsedMs < 5000) {
|
|
273
|
+
process.stdout.write([
|
|
274
|
+
"",
|
|
275
|
+
"=======================================================================",
|
|
276
|
+
" WARNING: Screen Recording permission needed",
|
|
277
|
+
"=======================================================================",
|
|
278
|
+
"",
|
|
279
|
+
" sck-capture cannot access screen capture and audio without",
|
|
280
|
+
" TCC (Screen Recording) permission from macOS.",
|
|
281
|
+
"",
|
|
282
|
+
" If you just clicked Allow -- that is normal! macOS does not apply",
|
|
283
|
+
" the permission to processes that are already running. To fix:",
|
|
284
|
+
"",
|
|
285
|
+
" 1. Press Ctrl+C to stop sinain",
|
|
286
|
+
" 2. Quit and restart your Terminal app (Cmd+Q, then reopen)",
|
|
287
|
+
" 3. Run again: npx @geravant/sinain@latest start",
|
|
288
|
+
"",
|
|
289
|
+
" Already declined? Re-grant permission:",
|
|
290
|
+
" System Settings > Privacy & Security > Screen Recording",
|
|
291
|
+
" > enable Terminal (or your terminal app)",
|
|
292
|
+
"",
|
|
293
|
+
"=======================================================================",
|
|
294
|
+
"",
|
|
295
|
+
].join("\n"));
|
|
296
|
+
|
|
297
|
+
// Emit TCC-specific error so index.ts can initiate graceful shutdown
|
|
298
|
+
this.emit("tcc-denied");
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
255
302
|
warn(TAG, `${name} exited unexpectedly, stopping pipeline`);
|
|
256
303
|
this.stop();
|
|
257
304
|
}
|
package/sinain-core/src/index.ts
CHANGED
|
@@ -543,7 +543,14 @@ async function importKnowledgeToLocal(data: string): Promise<string> {
|
|
|
543
543
|
const dbPath = `${localDir}/knowledge-graph.db`;
|
|
544
544
|
|
|
545
545
|
const __dir = dirname(fileURLToPath(import.meta.url));
|
|
546
|
-
|
|
546
|
+
// Two package layouts are supported:
|
|
547
|
+
// dev/monorepo: <repo>/sinain-core/src/ → ../../sinain-hud-plugin/sinain-memory
|
|
548
|
+
// npm-published flat: <pkg>/sinain-core/src/ → ../../sinain-memory
|
|
549
|
+
const scriptsDir = [
|
|
550
|
+
resolve(__dir, "..", "..", "sinain-hud-plugin", "sinain-memory"), // dev/monorepo layout
|
|
551
|
+
resolve(__dir, "..", "..", "sinain-memory"), // npm-published flat layout
|
|
552
|
+
resolve(__dir, "..", "sinain-memory"), // legacy alt
|
|
553
|
+
].find(p => existsSync(`${p}/triplestore.py`)) || resolve(__dir, "..", "..", "sinain-memory");
|
|
547
554
|
|
|
548
555
|
// Convert facts to graph ops for knowledge_integrator
|
|
549
556
|
const graphOps = facts.map((f: any) => ({
|
|
@@ -834,6 +841,12 @@ async function main() {
|
|
|
834
841
|
wsHandler.updateState({ audio: "muted" });
|
|
835
842
|
});
|
|
836
843
|
|
|
844
|
+
systemAudioPipeline.on("tcc-denied", () => {
|
|
845
|
+
// Banner already printed by pipeline.ts. Initiate graceful shutdown so
|
|
846
|
+
// sinain exits cleanly rather than continuing with audio dead.
|
|
847
|
+
shutdown("TCC-DENIED").catch(() => process.exit(1));
|
|
848
|
+
});
|
|
849
|
+
|
|
837
850
|
systemAudioPipeline.on("muted", () => {
|
|
838
851
|
log(TAG, "system audio muted (capture process still running)");
|
|
839
852
|
wsHandler.updateState({ audio: "muted" });
|
|
@@ -55,10 +55,14 @@ export class EntityCache {
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
// Query entity names directly via SQLite
|
|
58
|
+
// Query entity names directly via SQLite.
|
|
59
|
+
// Two package layouts are supported:
|
|
60
|
+
// dev/monorepo: <repo>/sinain-core/src/learning/ → ../../../sinain-hud-plugin/sinain-memory
|
|
61
|
+
// npm-published flat: <pkg>/sinain-core/src/learning/ → ../../../sinain-memory
|
|
59
62
|
const scriptCandidates = [
|
|
60
|
-
resolve(__dir, "..", "..", "sinain-hud-plugin", "sinain-memory", "graph_query.py"),
|
|
61
|
-
resolve(__dir, "..", "sinain-memory", "graph_query.py"),
|
|
63
|
+
resolve(__dir, "..", "..", "..", "sinain-hud-plugin", "sinain-memory", "graph_query.py"), // dev/monorepo layout
|
|
64
|
+
resolve(__dir, "..", "..", "..", "sinain-memory", "graph_query.py"), // npm-published flat layout
|
|
65
|
+
resolve(__dir, "..", "..", "sinain-memory", "graph_query.py"), // legacy alt
|
|
62
66
|
];
|
|
63
67
|
const scriptPath = scriptCandidates.find(p => existsSync(p));
|
|
64
68
|
if (!scriptPath) return;
|
|
@@ -23,18 +23,26 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
23
23
|
|
|
24
24
|
/** Resolve the sinain-memory Python scripts directory. */
|
|
25
25
|
function resolveScriptsDir(): string {
|
|
26
|
-
// Look for sinain-memory scripts in known locations
|
|
26
|
+
// Look for sinain-memory scripts in known locations.
|
|
27
|
+
// Two package layouts are supported:
|
|
28
|
+
// dev/monorepo: <repo>/sinain-core/src/learning/ → ../../../sinain-hud-plugin/sinain-memory
|
|
29
|
+
// npm-published flat: <pkg>/sinain-core/src/learning/ → ../../../sinain-memory
|
|
27
30
|
const candidates = [
|
|
28
|
-
resolve(__dirname, "..", "..", "..", "sinain-hud-plugin", "sinain-memory"),
|
|
29
|
-
resolve(__dirname, "..", "..", "sinain-memory"),
|
|
30
|
-
resolve(
|
|
31
|
+
resolve(__dirname, "..", "..", "..", "sinain-hud-plugin", "sinain-memory"), // dev/monorepo layout
|
|
32
|
+
resolve(__dirname, "..", "..", "..", "sinain-memory"), // npm-published flat layout
|
|
33
|
+
resolve(__dirname, "..", "..", "sinain-memory"), // legacy alt
|
|
34
|
+
resolve(process.env.HOME || "", ".sinain", "sinain-memory"), // user-local fallback
|
|
31
35
|
];
|
|
32
36
|
for (const dir of candidates) {
|
|
33
37
|
if (existsSync(resolve(dir, "session_distiller.py"))) {
|
|
34
38
|
return dir;
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
|
-
|
|
41
|
+
error(TAG, `sinain-memory scripts not found. Searched ${candidates.length} locations:`);
|
|
42
|
+
for (const dir of candidates) {
|
|
43
|
+
error(TAG, ` - ${dir}`);
|
|
44
|
+
}
|
|
45
|
+
return candidates[candidates.length - 1]; // Return user-local path as sentinel
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
/** Resolve the local memory directory. */
|