@prestyj/cli 5.32.0 → 5.32.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/README.md +3 -2
- package/assets/skills/task-list/SKILL.md +39 -0
- package/dist/app-sidecar/app-settings.js +11 -5
- package/dist/app-sidecar/app-settings.js.map +1 -1
- package/dist/app-sidecar/auth-routes.js +10 -3
- package/dist/app-sidecar/auth-routes.js.map +1 -1
- package/dist/app-sidecar/git-target.d.ts +15 -2
- package/dist/app-sidecar/git-target.js +24 -10
- package/dist/app-sidecar/git-target.js.map +1 -1
- package/dist/app-sidecar/goal-routes.js +8 -0
- package/dist/app-sidecar/goal-routes.js.map +1 -1
- package/dist/app-sidecar/history-routes.js +7 -0
- package/dist/app-sidecar/history-routes.js.map +1 -1
- package/dist/app-sidecar/history.d.ts +5 -0
- package/dist/app-sidecar/history.js.map +1 -1
- package/dist/app-sidecar/integration-routes.js +4 -0
- package/dist/app-sidecar/integration-routes.js.map +1 -1
- package/dist/app-sidecar/mcp-routes.js +1 -0
- package/dist/app-sidecar/mcp-routes.js.map +1 -1
- package/dist/app-sidecar/mcp-rows.d.ts +2 -0
- package/dist/app-sidecar/mcp-rows.js +4 -1
- package/dist/app-sidecar/mcp-rows.js.map +1 -1
- package/dist/app-sidecar/prompt-routes.js +67 -1
- package/dist/app-sidecar/prompt-routes.js.map +1 -1
- package/dist/app-sidecar/route-context.d.ts +2 -0
- package/dist/app-sidecar/run-control-routes.js +43 -3
- package/dist/app-sidecar/run-control-routes.js.map +1 -1
- package/dist/app-sidecar/session-routes.js +10 -0
- package/dist/app-sidecar/session-routes.js.map +1 -1
- package/dist/app-sidecar/task-routes.js +2 -0
- package/dist/app-sidecar/task-routes.js.map +1 -1
- package/dist/app-sidecar/trophy-manager.d.ts +15 -0
- package/dist/app-sidecar/trophy-manager.js +71 -0
- package/dist/app-sidecar/trophy-manager.js.map +1 -0
- package/dist/app-sidecar/workspace-routes.js +1 -0
- package/dist/app-sidecar/workspace-routes.js.map +1 -1
- package/dist/app-sidecar.js +157 -30
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli/auth.js +22 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/mcp.js +6 -1
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli.js +13 -9
- package/dist/cli.js.map +1 -1
- package/dist/config.js +4 -2
- package/dist/config.js.map +1 -1
- package/dist/core/action-threats.d.ts +68 -0
- package/dist/core/action-threats.js +894 -0
- package/dist/core/action-threats.js.map +1 -0
- package/dist/core/agent-notifications.d.ts +18 -0
- package/dist/core/agent-notifications.js +35 -2
- package/dist/core/agent-notifications.js.map +1 -1
- package/dist/core/agent-session/verification-tracker.d.ts +21 -0
- package/dist/core/agent-session/verification-tracker.js +39 -1
- package/dist/core/agent-session/verification-tracker.js.map +1 -1
- package/dist/core/agent-session.d.ts +168 -2
- package/dist/core/agent-session.js +486 -23
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/blocked-packages-file.d.ts +33 -0
- package/dist/core/blocked-packages-file.js +274 -0
- package/dist/core/blocked-packages-file.js.map +1 -0
- package/dist/core/compaction/policy.d.ts +2 -2
- package/dist/core/compaction/policy.js +86 -43
- package/dist/core/compaction/policy.js.map +1 -1
- package/dist/core/compaction/token-estimator.d.ts +4 -1
- package/dist/core/compaction/token-estimator.js +5 -2
- package/dist/core/compaction/token-estimator.js.map +1 -1
- package/dist/core/event-bus.d.ts +10 -0
- package/dist/core/event-bus.js +2 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/idle-wake.d.ts +62 -0
- package/dist/core/idle-wake.js +103 -0
- package/dist/core/idle-wake.js.map +1 -0
- package/dist/core/injection-detect.d.ts +2 -1
- package/dist/core/injection-detect.js +13 -4
- package/dist/core/injection-detect.js.map +1 -1
- package/dist/core/installed-threats.d.ts +23 -0
- package/dist/core/installed-threats.js +71 -0
- package/dist/core/installed-threats.js.map +1 -0
- package/dist/core/mcp/catalog-cache.d.ts +2 -0
- package/dist/core/mcp/catalog-cache.js +4 -0
- package/dist/core/mcp/catalog-cache.js.map +1 -1
- package/dist/core/mcp/client.d.ts +8 -0
- package/dist/core/mcp/client.js +37 -3
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/deferred-catalog.d.ts +12 -1
- package/dist/core/mcp/deferred-catalog.js +37 -10
- package/dist/core/mcp/deferred-catalog.js.map +1 -1
- package/dist/core/mcp/index.d.ts +2 -0
- package/dist/core/mcp/index.js +1 -0
- package/dist/core/mcp/index.js.map +1 -1
- package/dist/core/mcp/tool-guard.d.ts +58 -0
- package/dist/core/mcp/tool-guard.js +215 -0
- package/dist/core/mcp/tool-guard.js.map +1 -0
- package/dist/core/network-guard.d.ts +0 -20
- package/dist/core/network-guard.js +6 -0
- package/dist/core/network-guard.js.map +1 -1
- package/dist/core/package-cooldown.d.ts +71 -0
- package/dist/core/package-cooldown.js +301 -0
- package/dist/core/package-cooldown.js.map +1 -0
- package/dist/core/package-threats.d.ts +77 -3
- package/dist/core/package-threats.js +1250 -78
- package/dist/core/package-threats.js.map +1 -1
- package/dist/core/process-manager.d.ts +54 -12
- package/dist/core/process-manager.js +233 -56
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/project-files.d.ts +15 -0
- package/dist/core/project-files.js +37 -0
- package/dist/core/project-files.js.map +1 -0
- package/dist/core/prompt-commands.js +1 -0
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.js +4 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/shell-threats.d.ts +14 -1
- package/dist/core/shell-threats.js +73 -24
- package/dist/core/shell-threats.js.map +1 -1
- package/dist/core/skill-scan.d.ts +112 -0
- package/dist/core/skill-scan.js +781 -0
- package/dist/core/skill-scan.js.map +1 -0
- package/dist/core/skills.d.ts +33 -0
- package/dist/core/skills.js +87 -16
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +5 -1
- package/dist/core/slash-commands.js +24 -9
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/steering.d.ts +7 -0
- package/dist/core/steering.js +13 -0
- package/dist/core/steering.js.map +1 -1
- package/dist/core/style-packs/index.js +1 -1
- package/dist/core/style-packs/index.js.map +1 -1
- package/dist/core/style-packs/packs.js +2 -2
- package/dist/core/subagent-manager.js +5 -4
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/threat-feed.d.ts +65 -0
- package/dist/core/threat-feed.js +335 -0
- package/dist/core/threat-feed.js.map +1 -0
- package/dist/core/trophies/catalog-more.d.ts +2 -0
- package/dist/core/trophies/catalog-more.js +857 -0
- package/dist/core/trophies/catalog-more.js.map +1 -0
- package/dist/core/trophies/catalog.d.ts +4 -0
- package/dist/core/trophies/catalog.js +649 -0
- package/dist/core/trophies/catalog.js.map +1 -0
- package/dist/core/trophies/engine.d.ts +70 -0
- package/dist/core/trophies/engine.js +351 -0
- package/dist/core/trophies/engine.js.map +1 -0
- package/dist/core/trophies/store.d.ts +17 -0
- package/dist/core/trophies/store.js +113 -0
- package/dist/core/trophies/store.js.map +1 -0
- package/dist/core/trophies/types.d.ts +119 -0
- package/dist/core/trophies/types.js +78 -0
- package/dist/core/trophies/types.js.map +1 -0
- package/dist/core/verification-evidence.d.ts +10 -6
- package/dist/core/verification-evidence.js +190 -11
- package/dist/core/verification-evidence.js.map +1 -1
- package/dist/goals-agent/goals-agent.js +3 -2
- package/dist/goals-agent/goals-agent.js.map +1 -1
- package/dist/interactive.js +16 -5
- package/dist/interactive.js.map +1 -1
- package/dist/modes/acp-mode.js +8 -1
- package/dist/modes/acp-mode.js.map +1 -1
- package/dist/modes/agent-home-mode.js +13 -1
- package/dist/modes/agent-home-mode.js.map +1 -1
- package/dist/modes/rpc-mode.d.ts +2 -1
- package/dist/modes/rpc-mode.js +15 -3
- package/dist/modes/rpc-mode.js.map +1 -1
- package/dist/modes/serve-mode.js +13 -1
- package/dist/modes/serve-mode.js.map +1 -1
- package/dist/system-prompt.d.ts +8 -0
- package/dist/system-prompt.js +34 -13
- package/dist/system-prompt.js.map +1 -1
- package/dist/test-support/slow-git.d.ts +1 -0
- package/dist/test-support/slow-git.js +21 -0
- package/dist/test-support/slow-git.js.map +1 -0
- package/dist/tools/background-watch-lint.d.ts +18 -0
- package/dist/tools/background-watch-lint.js +102 -0
- package/dist/tools/background-watch-lint.js.map +1 -0
- package/dist/tools/bash.d.ts +15 -4
- package/dist/tools/bash.js +75 -47
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/checklist.d.ts +3 -3
- package/dist/tools/compress.js +45 -0
- package/dist/tools/compress.js.map +1 -1
- package/dist/tools/edit.js +5 -0
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/generate-image.d.ts +29 -6
- package/dist/tools/generate-image.js +325 -151
- package/dist/tools/generate-image.js.map +1 -1
- package/dist/tools/grep.d.ts +14 -0
- package/dist/tools/grep.js +36 -2
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/index.d.ts +5 -1
- package/dist/tools/index.js +7 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/prompt-hints.d.ts +8 -1
- package/dist/tools/prompt-hints.js +22 -2
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/routine-output.d.ts +30 -0
- package/dist/tools/routine-output.js +203 -0
- package/dist/tools/routine-output.js.map +1 -0
- package/dist/tools/skill.d.ts +2 -2
- package/dist/tools/skill.js +8 -1
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-shared.js +4 -1
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/task-output.js +11 -1
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/write.js +8 -0
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/components/ModelSelector.d.ts +10 -0
- package/dist/ui/components/ModelSelector.js +51 -5
- package/dist/ui/components/ModelSelector.js.map +1 -1
- package/dist/ui/components/ToolExecution.js +2 -2
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/mcp.d.ts +2 -0
- package/dist/ui/mcp.js.map +1 -1
- package/dist/ui/terminal-history.js +2 -1
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/tool-line-summary.js +3 -1
- package/dist/ui/tool-line-summary.js.map +1 -1
- package/dist/utils/git.d.ts +12 -3
- package/dist/utils/git.js +21 -8
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +23 -0
- package/dist/utils/image.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BlockedPackage } from "./shell-threats.js";
|
|
2
|
+
export declare const BLOCKLIST_START = "<!-- ez-safe:blocked-packages:start -->";
|
|
3
|
+
export declare const BLOCKLIST_END = "<!-- ez-safe:blocked-packages:end -->";
|
|
4
|
+
/**
|
|
5
|
+
* Same names and order as the system prompt's CONTEXT_FILES (a test keeps
|
|
6
|
+
* them equal): EZ Coder loads only the first that exists per folder, so the
|
|
7
|
+
* list must go into that one. Creating a CLAUDE.md beside a .cursorrules
|
|
8
|
+
* would outrank it and silently drop the user's own rules.
|
|
9
|
+
*/
|
|
10
|
+
export declare const INSTRUCTION_FILES: readonly ["AGENTS.override.md", "AGENTS.md", "CLAUDE.md", ".cursorrules", "CONVENTIONS.md"];
|
|
11
|
+
/** The instruction file EZ Coder reads in `dir` (CLAUDE.md when there is none yet, as /init). */
|
|
12
|
+
export declare function instructionFileFor(dir: string): Promise<string>;
|
|
13
|
+
/** One list line, or null when anything fails validation. */
|
|
14
|
+
export declare function blocklistLine(pkg: BlockedPackage): string | null;
|
|
15
|
+
/** The text with the managed block set to `entries` (added at the end if missing). */
|
|
16
|
+
export declare function withBlocklist(text: string, entries: string[]): string;
|
|
17
|
+
/** Entries currently in the managed block of `text`. */
|
|
18
|
+
export declare function readBlocklist(text: string): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Only write inside a real project: never the home folder or a filesystem
|
|
21
|
+
* root (a ~/CLAUDE.md would apply to every project), and never a loose folder
|
|
22
|
+
* such as Downloads or a temp dir with no project marker in it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isProjectDir(dir: string, home?: string): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Add `packages` to the project's list in `dir`. Returns the file written, or
|
|
27
|
+
* null when nothing new needed recording (or `dir` isn't a project, or the
|
|
28
|
+
* file is read-only/someone else's: their choice wins). Rejects on I/O
|
|
29
|
+
* failure; callers fire and forget and log it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function recordBlockedPackages(dir: string, packages: readonly BlockedPackage[], options?: {
|
|
32
|
+
home?: string;
|
|
33
|
+
}): Promise<string | null>;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's "don't install" list: when a guard refuses a package, the app
|
|
3
|
+
* (not the agent) records it in the instruction file EZ Coder loads for the
|
|
4
|
+
* project, so every later session knows about it from its first token.
|
|
5
|
+
*
|
|
6
|
+
* One small managed block between markers, appended to the file EZ Coder
|
|
7
|
+
* reads (the first of INSTRUCTION_FILES that exists; CLAUDE.md is created when
|
|
8
|
+
* none does, as /init does). Deduplicated, capped, and nothing but validated package names,
|
|
9
|
+
* versions and our own reason text ever goes in, so the block can't carry
|
|
10
|
+
* injected instructions. Never touched mid-prompt: the running session already
|
|
11
|
+
* knows from the block message, and nothing re-renders the cached prompt.
|
|
12
|
+
*/
|
|
13
|
+
import { constants as fsConstants } from "node:fs";
|
|
14
|
+
import fsp from "node:fs/promises";
|
|
15
|
+
import os from "node:os";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { retryWindowsReplace } from "./session-storage.js";
|
|
18
|
+
export const BLOCKLIST_START = "<!-- ez-safe:blocked-packages:start -->";
|
|
19
|
+
export const BLOCKLIST_END = "<!-- ez-safe:blocked-packages:end -->";
|
|
20
|
+
const HEADER = [
|
|
21
|
+
"## Blocked packages",
|
|
22
|
+
"EZ Coder's safety checks blocked these. Never install or run them; use another version or package.",
|
|
23
|
+
];
|
|
24
|
+
/** Newest entries kept; older ones fall off the top. */
|
|
25
|
+
const MAX_ENTRIES = 30;
|
|
26
|
+
/** Bigger instruction files are left alone (not ours to rewrite). */
|
|
27
|
+
const MAX_FILE_BYTES = 4 * 1024 * 1024;
|
|
28
|
+
/**
|
|
29
|
+
* Same names and order as the system prompt's CONTEXT_FILES (a test keeps
|
|
30
|
+
* them equal): EZ Coder loads only the first that exists per folder, so the
|
|
31
|
+
* list must go into that one. Creating a CLAUDE.md beside a .cursorrules
|
|
32
|
+
* would outrank it and silently drop the user's own rules.
|
|
33
|
+
*/
|
|
34
|
+
export const INSTRUCTION_FILES = [
|
|
35
|
+
"AGENTS.override.md",
|
|
36
|
+
"AGENTS.md",
|
|
37
|
+
"CLAUDE.md",
|
|
38
|
+
".cursorrules",
|
|
39
|
+
"CONVENTIONS.md",
|
|
40
|
+
];
|
|
41
|
+
const NAME = /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/i;
|
|
42
|
+
const VERSION = /^[a-z0-9][a-z0-9.+_-]{0,63}$/i;
|
|
43
|
+
const REASON = /^[\w "(),.:@/-]{1,120}$/;
|
|
44
|
+
/** The instruction file EZ Coder reads in `dir` (CLAUDE.md when there is none yet, as /init). */
|
|
45
|
+
export async function instructionFileFor(dir) {
|
|
46
|
+
for (const name of INSTRUCTION_FILES) {
|
|
47
|
+
const file = path.join(dir, name);
|
|
48
|
+
try {
|
|
49
|
+
if ((await fsp.stat(file)).isFile())
|
|
50
|
+
return file;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Not there: try the next name.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return path.join(dir, "CLAUDE.md");
|
|
57
|
+
}
|
|
58
|
+
/** One list line, or null when anything fails validation. */
|
|
59
|
+
export function blocklistLine(pkg) {
|
|
60
|
+
if (pkg.ecosystem !== "npm" && pkg.ecosystem !== "PyPI")
|
|
61
|
+
return null;
|
|
62
|
+
if (!NAME.test(pkg.name) || (pkg.version !== undefined && !VERSION.test(pkg.version))) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (!REASON.test(pkg.reason))
|
|
66
|
+
return null;
|
|
67
|
+
const id = pkg.version ? `${pkg.name}@${pkg.version}` : pkg.name;
|
|
68
|
+
return `- ${pkg.ecosystem} \`${id}\`: ${pkg.reason}`;
|
|
69
|
+
}
|
|
70
|
+
/** `- npm \`chalk@5.6.1\`: …` → `npm chalk@5.6.1`, the dedupe key. */
|
|
71
|
+
function lineKey(line) {
|
|
72
|
+
return /^- (\S+) `([^`]+)`/.exec(line)?.slice(1, 3).join(" ").toLowerCase() ?? line;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The managed block's span in `text`: the first end marker that has a start
|
|
76
|
+
* marker before it, paired with the nearest such start. A stray start or end
|
|
77
|
+
* marker (hand-edited, half-deleted) never makes us swallow the user's text
|
|
78
|
+
* between it and a real block.
|
|
79
|
+
*/
|
|
80
|
+
function blockSpan(text) {
|
|
81
|
+
let end = text.indexOf(BLOCKLIST_END);
|
|
82
|
+
while (end !== -1) {
|
|
83
|
+
const start = text.lastIndexOf(BLOCKLIST_START, end);
|
|
84
|
+
if (start !== -1)
|
|
85
|
+
return { start, end };
|
|
86
|
+
end = text.indexOf(BLOCKLIST_END, end + BLOCKLIST_END.length);
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/** Lines inside the block that aren't ours (a user's own note): kept as-is. */
|
|
91
|
+
function blockExtras(text) {
|
|
92
|
+
const span = blockSpan(text);
|
|
93
|
+
if (!span)
|
|
94
|
+
return [];
|
|
95
|
+
return text
|
|
96
|
+
.slice(span.start + BLOCKLIST_START.length, span.end)
|
|
97
|
+
.split(/\r?\n/)
|
|
98
|
+
.filter((line) => line.trim() !== "" && !line.startsWith("- ") && !HEADER.includes(line));
|
|
99
|
+
}
|
|
100
|
+
/** The text with the managed block set to `entries` (added at the end if missing). */
|
|
101
|
+
export function withBlocklist(text, entries) {
|
|
102
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
103
|
+
const block = [BLOCKLIST_START, ...HEADER, ...blockExtras(text), ...entries, BLOCKLIST_END].join(eol);
|
|
104
|
+
const span = blockSpan(text);
|
|
105
|
+
if (span) {
|
|
106
|
+
return text.slice(0, span.start) + block + text.slice(span.end + BLOCKLIST_END.length);
|
|
107
|
+
}
|
|
108
|
+
const body = text.replace(/[ \t\r\n]+$/, "");
|
|
109
|
+
return body ? `${body}${eol}${eol}${block}${eol}` : `${block}${eol}`;
|
|
110
|
+
}
|
|
111
|
+
/** Entries currently in the managed block of `text`. */
|
|
112
|
+
export function readBlocklist(text) {
|
|
113
|
+
const span = blockSpan(text);
|
|
114
|
+
if (!span)
|
|
115
|
+
return [];
|
|
116
|
+
return text
|
|
117
|
+
.slice(span.start + BLOCKLIST_START.length, span.end)
|
|
118
|
+
.split(/\r?\n/)
|
|
119
|
+
.filter((line) => line.startsWith("- "));
|
|
120
|
+
}
|
|
121
|
+
/** Files and folders that make `dir` a real project (a worktree's `.git` is a file). */
|
|
122
|
+
const PROJECT_MARKERS = [
|
|
123
|
+
".git",
|
|
124
|
+
"package.json",
|
|
125
|
+
"pyproject.toml",
|
|
126
|
+
"requirements.txt",
|
|
127
|
+
"setup.py",
|
|
128
|
+
"Cargo.toml",
|
|
129
|
+
"go.mod",
|
|
130
|
+
"package-lock.json",
|
|
131
|
+
"pnpm-lock.yaml",
|
|
132
|
+
"yarn.lock",
|
|
133
|
+
"bun.lock",
|
|
134
|
+
"uv.lock",
|
|
135
|
+
...INSTRUCTION_FILES,
|
|
136
|
+
];
|
|
137
|
+
/**
|
|
138
|
+
* Only write inside a real project: never the home folder or a filesystem
|
|
139
|
+
* root (a ~/CLAUDE.md would apply to every project), and never a loose folder
|
|
140
|
+
* such as Downloads or a temp dir with no project marker in it.
|
|
141
|
+
*/
|
|
142
|
+
export async function isProjectDir(dir, home = os.homedir()) {
|
|
143
|
+
const resolved = path.resolve(dir);
|
|
144
|
+
if (path.parse(resolved).root === resolved)
|
|
145
|
+
return false;
|
|
146
|
+
const norm = (p) => (process.platform === "win32" ? p.toLowerCase() : p);
|
|
147
|
+
if (home && norm(path.resolve(home)) === norm(resolved))
|
|
148
|
+
return false;
|
|
149
|
+
const hits = await Promise.all(PROJECT_MARKERS.map((name) => fsp.lstat(path.join(resolved, name)).then(() => true, () => false)));
|
|
150
|
+
return hits.includes(true);
|
|
151
|
+
}
|
|
152
|
+
/** Lockfiles older than this are from a crashed writer and may be taken over. */
|
|
153
|
+
const LOCK_STALE_MS = 10_000;
|
|
154
|
+
const LOCK_WAIT_MS = 3_000;
|
|
155
|
+
/**
|
|
156
|
+
* A cross-process lock beside the file (two GG windows on one project are two
|
|
157
|
+
* sidecars only when they're separate apps; still, never lose an entry or the
|
|
158
|
+
* user's text). Returns the release function, or throws after LOCK_WAIT_MS.
|
|
159
|
+
*/
|
|
160
|
+
async function lockFile(file) {
|
|
161
|
+
const lock = `${file}.ez-lock`;
|
|
162
|
+
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
163
|
+
for (;;) {
|
|
164
|
+
try {
|
|
165
|
+
const handle = await fsp.open(lock, "wx");
|
|
166
|
+
await handle.close();
|
|
167
|
+
return () => fsp.rm(lock, { force: true });
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (err.code !== "EEXIST")
|
|
171
|
+
throw err;
|
|
172
|
+
const st = await fsp.stat(lock).catch(() => null);
|
|
173
|
+
if (st && Date.now() - st.mtimeMs > LOCK_STALE_MS) {
|
|
174
|
+
await fsp.rm(lock, { force: true }).catch(() => { });
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (Date.now() > deadline)
|
|
178
|
+
throw new Error(`${lock} is held by another writer`, { cause: err });
|
|
179
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Read, merge, write atomically; "changed" when the file moved under us. */
|
|
184
|
+
async function writeOnce(file, lines) {
|
|
185
|
+
const before = await fsp.stat(file).catch(() => null);
|
|
186
|
+
const text = before ? await fsp.readFile(file, "utf8") : "";
|
|
187
|
+
const entries = readBlocklist(text);
|
|
188
|
+
const known = new Set(entries.map(lineKey));
|
|
189
|
+
const added = lines.filter((line) => {
|
|
190
|
+
const key = lineKey(line);
|
|
191
|
+
if (known.has(key))
|
|
192
|
+
return false;
|
|
193
|
+
known.add(key);
|
|
194
|
+
return true;
|
|
195
|
+
});
|
|
196
|
+
if (added.length === 0)
|
|
197
|
+
return null;
|
|
198
|
+
const next = withBlocklist(text, [...entries, ...added].slice(-MAX_ENTRIES));
|
|
199
|
+
const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
200
|
+
try {
|
|
201
|
+
await fsp.writeFile(tmp, next, {
|
|
202
|
+
encoding: "utf8",
|
|
203
|
+
mode: before ? before.mode & 0o777 : 0o644,
|
|
204
|
+
});
|
|
205
|
+
const now = await fsp.stat(file).catch(() => null);
|
|
206
|
+
if (now?.mtimeMs !== before?.mtimeMs || now?.size !== before?.size) {
|
|
207
|
+
await fsp.rm(tmp, { force: true });
|
|
208
|
+
return "changed";
|
|
209
|
+
}
|
|
210
|
+
await retryWindowsReplace(() => fsp.rename(tmp, file));
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
await fsp.rm(tmp, { force: true }).catch(() => { });
|
|
214
|
+
throw err;
|
|
215
|
+
}
|
|
216
|
+
return file;
|
|
217
|
+
}
|
|
218
|
+
/** One write at a time per file, so concurrent blocks never lose an entry. */
|
|
219
|
+
const queues = new Map();
|
|
220
|
+
/**
|
|
221
|
+
* Add `packages` to the project's list in `dir`. Returns the file written, or
|
|
222
|
+
* null when nothing new needed recording (or `dir` isn't a project, or the
|
|
223
|
+
* file is read-only/someone else's: their choice wins). Rejects on I/O
|
|
224
|
+
* failure; callers fire and forget and log it.
|
|
225
|
+
*/
|
|
226
|
+
export async function recordBlockedPackages(dir, packages, options = {}) {
|
|
227
|
+
const lines = packages.map(blocklistLine).filter((l) => l !== null);
|
|
228
|
+
if (lines.length === 0)
|
|
229
|
+
return null;
|
|
230
|
+
if (!(await isProjectDir(dir, options.home)))
|
|
231
|
+
return null;
|
|
232
|
+
let file = await instructionFileFor(dir);
|
|
233
|
+
// A symlinked CLAUDE.md -> AGENTS.md: write through to the real file, never
|
|
234
|
+
// replace the link with a regular file.
|
|
235
|
+
const link = await fsp.lstat(file).catch(() => null);
|
|
236
|
+
if (link?.isSymbolicLink())
|
|
237
|
+
file = await fsp.realpath(file).catch(() => file);
|
|
238
|
+
const run = async () => {
|
|
239
|
+
const first = await fsp.stat(file).catch(() => null);
|
|
240
|
+
if (first) {
|
|
241
|
+
if (!first.isFile() || first.size > MAX_FILE_BYTES)
|
|
242
|
+
return null;
|
|
243
|
+
// Read-only or owned by someone else: leave it alone (a rename would
|
|
244
|
+
// silently replace it).
|
|
245
|
+
const writable = await fsp.access(file, fsConstants.W_OK).then(() => true, () => false);
|
|
246
|
+
if (!writable)
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
const release = await lockFile(file);
|
|
250
|
+
try {
|
|
251
|
+
// An editor saving mid-write: re-read and try again, never clobber it.
|
|
252
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
253
|
+
const result = await writeOnce(file, lines);
|
|
254
|
+
if (result !== "changed")
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
await release().catch(() => { });
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const prev = queues.get(file) ?? Promise.resolve();
|
|
264
|
+
const next = prev.then(run, run);
|
|
265
|
+
const settled = next.catch(() => null);
|
|
266
|
+
queues.set(file, settled);
|
|
267
|
+
// Drop the entry once idle, so the map doesn't grow with every project.
|
|
268
|
+
void settled.then(() => {
|
|
269
|
+
if (queues.get(file) === settled)
|
|
270
|
+
queues.delete(file);
|
|
271
|
+
});
|
|
272
|
+
return next;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=blocked-packages-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocked-packages-file.js","sourceRoot":"","sources":["../../src/core/blocked-packages-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Provider } from "@prestyj/ai";
|
|
2
2
|
export declare const DEFAULT_COMPACTION_THRESHOLD = 0.85;
|
|
3
|
-
/** The
|
|
4
|
-
export declare function resolveLatencyWindowCap(provider: Provider): number | undefined;
|
|
3
|
+
/** The effective trigger window cap for a provider (and model), if one applies. */
|
|
4
|
+
export declare function resolveLatencyWindowCap(provider: Provider, model?: string): number | undefined;
|
|
5
5
|
export interface CompactionPolicy {
|
|
6
6
|
threshold: number;
|
|
7
7
|
targetTokens: number;
|
|
@@ -1,63 +1,106 @@
|
|
|
1
1
|
export const DEFAULT_COMPACTION_THRESHOLD = 0.85;
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Caps on the context window used for compaction TRIGGERING, per provider.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* time-to-first-token at 213K tokens). A session sitting at 21% of a 1M
|
|
10
|
-
* window therefore paid a 45-70s tax on EVERY model call without ever
|
|
11
|
-
* approaching the 85% compaction trigger.
|
|
5
|
+
* The trigger is `threshold × min(contextWindow, cap)`. A cap moves only when
|
|
6
|
+
* compaction summarizes; the model's true window still governs hard limits
|
|
7
|
+
* (request size, output budgets), and min() keeps a smaller advertised window
|
|
8
|
+
* authoritative — a cap never raises a trigger.
|
|
12
9
|
*
|
|
13
|
-
*
|
|
10
|
+
* Every entry below needs evidence of ONE of these, cited inline:
|
|
14
11
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* tokens, zero stalls in 2,000+ turns). Capping these would throw away
|
|
21
|
-
* working context for nothing.
|
|
22
|
-
* 3. UNKNOWN — the conservative default cap below. Any provider we have
|
|
23
|
-
* not measured gets it, so a user on ANY model is protected from the
|
|
24
|
-
* mega-window + cold-prefill pattern. The `cache_health` /
|
|
25
|
-
* `prompt_cache_miss` diag lines (agent-loop) turn tier 3 into tier 1 or
|
|
26
|
-
* 2 with one line here as evidence arrives — remove a provider's cap
|
|
27
|
-
* once its logs show healthy cache reads at large sizes, lower it when
|
|
28
|
-
* they show misses.
|
|
12
|
+
* - a hard input limit below the advertised window;
|
|
13
|
+
* - measured slow turns (re-prefill without prompt caching);
|
|
14
|
+
* - a price tier that reprices the WHOLE request once the prompt crosses a
|
|
15
|
+
* size, so every turn past it costs more;
|
|
16
|
+
* - the vendor's own agent compacting this model earlier on the same route.
|
|
29
17
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
18
|
+
* "uncapped" needs evidence too: automatic prompt caching with cheap cache
|
|
19
|
+
* hits and no long-context tier, or measured fast turns at large sizes.
|
|
20
|
+
* Providers with no evidence either way keep {@link DEFAULT_LATENCY_WINDOW_CAP}.
|
|
21
|
+
* Verified 2026-10-16 against the vendors' agents in source (deepseek-harness,
|
|
22
|
+
* gemini-cli, qwen-code, codex, CodeWhale's model/pricing tables) and docs.
|
|
34
23
|
*/
|
|
35
|
-
const
|
|
24
|
+
const PROVIDER_WINDOW_CAPS = {
|
|
25
|
+
// Measured: TTFT 1.1s <50K → 3.6s at 700K–1M, ~100% cache reads over
|
|
26
|
+
// 26,000+ turns (session logs, 2026-10). No long-context price tier. Claude
|
|
27
|
+
anthropic: "uncapped",
|
|
28
|
+
// Price line: once input passes 272K, OpenAI bills the WHOLE request at 2×
|
|
29
|
+
// input/cache and 1.5× output (OpenAI model pages, via CodeWhale pricing.rs
|
|
30
|
+
// OPENAI_LONG_CONTEXT_SURCHARGE_THRESHOLD). Codex itself stays under it,
|
|
31
|
+
// compacting at 90% of a 272K window (codex-rs/protocol/src/openai_models.rs
|
|
32
|
+
// auto_compact_token_limit). Trigger 231K on both routes: the API key's
|
|
33
|
+
// 1.05M window is capped here, the Codex OAuth route already passes 272K.
|
|
34
|
+
openai: 272_000,
|
|
35
|
+
// Measured slow: every turn re-prefilled the whole context on the Coding
|
|
36
|
+
// Plan endpoint at ~3–5K tok/s (2026-09-22 sidecar log: 44–68s TTFT at 213K).
|
|
36
37
|
glm: 176_000,
|
|
38
|
+
// DeepSeek's own agent compacts at 80% of a 1M window with no cap
|
|
39
|
+
// (deepseek-harness packages/compaction: ratio 0.8, DEFAULT_CONTEXT_WINDOW
|
|
40
|
+
// 1_000_000). Automatic prefix caching, hits ~1/50 of a miss (pi models:
|
|
41
|
+
// cacheRead 0.006 vs input 0.30), no long-context surcharge.
|
|
42
|
+
deepseek: "uncapped",
|
|
43
|
+
// Kimi K3: automatic caching, hit $0.30 vs miss $3.00, no long-context tier
|
|
44
|
+
// (platform.kimi.ai pricing, via CodeWhale pricing.rs). Kimi For Coding
|
|
45
|
+
// (K2.8 Preview) serves up to 1M (kimi.com/code/docs).
|
|
46
|
+
moonshot: "uncapped",
|
|
47
|
+
// Measured: mimo-v2.6-pro ~1,600 turns, TTFT 4–7s, 95–100% of input read
|
|
48
|
+
// from cache up to 250K (session logs). Cache hit $0.0036 vs miss $0.435
|
|
49
|
+
// (~1/120), and V2.6 has a single price tier (Xiaomi rate card).
|
|
50
|
+
xiaomi: "uncapped",
|
|
51
|
+
// MiniMax-M3 doubles its price once input passes 512K (0.30 → 0.60 in, cache
|
|
52
|
+
// 0.06 → 0.12: CodeWhale pricing.rs MINIMAX_M3_LONG_CONTEXT_THRESHOLD, from
|
|
53
|
+
// MiniMax's pay-as-you-go page), and 512K is the guaranteed window; "1M" is
|
|
54
|
+
// up to. Trigger 435K stays under the line.
|
|
55
|
+
minimax: 512_000,
|
|
56
|
+
// Google's own Gemini CLI compresses at 50% of the window on this same
|
|
57
|
+
// Code Assist route (packages/cli/src/ui/constants.ts
|
|
58
|
+
// DEFAULT_COMPRESSION_THRESHOLD = 0.5; tokenLimit 1_048_576 for every
|
|
59
|
+
// Gemini model), and implicit caching on Code Assist is unverified. 616K ×
|
|
60
|
+
// 0.85 = 524K ≈ 50% of 1,048,576. Flash and Flash Lite are flat-priced at any
|
|
61
|
+
// prompt size; 3.1 Pro has its own price-line cap in MODEL_WINDOW_CAPS.
|
|
62
|
+
gemini: 616_000,
|
|
63
|
+
// Price line: xAI bills the WHOLE request at 2× ($4 / $1 cached / $12) once a
|
|
64
|
+
// grok-4.7 prompt reaches 200K tokens (docs.x.ai/developers/pricing;
|
|
65
|
+
// CodeWhale pricing.rs GROK_4_6_LONG_CONTEXT_THRESHOLD = 200_000). Trigger
|
|
66
|
+
// 170K stays under the line.
|
|
67
|
+
xai: 200_000,
|
|
68
|
+
// Qwen's own agent (qwen-code) runs qwen3.8-max at a 1M window and compacts
|
|
69
|
+
// at 85% (chatCompressionService DEFAULT_PCT). OpenRouter lists cache reads
|
|
70
|
+
// at $0.25 vs $2.00 input and no long-context tier.
|
|
71
|
+
openrouter: "uncapped",
|
|
37
72
|
};
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Per-model caps, checked before the provider's rule: a model whose pricing
|
|
75
|
+
* differs from the rest of its provider.
|
|
76
|
+
*/
|
|
77
|
+
const MODEL_WINDOW_CAPS = {
|
|
78
|
+
// Price line: Gemini 3.1 Pro bills the WHOLE request at $4 / $18 instead of
|
|
79
|
+
// $2 / $12 once the prompt passes 200K tokens (Gemini API pricing); the
|
|
80
|
+
// Flash models stay flat. On a Code Assist licence this compacts earlier than
|
|
81
|
+
// Gemini CLI's 50%, which keeps API-key users off the higher rate.
|
|
82
|
+
"gemini-3.1-pro-preview": 200_000,
|
|
83
|
+
};
|
|
84
|
+
/** Conservative ceiling for providers with NO evidence either way (Sakana, the
|
|
85
|
+
* Hugging Face router — whose served window and caching vary by backend).
|
|
86
|
+
* Only bites windows above ~470K; 200–272K windows are unaffected. */
|
|
45
87
|
const DEFAULT_LATENCY_WINDOW_CAP = 400_000;
|
|
46
|
-
/** The
|
|
47
|
-
export function resolveLatencyWindowCap(provider) {
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
return
|
|
51
|
-
|
|
88
|
+
/** The effective trigger window cap for a provider (and model), if one applies. */
|
|
89
|
+
export function resolveLatencyWindowCap(provider, model) {
|
|
90
|
+
const modelCap = model === undefined ? undefined : MODEL_WINDOW_CAPS[model];
|
|
91
|
+
if (modelCap !== undefined)
|
|
92
|
+
return modelCap;
|
|
93
|
+
const rule = PROVIDER_WINDOW_CAPS[provider];
|
|
94
|
+
if (rule === "uncapped")
|
|
52
95
|
return undefined;
|
|
53
|
-
return DEFAULT_LATENCY_WINDOW_CAP;
|
|
96
|
+
return rule ?? DEFAULT_LATENCY_WINDOW_CAP;
|
|
54
97
|
}
|
|
55
98
|
/** One trigger policy shared by app sessions and CLI compaction. */
|
|
56
99
|
export function resolveCompactionPolicy(options) {
|
|
57
100
|
const threshold = Number.isFinite(options.threshold) && options.threshold > 0 && options.threshold < 1
|
|
58
101
|
? options.threshold
|
|
59
102
|
: DEFAULT_COMPACTION_THRESHOLD;
|
|
60
|
-
const latencyCap = resolveLatencyWindowCap(options.provider);
|
|
103
|
+
const latencyCap = resolveLatencyWindowCap(options.provider, options.model);
|
|
61
104
|
// The trigger fires against the latency-capped window when one applies —
|
|
62
105
|
// min() keeps a provider-declared window smaller than the cap authoritative.
|
|
63
106
|
const effectiveWindow = latencyCap
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/core/compaction/policy.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/core/compaction/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,7 +27,10 @@ export declare function measureConversationChars(messages: Message[]): {
|
|
|
27
27
|
* its authoritative total input tokens (uncached + cache read/write). Skips
|
|
28
28
|
* histories containing image/video parts.
|
|
29
29
|
*/
|
|
30
|
-
export declare function calibrateEstimatorFromUsage(history: Message[], usage: Usage
|
|
30
|
+
export declare function calibrateEstimatorFromUsage(history: Message[], usage: Usage,
|
|
31
|
+
/** Characters the provider also counted but `history` lacks — the tool
|
|
32
|
+
* definitions sent with the request. Omitting them biases the ratio low. */
|
|
33
|
+
extraChars?: number): void;
|
|
31
34
|
export declare function estimateTokens(text: string): number;
|
|
32
35
|
export declare function estimateMessageTokens(message: Message): number;
|
|
33
36
|
export declare function estimateConversationTokens(messages: Message[]): number;
|
|
@@ -108,12 +108,15 @@ export function measureConversationChars(messages) {
|
|
|
108
108
|
* its authoritative total input tokens (uncached + cache read/write). Skips
|
|
109
109
|
* histories containing image/video parts.
|
|
110
110
|
*/
|
|
111
|
-
export function calibrateEstimatorFromUsage(history, usage
|
|
111
|
+
export function calibrateEstimatorFromUsage(history, usage,
|
|
112
|
+
/** Characters the provider also counted but `history` lacks — the tool
|
|
113
|
+
* definitions sent with the request. Omitting them biases the ratio low. */
|
|
114
|
+
extraChars = 0) {
|
|
112
115
|
const { chars, hasMedia } = measureConversationChars(history);
|
|
113
116
|
if (hasMedia)
|
|
114
117
|
return;
|
|
115
118
|
const totalInputTokens = usage.inputTokens + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
116
|
-
calibrateEstimator(chars, totalInputTokens);
|
|
119
|
+
calibrateEstimator(chars + Math.max(0, extraChars), totalInputTokens);
|
|
117
120
|
}
|
|
118
121
|
function getModelCharsPerToken() {
|
|
119
122
|
if (!activeModel)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../../../src/core/compaction/token-estimator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../../../src/core/compaction/token-estimator.ts"],"names":[],"mappings":"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"}
|
package/dist/core/event-bus.d.ts
CHANGED
|
@@ -86,6 +86,16 @@ export interface BusEventMap {
|
|
|
86
86
|
diagnostics: {
|
|
87
87
|
text: string;
|
|
88
88
|
};
|
|
89
|
+
/** A project's lockfile pins a package now known to be malware (background check). */
|
|
90
|
+
security_notice: {
|
|
91
|
+
key: string;
|
|
92
|
+
message: string;
|
|
93
|
+
};
|
|
94
|
+
/** A guard blocked something (or found an infected installed package): a chat row. */
|
|
95
|
+
security_block: {
|
|
96
|
+
rule: string;
|
|
97
|
+
target: string;
|
|
98
|
+
};
|
|
89
99
|
hook: {
|
|
90
100
|
kind: "ideal" | "verification" | "loop_break" | "regrounding";
|
|
91
101
|
coverageExpected?: string[];
|
package/dist/core/event-bus.js
CHANGED
|
@@ -19,6 +19,8 @@ function emptyListenerSets() {
|
|
|
19
19
|
server_tool_call: new Set(),
|
|
20
20
|
server_tool_result: new Set(),
|
|
21
21
|
diagnostics: new Set(),
|
|
22
|
+
security_notice: new Set(),
|
|
23
|
+
security_block: new Set(),
|
|
22
24
|
hook: new Set(),
|
|
23
25
|
hook_armed: new Set(),
|
|
24
26
|
subagent_state: new Set(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/core/event-bus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/core/event-bus.ts"],"names":[],"mappings":"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"}
|