@frostbridge/imdl 0.1.7 → 0.1.9
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/dist/index.js +149 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2688,7 +2688,7 @@ function resumeCommand() {
|
|
|
2688
2688
|
import pc6 from "picocolors";
|
|
2689
2689
|
|
|
2690
2690
|
// src/adapters/index.ts
|
|
2691
|
-
import { existsSync as existsSync18, readFileSync as
|
|
2691
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
2692
2692
|
import { join as join17 } from "path";
|
|
2693
2693
|
|
|
2694
2694
|
// src/transport/buffer.ts
|
|
@@ -3197,7 +3197,7 @@ var ClaudeCodeAdapter = class {
|
|
|
3197
3197
|
};
|
|
3198
3198
|
|
|
3199
3199
|
// src/adapters/cursor.ts
|
|
3200
|
-
import { existsSync as existsSync17, readdirSync as readdirSync4, statSync as statSync9 } from "fs";
|
|
3200
|
+
import { existsSync as existsSync17, readdirSync as readdirSync4, readFileSync as readFileSync12, statSync as statSync9 } from "fs";
|
|
3201
3201
|
import { join as join16 } from "path";
|
|
3202
3202
|
import { homedir as homedir13 } from "os";
|
|
3203
3203
|
import { createRequire } from "module";
|
|
@@ -3579,6 +3579,97 @@ var CursorAdapter = class _CursorAdapter {
|
|
|
3579
3579
|
}
|
|
3580
3580
|
return `cursor-${parts[parts.length - 2] || "unknown"}`;
|
|
3581
3581
|
}
|
|
3582
|
+
/**
|
|
3583
|
+
* Scan Cursor's agent-transcripts JSONL files (real-time, like Claude Code).
|
|
3584
|
+
* Path: ~/.cursor/projects/{project}/agent-transcripts/{session}/{session}.jsonl
|
|
3585
|
+
* Uses offsets to only read new lines since last scan.
|
|
3586
|
+
*/
|
|
3587
|
+
extractFromTranscripts(since, offsets) {
|
|
3588
|
+
const projectsDir = join16(homedir13(), ".cursor", "projects");
|
|
3589
|
+
if (!existsSync17(projectsDir)) return { events: [], newOffsets: offsets };
|
|
3590
|
+
const events = [];
|
|
3591
|
+
const newOffsets = { ...offsets };
|
|
3592
|
+
try {
|
|
3593
|
+
const projects = readdirSync4(projectsDir);
|
|
3594
|
+
for (const proj of projects) {
|
|
3595
|
+
const transcriptsDir = join16(projectsDir, proj, "agent-transcripts");
|
|
3596
|
+
if (!existsSync17(transcriptsDir)) continue;
|
|
3597
|
+
let sessionDirs;
|
|
3598
|
+
try {
|
|
3599
|
+
sessionDirs = readdirSync4(transcriptsDir);
|
|
3600
|
+
} catch {
|
|
3601
|
+
continue;
|
|
3602
|
+
}
|
|
3603
|
+
for (const sessionDir of sessionDirs) {
|
|
3604
|
+
const jsonlPath = join16(transcriptsDir, sessionDir, `${sessionDir}.jsonl`);
|
|
3605
|
+
if (!existsSync17(jsonlPath)) continue;
|
|
3606
|
+
if (since) {
|
|
3607
|
+
try {
|
|
3608
|
+
const stat = statSync9(jsonlPath);
|
|
3609
|
+
if (stat.mtimeMs < since.getTime()) continue;
|
|
3610
|
+
} catch {
|
|
3611
|
+
continue;
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3614
|
+
try {
|
|
3615
|
+
const content = readFileSync12(jsonlPath, "utf-8");
|
|
3616
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
3617
|
+
const lastOffset = offsets[jsonlPath] || 0;
|
|
3618
|
+
if (lines.length <= lastOffset) continue;
|
|
3619
|
+
const newLines = lines.slice(lastOffset);
|
|
3620
|
+
newOffsets[jsonlPath] = lines.length;
|
|
3621
|
+
const projectPath = "/" + proj.replace(/-/g, "/").replace(/^\//, "");
|
|
3622
|
+
const sid = `cursor-${sessionDir.slice(0, 8)}`;
|
|
3623
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3624
|
+
for (const line of newLines) {
|
|
3625
|
+
let entry;
|
|
3626
|
+
try {
|
|
3627
|
+
entry = JSON.parse(line);
|
|
3628
|
+
} catch {
|
|
3629
|
+
continue;
|
|
3630
|
+
}
|
|
3631
|
+
const content2 = entry.message?.content;
|
|
3632
|
+
if (!Array.isArray(content2)) continue;
|
|
3633
|
+
if (entry.role === "user") {
|
|
3634
|
+
let text = "";
|
|
3635
|
+
for (const block of content2) {
|
|
3636
|
+
if (block?.type === "text" && block.text) {
|
|
3637
|
+
text += block.text.replace(/<user_query>\n?/g, "").replace(/\n?<\/user_query>/g, "").trim();
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
if (!text || this.isNoisePrompt(text)) continue;
|
|
3641
|
+
events.push({
|
|
3642
|
+
sessionId: sid,
|
|
3643
|
+
type: "user_prompt",
|
|
3644
|
+
prompt: text.slice(0, 1e4),
|
|
3645
|
+
timestamp: now,
|
|
3646
|
+
cwd: projectPath,
|
|
3647
|
+
agentType: "cursor"
|
|
3648
|
+
});
|
|
3649
|
+
} else if (entry.role === "assistant") {
|
|
3650
|
+
for (const block of content2) {
|
|
3651
|
+
if (block?.type === "tool_use" && block.name) {
|
|
3652
|
+
events.push({
|
|
3653
|
+
sessionId: sid,
|
|
3654
|
+
type: "pre_tool_use",
|
|
3655
|
+
toolName: block.name,
|
|
3656
|
+
toolInput: block.input || void 0,
|
|
3657
|
+
timestamp: now,
|
|
3658
|
+
cwd: projectPath,
|
|
3659
|
+
agentType: "cursor"
|
|
3660
|
+
});
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
} catch {
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
} catch {
|
|
3670
|
+
}
|
|
3671
|
+
return { events, newOffsets };
|
|
3672
|
+
}
|
|
3582
3673
|
/**
|
|
3583
3674
|
* Returns the workspace storage path for Cursor, or null if not found.
|
|
3584
3675
|
*/
|
|
@@ -3610,6 +3701,13 @@ var CursorAdapter = class _CursorAdapter {
|
|
|
3610
3701
|
return [];
|
|
3611
3702
|
}
|
|
3612
3703
|
}
|
|
3704
|
+
/**
|
|
3705
|
+
* Returns the Cursor projects directory for transcript scanning.
|
|
3706
|
+
*/
|
|
3707
|
+
static getProjectsDir() {
|
|
3708
|
+
const dir = join16(homedir13(), ".cursor", "projects");
|
|
3709
|
+
return existsSync17(dir) ? dir : null;
|
|
3710
|
+
}
|
|
3613
3711
|
};
|
|
3614
3712
|
|
|
3615
3713
|
// src/adapters/index.ts
|
|
@@ -3617,7 +3715,7 @@ var STATE_FILE = join17(getImdlDir(), "adapter-state.json");
|
|
|
3617
3715
|
function loadState() {
|
|
3618
3716
|
try {
|
|
3619
3717
|
if (existsSync18(STATE_FILE)) {
|
|
3620
|
-
return JSON.parse(
|
|
3718
|
+
return JSON.parse(readFileSync13(STATE_FILE, "utf-8"));
|
|
3621
3719
|
}
|
|
3622
3720
|
} catch {
|
|
3623
3721
|
}
|
|
@@ -3698,9 +3796,38 @@ async function collectPrompts() {
|
|
|
3698
3796
|
}
|
|
3699
3797
|
}
|
|
3700
3798
|
}
|
|
3799
|
+
const cursorAdapter = new CursorAdapter();
|
|
3800
|
+
if (CursorAdapter.getProjectsDir()) {
|
|
3801
|
+
try {
|
|
3802
|
+
const { events: transcriptEvents, newOffsets } = cursorAdapter.extractFromTranscripts(new Date(state.lastRun), state.offsets);
|
|
3803
|
+
state.offsets = newOffsets;
|
|
3804
|
+
for (const event of transcriptEvents) {
|
|
3805
|
+
let violation;
|
|
3806
|
+
if (event.prompt) {
|
|
3807
|
+
const scan = scanPromptForSecrets(event.prompt);
|
|
3808
|
+
if (scan.hasSecrets) {
|
|
3809
|
+
violation = createPromptViolation(scan.findings);
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
const buffered = {
|
|
3813
|
+
sessionId: event.sessionId,
|
|
3814
|
+
type: event.type,
|
|
3815
|
+
toolName: event.toolName,
|
|
3816
|
+
toolInput: event.toolInput ? redactObject(event.toolInput) : void 0,
|
|
3817
|
+
prompt: event.prompt ? redactObject(event.prompt) : void 0,
|
|
3818
|
+
timestamp: event.timestamp,
|
|
3819
|
+
cwd: event.cwd,
|
|
3820
|
+
agentType: "cursor",
|
|
3821
|
+
violation
|
|
3822
|
+
};
|
|
3823
|
+
appendEvent(buffered);
|
|
3824
|
+
collected++;
|
|
3825
|
+
}
|
|
3826
|
+
} catch {
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3701
3829
|
const cursorWorkspaces = CursorAdapter.getAllWorkspaces();
|
|
3702
3830
|
if (cursorWorkspaces.length > 0) {
|
|
3703
|
-
const cursorAdapter = new CursorAdapter();
|
|
3704
3831
|
for (const ws of cursorWorkspaces) {
|
|
3705
3832
|
try {
|
|
3706
3833
|
const events = await cursorAdapter.extractEvents({
|
|
@@ -3758,7 +3885,7 @@ async function collectCommand() {
|
|
|
3758
3885
|
|
|
3759
3886
|
// src/commands/daemon.ts
|
|
3760
3887
|
import pc7 from "picocolors";
|
|
3761
|
-
import { existsSync as existsSync19, readFileSync as
|
|
3888
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
|
|
3762
3889
|
import { join as join18 } from "path";
|
|
3763
3890
|
var INTERVAL_MS = 3e4;
|
|
3764
3891
|
async function daemonCommand() {
|
|
@@ -3783,7 +3910,7 @@ async function daemonCommand() {
|
|
|
3783
3910
|
async function ingestShellEvents() {
|
|
3784
3911
|
const shellLog = join18(getBufferDir(), "shell-events.ndjson");
|
|
3785
3912
|
if (!existsSync19(shellLog)) return 0;
|
|
3786
|
-
const content =
|
|
3913
|
+
const content = readFileSync14(shellLog, "utf-8").trim();
|
|
3787
3914
|
if (!content) return 0;
|
|
3788
3915
|
const config = loadConfig();
|
|
3789
3916
|
const lines = content.split("\n");
|
|
@@ -3888,7 +4015,7 @@ async function requestCommand(options) {
|
|
|
3888
4015
|
// src/commands/lock.ts
|
|
3889
4016
|
import pc9 from "picocolors";
|
|
3890
4017
|
import { createHash as createHash2 } from "crypto";
|
|
3891
|
-
import { readFileSync as
|
|
4018
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, existsSync as existsSync20 } from "fs";
|
|
3892
4019
|
import { join as join19, resolve as resolve3 } from "path";
|
|
3893
4020
|
var LOCKFILE_NAME = "mcp-lock.json";
|
|
3894
4021
|
function computeIntegrity(server, identity) {
|
|
@@ -3986,7 +4113,7 @@ async function verifyCommand(options) {
|
|
|
3986
4113
|
}
|
|
3987
4114
|
let lockfile;
|
|
3988
4115
|
try {
|
|
3989
|
-
lockfile = JSON.parse(
|
|
4116
|
+
lockfile = JSON.parse(readFileSync15(lockPath, "utf-8"));
|
|
3990
4117
|
} catch {
|
|
3991
4118
|
console.log(pc9.red("Failed to parse lockfile."));
|
|
3992
4119
|
process.exit(1);
|
|
@@ -4395,7 +4522,7 @@ async function checkCompliance(developerId) {
|
|
|
4395
4522
|
}
|
|
4396
4523
|
|
|
4397
4524
|
// src/permissions/fixer.ts
|
|
4398
|
-
import { existsSync as existsSync21, readFileSync as
|
|
4525
|
+
import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "fs";
|
|
4399
4526
|
import { join as join20 } from "path";
|
|
4400
4527
|
import { homedir as homedir14 } from "os";
|
|
4401
4528
|
function buildFixesFromChanges(changes) {
|
|
@@ -4413,7 +4540,7 @@ function buildFixForAgent(change, home) {
|
|
|
4413
4540
|
const configPath = join20(home, ".claude", "settings.json");
|
|
4414
4541
|
if (!existsSync21(configPath)) return null;
|
|
4415
4542
|
try {
|
|
4416
|
-
const settings = JSON.parse(
|
|
4543
|
+
const settings = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
4417
4544
|
const tools = settings.allowedTools || [];
|
|
4418
4545
|
if (category === "shell") {
|
|
4419
4546
|
if (!tools.includes("Bash") && !tools.some((t) => t.startsWith("Bash("))) return null;
|
|
@@ -4444,7 +4571,7 @@ function buildFixForAgent(change, home) {
|
|
|
4444
4571
|
const configPath = join20(home, ".cursor", "settings.json");
|
|
4445
4572
|
if (!existsSync21(configPath)) return null;
|
|
4446
4573
|
try {
|
|
4447
|
-
const settings = JSON.parse(
|
|
4574
|
+
const settings = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
4448
4575
|
if ((category === "agentic_mode" || category === "shell") && settings["cursor.composer.yoloMode"] === true) {
|
|
4449
4576
|
return { agentType, category: "agentic_mode", currentGrant: "unrestricted", newGrant: "confirmation", configPath, description: "Disable YOLO mode" };
|
|
4450
4577
|
}
|
|
@@ -4456,7 +4583,7 @@ function buildFixForAgent(change, home) {
|
|
|
4456
4583
|
const configPath = join20(home, ".codex", "config.json");
|
|
4457
4584
|
if (!existsSync21(configPath)) return null;
|
|
4458
4585
|
try {
|
|
4459
|
-
const config = JSON.parse(
|
|
4586
|
+
const config = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
4460
4587
|
if ((category === "agentic_mode" || category === "shell") && config.sandbox_mode === "full_auto") {
|
|
4461
4588
|
return { agentType, category: "agentic_mode", currentGrant: "unrestricted", newGrant: "confirmation", configPath, description: "Switch to supervised mode" };
|
|
4462
4589
|
}
|
|
@@ -4468,7 +4595,7 @@ function buildFixForAgent(change, home) {
|
|
|
4468
4595
|
const configPath = join20(home, "Library", "Application Support", "Code", "User", "settings.json");
|
|
4469
4596
|
if (!existsSync21(configPath)) return null;
|
|
4470
4597
|
try {
|
|
4471
|
-
const settings = JSON.parse(
|
|
4598
|
+
const settings = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
4472
4599
|
if ((category === "agentic_mode" || category === "shell") && (settings["github.copilot.chat.agent.autoApprove"] || settings["chat.agent.autoApprove"])) {
|
|
4473
4600
|
return { agentType, category: "agentic_mode", currentGrant: "unrestricted", newGrant: "confirmation", configPath, description: "Disable autoApprove" };
|
|
4474
4601
|
}
|
|
@@ -4481,7 +4608,7 @@ function buildFixForAgent(change, home) {
|
|
|
4481
4608
|
const configPath = join20(home, ".windsurf", "mcp.json");
|
|
4482
4609
|
if (!existsSync21(configPath)) return null;
|
|
4483
4610
|
try {
|
|
4484
|
-
const config = JSON.parse(
|
|
4611
|
+
const config = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
4485
4612
|
const servers = Object.keys(config.mcpServers || {});
|
|
4486
4613
|
if (servers.length === 0) return null;
|
|
4487
4614
|
return { agentType, category, currentGrant: "unrestricted", newGrant: "denied", configPath, description: `Remove MCP servers (${servers.join(", ")})` };
|
|
@@ -4494,7 +4621,7 @@ function buildFixForAgent(change, home) {
|
|
|
4494
4621
|
}
|
|
4495
4622
|
function applyFix(fix) {
|
|
4496
4623
|
try {
|
|
4497
|
-
const content =
|
|
4624
|
+
const content = readFileSync16(fix.configPath, "utf-8");
|
|
4498
4625
|
const config = JSON.parse(content);
|
|
4499
4626
|
let modified = false;
|
|
4500
4627
|
if (fix.agentType === "claude-code") {
|
|
@@ -4785,7 +4912,7 @@ function grantLevel(grant) {
|
|
|
4785
4912
|
|
|
4786
4913
|
// src/commands/gateway.ts
|
|
4787
4914
|
import pc12 from "picocolors";
|
|
4788
|
-
import { existsSync as existsSync22, readFileSync as
|
|
4915
|
+
import { existsSync as existsSync22, readFileSync as readFileSync17, writeFileSync as writeFileSync10, mkdirSync as mkdirSync3 } from "fs";
|
|
4789
4916
|
import { join as join21 } from "path";
|
|
4790
4917
|
import { homedir as homedir15 } from "os";
|
|
4791
4918
|
import { execSync as execSync2, spawn } from "child_process";
|
|
@@ -4931,7 +5058,7 @@ async function gatewayAlertsCommand(opts) {
|
|
|
4931
5058
|
console.log(pc12.dim("No alerts logged yet."));
|
|
4932
5059
|
return;
|
|
4933
5060
|
}
|
|
4934
|
-
const lines =
|
|
5061
|
+
const lines = readFileSync17(logPath, "utf-8").split("\n").filter(Boolean);
|
|
4935
5062
|
const limit = opts.limit ? parseInt(opts.limit, 10) : 20;
|
|
4936
5063
|
const recent = lines.slice(-limit);
|
|
4937
5064
|
if (opts.json) {
|
|
@@ -5035,7 +5162,7 @@ async function getGatewayStatus() {
|
|
|
5035
5162
|
function getRunningPid() {
|
|
5036
5163
|
if (!existsSync22(GATEWAY_PID_FILE)) return null;
|
|
5037
5164
|
try {
|
|
5038
|
-
const pid = parseInt(
|
|
5165
|
+
const pid = parseInt(readFileSync17(GATEWAY_PID_FILE, "utf-8").trim(), 10);
|
|
5039
5166
|
return isNaN(pid) ? null : pid;
|
|
5040
5167
|
} catch {
|
|
5041
5168
|
return null;
|
|
@@ -5052,7 +5179,7 @@ function isProcessAlive(pid) {
|
|
|
5052
5179
|
function getConfiguredPort() {
|
|
5053
5180
|
if (!existsSync22(GATEWAY_CONFIG)) return DEFAULT_PORT;
|
|
5054
5181
|
try {
|
|
5055
|
-
const content =
|
|
5182
|
+
const content = readFileSync17(GATEWAY_CONFIG, "utf-8");
|
|
5056
5183
|
const match = content.match(/listen_port\s*=\s*(\d+)/);
|
|
5057
5184
|
return match ? parseInt(match[1], 10) : DEFAULT_PORT;
|
|
5058
5185
|
} catch {
|
|
@@ -5124,7 +5251,7 @@ function loadGatewayToml() {
|
|
|
5124
5251
|
if (!existsSync22(GATEWAY_CONFIG)) {
|
|
5125
5252
|
ensureConfig(DEFAULT_PORT);
|
|
5126
5253
|
}
|
|
5127
|
-
return
|
|
5254
|
+
return readFileSync17(GATEWAY_CONFIG, "utf-8");
|
|
5128
5255
|
}
|
|
5129
5256
|
function saveGatewayToml(content) {
|
|
5130
5257
|
writeFileSync10(GATEWAY_CONFIG, content, { mode: 384 });
|
|
@@ -5457,7 +5584,7 @@ function ruleTypeToCategory(type) {
|
|
|
5457
5584
|
}
|
|
5458
5585
|
|
|
5459
5586
|
// src/transport/sync.ts
|
|
5460
|
-
import { readFileSync as
|
|
5587
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync23 } from "fs";
|
|
5461
5588
|
import { join as join22 } from "path";
|
|
5462
5589
|
var SYNC_INTERVAL = 6e4;
|
|
5463
5590
|
var SYNC_TIMEOUT = 3e3;
|
|
@@ -5468,7 +5595,7 @@ function getLastSyncTime() {
|
|
|
5468
5595
|
try {
|
|
5469
5596
|
const file = getSyncStateFile();
|
|
5470
5597
|
if (existsSync23(file)) {
|
|
5471
|
-
const data = JSON.parse(
|
|
5598
|
+
const data = JSON.parse(readFileSync18(file, "utf-8"));
|
|
5472
5599
|
return data.lastSync || 0;
|
|
5473
5600
|
}
|
|
5474
5601
|
} catch {
|