@cortexkit/pi-magic-context 0.41.4 → 0.42.0

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.
@@ -1,16 +1,14 @@
1
1
  import {
2
2
  setHarness,
3
- log
4
- } from "./index-147qn1yq.js";
5
- import {
3
+ log,
6
4
  resolveProjectIdentityForSession,
7
5
  setStoragePrivatePermissionEnforcement,
8
6
  openDatabase,
9
- resolvePiHarnessKind,
10
7
  loadPiConfig,
11
8
  ensureProjectRegisteredFromPiDirectory,
9
+ resolvePiHarnessKind,
12
10
  registerMagicContextTools
13
- } from "./index-jc59f2q7.js";
11
+ } from "./index-yb21jtfd.js";
14
12
 
15
13
  // src/subagent-entry.ts
16
14
  var SUBAGENT_DREAMER_ACTIONS_FLAG = "magic-context-dreamer-actions";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.41.4",
3
+ "version": "0.42.0",
4
4
  "type": "module",
5
5
  "description": "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -1,466 +0,0 @@
1
- // ../plugin/src/shared/harness.ts
2
- var currentHarness = "opencode";
3
- var harnessLocked = false;
4
- function setHarness(value) {
5
- if (harnessLocked && currentHarness !== value) {
6
- throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
7
- }
8
- currentHarness = value;
9
- harnessLocked = true;
10
- }
11
- function getHarness() {
12
- return currentHarness;
13
- }
14
-
15
- // ../plugin/src/shared/data-path.ts
16
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
17
- import * as os from "node:os";
18
- import * as path from "node:path";
19
- function getDataDir() {
20
- return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
21
- }
22
- function getMagicContextTempDir(harness = getHarness()) {
23
- return path.join(os.tmpdir(), harness, "magic-context");
24
- }
25
- function getMagicContextLogPath(harness = getHarness()) {
26
- const envPath = process.env.MAGIC_CONTEXT_LOG_PATH?.trim();
27
- if (envPath)
28
- return envPath;
29
- return path.join(getMagicContextTempDir(harness), "magic-context.log");
30
- }
31
- function getProjectMagicContextDir(directory) {
32
- return path.join(directory, ".cortexkit", "magic-context");
33
- }
34
- var GITIGNORE_GUARD_OPEN = "# >>> cortexkit:magic-context";
35
- var GITIGNORE_GUARD_CLOSE = "# <<< cortexkit:magic-context";
36
- function ensureCortexKitArtifactGitignore(directory) {
37
- try {
38
- const cortexKitDir = path.join(directory, ".cortexkit");
39
- const gitignorePath = path.join(cortexKitDir, ".gitignore");
40
- let existing = "";
41
- if (existsSync(gitignorePath)) {
42
- existing = readFileSync(gitignorePath, "utf8");
43
- if (existing.includes(GITIGNORE_GUARD_OPEN))
44
- return;
45
- }
46
- const block = `${GITIGNORE_GUARD_OPEN}
47
- magic-context/
48
- ${GITIGNORE_GUARD_CLOSE}
49
- `;
50
- const needsLeadingNewline = existing.length > 0 && !existing.endsWith(`
51
- `);
52
- const next = existing + (needsLeadingNewline ? `
53
- ` : "") + block;
54
- mkdirSync(cortexKitDir, { recursive: true });
55
- writeFileSync(gitignorePath, next, "utf8");
56
- } catch {}
57
- }
58
- function getProjectMagicContextHistorianDir(directory) {
59
- return path.join(getProjectMagicContextDir(directory), "historian");
60
- }
61
- function getOpenCodeStorageDir() {
62
- return path.join(getDataDir(), "opencode", "storage");
63
- }
64
- function getMagicContextStorageResolution() {
65
- const testDataDir = process.env.MAGIC_CONTEXT_TEST_DATA_DIR?.trim();
66
- if (testDataDir) {
67
- const perTestDataHome = process.env.XDG_DATA_HOME?.trim();
68
- if (perTestDataHome && path.resolve(perTestDataHome) !== path.resolve(testDataDir)) {
69
- return {
70
- path: path.join(perTestDataHome, "cortexkit", "magic-context"),
71
- source: "test isolation"
72
- };
73
- }
74
- return {
75
- path: path.join(testDataDir, "cortexkit", "magic-context"),
76
- source: "test isolation"
77
- };
78
- }
79
- if (false) {}
80
- const explicitStorageDir = process.env.MAGIC_CONTEXT_STORAGE_DIR?.trim();
81
- if (explicitStorageDir) {
82
- if (!path.isAbsolute(explicitStorageDir)) {
83
- throw new Error("MAGIC_CONTEXT_STORAGE_DIR must be an absolute path");
84
- }
85
- return { path: explicitStorageDir, source: "environment override" };
86
- }
87
- const xdgDataHome = process.env.XDG_DATA_HOME?.trim();
88
- if (xdgDataHome) {
89
- return {
90
- path: path.join(xdgDataHome, "cortexkit", "magic-context"),
91
- source: "XDG_DATA_HOME"
92
- };
93
- }
94
- return {
95
- path: path.join(os.homedir(), ".local", "share", "cortexkit", "magic-context"),
96
- source: "platform default"
97
- };
98
- }
99
- function getMagicContextStorageDir() {
100
- return getMagicContextStorageResolution().path;
101
- }
102
- function getLegacyOpenCodeMagicContextStorageDir() {
103
- return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
104
- }
105
-
106
- // ../plugin/src/shared/logger.ts
107
- import * as fs from "node:fs";
108
- import * as path2 from "node:path";
109
-
110
- // ../plugin/src/shared/redaction.ts
111
- import { homedir as homedir2, userInfo } from "node:os";
112
- function escapeRegex(value) {
113
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
114
- }
115
- var SECRET_WORDS = [
116
- "key",
117
- "token",
118
- "secret",
119
- "password",
120
- "auth",
121
- "authorization",
122
- "bearer",
123
- "credential"
124
- ];
125
- var SECRET_SEGMENT_PATTERN = new RegExp(`^(?:${SECRET_WORDS.map((w) => `${w}s?`).join("|")})$`, "i");
126
- var TRAILING_DESCRIPTORS = new Set(["id", "ids", "value", "values", "header", "headers"]);
127
- function redactionTypeForKey(key) {
128
- const normalized = key.trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, "_");
129
- const suffix = normalized.split(".").filter(Boolean).at(-1) ?? normalized;
130
- return suffix || "secret";
131
- }
132
- function isNonSecretScalarValue(value) {
133
- const v = value.trim();
134
- if (v === "true" || v === "false" || v === "null" || v === "undefined")
135
- return true;
136
- return /^[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(v);
137
- }
138
- var SECRET_QUALIFIERS = new Set([
139
- "api",
140
- "access",
141
- "private",
142
- "client",
143
- "auth",
144
- "authorization",
145
- "secret",
146
- "bearer",
147
- "session",
148
- "refresh",
149
- "service",
150
- "x",
151
- "openai",
152
- "anthropic",
153
- "google",
154
- "github",
155
- "huggingface",
156
- "aws",
157
- "azure"
158
- ]);
159
- function isSecretKey(key) {
160
- const segments = key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().split(/[._-]+/).filter(Boolean);
161
- if (segments.length === 0)
162
- return false;
163
- if (segments.length === 1) {
164
- const first = segments[0];
165
- return Boolean(first && SECRET_SEGMENT_PATTERN.test(first));
166
- }
167
- for (let i = 0;i < segments.length; i++) {
168
- const seg = segments[i];
169
- if (!seg || !SECRET_SEGMENT_PATTERN.test(seg))
170
- continue;
171
- let trailingOk = true;
172
- for (let j = i + 1;j < segments.length; j++) {
173
- const tail = segments[j];
174
- if (!tail)
175
- continue;
176
- if (TRAILING_DESCRIPTORS.has(tail))
177
- continue;
178
- if (SECRET_SEGMENT_PATTERN.test(tail))
179
- continue;
180
- trailingOk = false;
181
- break;
182
- }
183
- if (!trailingOk)
184
- continue;
185
- for (let k = i - 1;k >= 0; k--) {
186
- const lead = segments[k];
187
- if (lead && SECRET_QUALIFIERS.has(lead))
188
- return true;
189
- }
190
- }
191
- return false;
192
- }
193
- function sanitizePathString(value) {
194
- const home = process.env.HOME || process.env.USERPROFILE || homedir2();
195
- const username = userInfo().username;
196
- let sanitized = value;
197
- if (home) {
198
- sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
199
- }
200
- sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
201
- sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
202
- sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
203
- if (username) {
204
- sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
205
- }
206
- return sanitized;
207
- }
208
- var SECRET_TEXT_PATTERNS = [
209
- {
210
- pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
211
- replacement: "<ANTHROPIC_API_KEY_REDACTED>"
212
- },
213
- {
214
- pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{12,}/g,
215
- replacement: "<OPENAI_API_KEY_REDACTED>"
216
- },
217
- {
218
- pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
219
- replacement: "<GITHUB_PAT_REDACTED>"
220
- },
221
- {
222
- pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
223
- replacement: "<GITHUB_TOKEN_REDACTED>"
224
- },
225
- {
226
- pattern: /\bhf_[A-Za-z0-9]{30,}/g,
227
- replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
228
- },
229
- {
230
- pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
231
- replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
232
- },
233
- {
234
- pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
235
- replacement: "<SLACK_TOKEN_REDACTED>"
236
- },
237
- {
238
- pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
239
- replacement: "<GOOGLE_API_KEY_REDACTED>"
240
- },
241
- {
242
- pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{8,})/gi,
243
- replacement: (_full, prefix) => `${prefix}<REDACTED:bearer>`
244
- },
245
- {
246
- pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
247
- replacement: "<JWT_REDACTED>"
248
- },
249
- {
250
- pattern: /(["'])([^"']*(?:key|token|secret|password|auth|bearer|credential)[^"']*)\1(\s*:\s*)(["'])([^"']*)\4/gi,
251
- replacement: (full, quote, key, separator, valueQuote, value) => isNonSecretScalarValue(value) ? full : `${quote}${key}${quote}${separator}${valueQuote}<REDACTED:${redactionTypeForKey(key)}>${valueQuote}`
252
- },
253
- {
254
- pattern: /\b([A-Za-z0-9_.-]*(?:key|token|secret|password|auth|bearer|credential)[A-Za-z0-9_.-]*)\s*=\s*([^\s'"`]+)/gi,
255
- replacement: (full, key, value) => isNonSecretScalarValue(value) ? full : `${key}=<REDACTED:${redactionTypeForKey(key)}>`
256
- }
257
- ];
258
- function redactSecretText(value) {
259
- let redacted = value;
260
- for (const { pattern, replacement } of SECRET_TEXT_PATTERNS) {
261
- if (typeof replacement === "string") {
262
- redacted = redacted.replace(pattern, replacement);
263
- } else {
264
- redacted = redacted.replace(pattern, replacement);
265
- }
266
- }
267
- return redacted;
268
- }
269
- function sanitizeDiagnosticText(value) {
270
- return redactSecretText(sanitizePathString(value));
271
- }
272
- var SHAREABILITY_SENSITIVE_PATTERNS = [
273
- /\bC:\/Users\/[^/\s]+/i,
274
- /(?:^|\s)~\/[^\s]+/,
275
- /\b(?:api[_-]?key|secret|token|password|passwd|pwd|client[_-]?secret|access[_-]?key)\b\s*[:=]\s*\S+/i,
276
- /\b(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?\b/i,
277
- /\b(?:10|127)\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,
278
- /\b192\.168\.\d{1,3}\.\d{1,3}\b/,
279
- /\b172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}\b/
280
- ];
281
- function hasShareabilitySensitiveText(text) {
282
- try {
283
- if (sanitizeDiagnosticText(text) !== text)
284
- return true;
285
- return SHAREABILITY_SENSITIVE_PATTERNS.some((pattern) => pattern.test(text));
286
- } catch {
287
- return true;
288
- }
289
- }
290
- function sanitizeConfigValue(value, keyPath = []) {
291
- if (value === null || typeof value === "number" || typeof value === "boolean")
292
- return value;
293
- const key = keyPath.at(-1) ?? "";
294
- if (key && isSecretKey(key)) {
295
- return `<REDACTED:${redactionTypeForKey(key)}>`;
296
- }
297
- if (typeof value === "string")
298
- return sanitizeDiagnosticText(value);
299
- if (Array.isArray(value)) {
300
- return value.map((entry, index) => sanitizeConfigValue(entry, [...keyPath, String(index)]));
301
- }
302
- if (value && typeof value === "object") {
303
- return Object.fromEntries(Object.entries(value).map(([entryKey, entry]) => [
304
- entryKey,
305
- sanitizeConfigValue(entry, [...keyPath, entryKey])
306
- ]));
307
- }
308
- return value;
309
- }
310
-
311
- // ../plugin/src/shared/logger.ts
312
- var isTestEnv = false;
313
- var buffer = [];
314
- var flushTimer = null;
315
- var FLUSH_INTERVAL_MS = 500;
316
- var BUFFER_SIZE_LIMIT = 50;
317
- var MAX_LOG_FILE_BYTES = 32 * 1024 * 1024;
318
- var SIZE_CHECK_INTERVAL_FLUSHES = 64;
319
- var activeLogFile = null;
320
- var activeLogSize = null;
321
- var flushesSinceSizeCheck = 0;
322
- var swallowedWriteCount = 0;
323
- var lastErrorMessage = null;
324
- var lastErrorTime = null;
325
- function recordSwallowedWrite(error) {
326
- try {
327
- swallowedWriteCount++;
328
- lastErrorMessage = sanitizeDiagnosticText(error instanceof Error ? error.message : String(error));
329
- lastErrorTime = new Date().toISOString();
330
- } catch {}
331
- }
332
- function ensureDir(filePath) {
333
- fs.mkdirSync(path2.dirname(filePath), { recursive: true });
334
- }
335
- function isMissingFile(error) {
336
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
337
- }
338
- function getCurrentLogSize(logFile) {
339
- if (activeLogFile === logFile && activeLogSize !== null && flushesSinceSizeCheck < SIZE_CHECK_INTERVAL_FLUSHES) {
340
- return activeLogSize;
341
- }
342
- try {
343
- const stat = fs.statSync(logFile);
344
- if (!stat.isFile()) {
345
- throw new Error(`Magic Context log path is not a regular file: ${logFile}`);
346
- }
347
- fs.chmodSync(logFile, 384);
348
- activeLogFile = logFile;
349
- activeLogSize = stat.size;
350
- flushesSinceSizeCheck = 0;
351
- return stat.size;
352
- } catch (error) {
353
- if (!isMissingFile(error))
354
- throw error;
355
- activeLogFile = logFile;
356
- activeLogSize = 0;
357
- flushesSinceSizeCheck = 0;
358
- return 0;
359
- }
360
- }
361
- function capLogData(data) {
362
- if (Buffer.byteLength(data) <= MAX_LOG_FILE_BYTES)
363
- return data;
364
- let bounded = Buffer.from(data).subarray(0, MAX_LOG_FILE_BYTES).toString("utf8");
365
- while (Buffer.byteLength(bounded) > MAX_LOG_FILE_BYTES) {
366
- bounded = bounded.slice(0, -1);
367
- }
368
- return bounded;
369
- }
370
- function writeBoundedPredecessor(logFile, predecessorPath, size) {
371
- const predecessorFd = fs.openSync(predecessorPath, "w", 384);
372
- try {
373
- fs.fchmodSync(predecessorFd, 384);
374
- const bytesToCopy = Math.min(size, MAX_LOG_FILE_BYTES);
375
- const sourceFd = fs.openSync(logFile, "r");
376
- try {
377
- const chunk = Buffer.allocUnsafe(Math.min(64 * 1024, bytesToCopy));
378
- let remaining = bytesToCopy;
379
- let position = Math.max(0, size - bytesToCopy);
380
- while (remaining > 0) {
381
- const bytesRead = fs.readSync(sourceFd, chunk, 0, Math.min(chunk.length, remaining), position);
382
- if (bytesRead === 0)
383
- break;
384
- fs.writeSync(predecessorFd, chunk, 0, bytesRead);
385
- remaining -= bytesRead;
386
- position += bytesRead;
387
- }
388
- } finally {
389
- fs.closeSync(sourceFd);
390
- }
391
- } finally {
392
- fs.closeSync(predecessorFd);
393
- }
394
- }
395
- function rotateLogFile(logFile, size) {
396
- const predecessorPath = `${logFile}.1`;
397
- writeBoundedPredecessor(logFile, predecessorPath, size);
398
- fs.truncateSync(logFile, 0);
399
- activeLogSize = 0;
400
- flushesSinceSizeCheck = 0;
401
- }
402
- function flush() {
403
- if (flushTimer) {
404
- clearTimeout(flushTimer);
405
- flushTimer = null;
406
- }
407
- if (buffer.length === 0)
408
- return;
409
- const bufferedData = buffer.join("");
410
- buffer = [];
411
- try {
412
- const data = capLogData(bufferedData);
413
- const logFile = getMagicContextLogPath();
414
- ensureDir(logFile);
415
- let currentSize = getCurrentLogSize(logFile);
416
- const dataSize = Buffer.byteLength(data);
417
- if (currentSize > 0 && currentSize + dataSize > MAX_LOG_FILE_BYTES) {
418
- rotateLogFile(logFile, currentSize);
419
- currentSize = 0;
420
- }
421
- fs.appendFileSync(logFile, data, { encoding: "utf8", mode: 384 });
422
- activeLogFile = logFile;
423
- activeLogSize = currentSize + dataSize;
424
- flushesSinceSizeCheck++;
425
- } catch (error) {
426
- activeLogFile = null;
427
- activeLogSize = null;
428
- flushesSinceSizeCheck = 0;
429
- recordSwallowedWrite(error);
430
- }
431
- }
432
- function scheduleFlush() {
433
- if (flushTimer)
434
- return;
435
- flushTimer = setTimeout(() => {
436
- flushTimer = null;
437
- flush();
438
- }, FLUSH_INTERVAL_MS);
439
- }
440
- function log(message, data) {
441
- if (isTestEnv)
442
- return;
443
- try {
444
- const timestamp = new Date().toISOString();
445
- const serialized = data === undefined ? "" : data instanceof Error ? ` ${sanitizeDiagnosticText(`${data.message}${data.stack ? `
446
- ${data.stack}` : ""}`)}` : ` ${JSON.stringify(sanitizeConfigValue(data))}`;
447
- buffer.push(`[${timestamp}] ${sanitizeDiagnosticText(message)}${serialized}
448
- `);
449
- if (buffer.length >= BUFFER_SIZE_LIMIT) {
450
- flush();
451
- } else {
452
- scheduleFlush();
453
- }
454
- } catch {}
455
- }
456
- function sessionLog(sessionId, message, data) {
457
- log(`[magic-context][${sessionId}] ${message}`, data);
458
- }
459
- function flushLogger() {
460
- flush();
461
- }
462
- if (!isTestEnv) {
463
- process.on("exit", flush);
464
- }
465
-
466
- export { sanitizeDiagnosticText, hasShareabilitySensitiveText, setHarness, getHarness, getDataDir, ensureCortexKitArtifactGitignore, getProjectMagicContextHistorianDir, getMagicContextStorageResolution, getMagicContextStorageDir, getLegacyOpenCodeMagicContextStorageDir, log, sessionLog, flushLogger };
@@ -1,76 +0,0 @@
1
- // ../plugin/src/shared/prompt-context.ts
2
- function isRecord(value) {
3
- return typeof value === "object" && value !== null;
4
- }
5
- function extractMessages(response) {
6
- if (Array.isArray(response))
7
- return response;
8
- if (isRecord(response) && Array.isArray(response.data))
9
- return response.data;
10
- return [];
11
- }
12
- function extractFromMessage(message) {
13
- if (!isRecord(message) || !isRecord(message.info))
14
- return null;
15
- const info = message.info;
16
- const modelInfo = isRecord(info.model) ? info.model : undefined;
17
- const agent = typeof info.agent === "string" ? info.agent : undefined;
18
- const providerID = typeof modelInfo?.providerID === "string" ? modelInfo.providerID : typeof info.providerID === "string" ? info.providerID : undefined;
19
- const modelID = typeof modelInfo?.modelID === "string" ? modelInfo.modelID : typeof info.modelID === "string" ? info.modelID : undefined;
20
- const variant = typeof modelInfo?.variant === "string" ? modelInfo.variant : typeof info.variant === "string" ? info.variant : undefined;
21
- if (!agent && (!providerID || !modelID) && !variant)
22
- return null;
23
- const out = {};
24
- if (agent)
25
- out.agent = agent;
26
- if (providerID && modelID)
27
- out.model = { providerID, modelID };
28
- if (variant)
29
- out.variant = variant;
30
- return out;
31
- }
32
- function mergeContexts(base, patch) {
33
- return {
34
- agent: base.agent ?? patch.agent,
35
- model: base.model ?? patch.model,
36
- variant: base.variant ?? patch.variant
37
- };
38
- }
39
- function isComplete(ctx) {
40
- return Boolean(ctx.agent && ctx.model && ctx.variant);
41
- }
42
- var PROMPT_CONTEXT_MESSAGE_LIMIT = 50;
43
- async function resolvePromptContext(client, sessionId) {
44
- if (!client || !sessionId)
45
- return null;
46
- const c = client;
47
- if (typeof c.session?.messages !== "function")
48
- return null;
49
- let messages = [];
50
- try {
51
- const response = await c.session.messages({
52
- path: { id: sessionId },
53
- query: { limit: PROMPT_CONTEXT_MESSAGE_LIMIT }
54
- });
55
- messages = extractMessages(response);
56
- } catch {
57
- return null;
58
- }
59
- if (messages.length === 0)
60
- return null;
61
- let result = {};
62
- for (let i = messages.length - 1;i >= 0; i -= 1) {
63
- const ctx = extractFromMessage(messages[i]);
64
- if (!ctx)
65
- continue;
66
- result = mergeContexts(result, ctx);
67
- if (isComplete(result))
68
- return result;
69
- }
70
- if (!result.agent && !result.model && !result.variant)
71
- return null;
72
- return result;
73
- }
74
- export {
75
- resolvePromptContext
76
- };
@@ -1,41 +0,0 @@
1
- import {
2
- log
3
- } from "./index-147qn1yq.js";
4
-
5
- // ../plugin/src/shared/safe-notification-target.ts
6
- var DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
7
- function isDefaultSessionTitle(title) {
8
- return DEFAULT_TITLE_RE.test(title);
9
- }
10
- async function readSessionTitle(client, sessionId) {
11
- try {
12
- const c = client;
13
- if (typeof c.session?.get !== "function")
14
- return null;
15
- const raw = await Promise.resolve(c.session.get({ path: { id: sessionId } }));
16
- const obj = raw;
17
- const title = obj && typeof obj === "object" ? obj.data?.title ?? obj.title : undefined;
18
- return typeof title === "string" ? title : null;
19
- } catch {
20
- return null;
21
- }
22
- }
23
- async function waitForSafeNotificationTarget(client, sessionId, options) {
24
- const attempts = Math.max(1, options?.attempts ?? 4);
25
- const delayMs = options?.delayMs ?? 15000;
26
- for (let attempt = 0;attempt < attempts; attempt += 1) {
27
- const title = await readSessionTitle(client, sessionId);
28
- if (title === null)
29
- return "safe";
30
- if (!isDefaultSessionTitle(title))
31
- return "safe";
32
- if (attempt < attempts - 1) {
33
- await new Promise((resolve) => setTimeout(resolve, delayMs));
34
- }
35
- }
36
- log(`[magic-context] notification skipped: session ${sessionId} still has its default title (would suppress title generation); will retry on a later startup`);
37
- return "skip";
38
- }
39
- export {
40
- waitForSafeNotificationTarget
41
- };