agent-relay 1.3.1 → 1.3.3
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/.trajectories/active/traj_3yx9dy148mge.json +42 -0
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.json +49 -0
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.md +31 -0
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.json +49 -0
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.md +31 -0
- package/.trajectories/completed/2026-01/traj_6unwwmgyj5sq.json +109 -0
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.json +49 -0
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.md +31 -0
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.json +66 -0
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.md +36 -0
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.json +49 -0
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.md +31 -0
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.json +65 -0
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.md +37 -0
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.json +36 -0
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.md +21 -0
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.json +101 -0
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.md +52 -0
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.json +61 -0
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.md +36 -0
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.json +73 -0
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.md +41 -0
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.json +77 -0
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.md +42 -0
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.json +109 -0
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.md +56 -0
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.json +113 -0
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.md +57 -0
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.json +61 -0
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.md +36 -0
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.json +49 -0
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.md +31 -0
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.json +49 -0
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.md +31 -0
- package/.trajectories/index.json +140 -1
- package/README.md +23 -9
- package/TRAIL_GIT_AUTH_FIX.md +113 -0
- package/deploy/workspace/codex.config.toml +1 -1
- package/deploy/workspace/entrypoint.sh +20 -79
- package/deploy/workspace/gh-relay +156 -0
- package/deploy/workspace/git-credential-relay +5 -1
- package/dist/bridge/multi-project-client.js +13 -10
- package/dist/bridge/spawner.d.ts +2 -0
- package/dist/bridge/spawner.js +58 -76
- package/dist/bridge/types.d.ts +2 -0
- package/dist/cli/index.d.ts +8 -6
- package/dist/cli/index.js +297 -30
- package/dist/cloud/api/admin.js +16 -3
- package/dist/cloud/api/codex-auth-helper.js +28 -8
- package/dist/cloud/api/consensus.d.ts +13 -0
- package/dist/cloud/api/consensus.js +259 -0
- package/dist/cloud/api/daemons.js +205 -1
- package/dist/cloud/api/git.js +37 -7
- package/dist/cloud/api/onboarding.js +4 -1
- package/dist/cloud/api/provider-env.d.ts +5 -0
- package/dist/cloud/api/provider-env.js +27 -0
- package/dist/cloud/api/providers.js +2 -0
- package/dist/cloud/api/test-helpers.js +130 -0
- package/dist/cloud/api/workspaces.js +38 -3
- package/dist/cloud/db/bulk-ingest.d.ts +88 -0
- package/dist/cloud/db/bulk-ingest.js +268 -0
- package/dist/cloud/db/drizzle.d.ts +33 -0
- package/dist/cloud/db/drizzle.js +174 -2
- package/dist/cloud/db/index.d.ts +24 -5
- package/dist/cloud/db/index.js +19 -4
- package/dist/cloud/db/schema.d.ts +397 -3
- package/dist/cloud/db/schema.js +75 -1
- package/dist/cloud/provisioner/index.d.ts +8 -0
- package/dist/cloud/provisioner/index.js +256 -50
- package/dist/cloud/server.js +47 -3
- package/dist/cloud/services/index.d.ts +1 -0
- package/dist/cloud/services/index.js +2 -0
- package/dist/cloud/services/nango.d.ts +3 -4
- package/dist/cloud/services/nango.js +11 -33
- package/dist/cloud/services/workspace-keepalive.d.ts +76 -0
- package/dist/cloud/services/workspace-keepalive.js +234 -0
- package/dist/config/relay-config.d.ts +23 -0
- package/dist/config/relay-config.js +23 -0
- package/dist/daemon/agent-manager.d.ts +20 -1
- package/dist/daemon/agent-manager.js +51 -0
- package/dist/daemon/agent-registry.js +4 -4
- package/dist/daemon/agent-signing.d.ts +158 -0
- package/dist/daemon/agent-signing.js +523 -0
- package/dist/daemon/api.js +18 -1
- package/dist/daemon/cli-auth.d.ts +4 -1
- package/dist/daemon/cli-auth.js +55 -11
- package/dist/daemon/cloud-sync.d.ts +47 -1
- package/dist/daemon/cloud-sync.js +152 -3
- package/dist/daemon/connection.d.ts +28 -0
- package/dist/daemon/connection.js +113 -22
- package/dist/daemon/consensus-integration.d.ts +167 -0
- package/dist/daemon/consensus-integration.js +371 -0
- package/dist/daemon/consensus.d.ts +271 -0
- package/dist/daemon/consensus.js +632 -0
- package/dist/daemon/delivery-tracker.d.ts +34 -0
- package/dist/daemon/delivery-tracker.js +104 -0
- package/dist/daemon/enhanced-features.d.ts +118 -0
- package/dist/daemon/enhanced-features.js +178 -0
- package/dist/daemon/index.d.ts +4 -0
- package/dist/daemon/index.js +5 -0
- package/dist/daemon/rate-limiter.d.ts +68 -0
- package/dist/daemon/rate-limiter.js +130 -0
- package/dist/daemon/router.d.ts +18 -11
- package/dist/daemon/router.js +57 -113
- package/dist/daemon/server.d.ts +13 -1
- package/dist/daemon/server.js +71 -9
- package/dist/daemon/sync-queue.d.ts +116 -0
- package/dist/daemon/sync-queue.js +361 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/116-de2a4ac06e5000dc.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/919-87d604a5d76c1fbd.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/{page-c617745b81344f4f.js → page-7f64824ae7d06707.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-3f559d393902aad2.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/page-16d1715ddaa874ee.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/{page-dc786c183425c2ac.js → page-814efc4d77b4191d.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-2ee6beb2ae96d210.js → main-5a40a5ae29646e1b.js} +1 -1
- package/dist/dashboard/out/_next/static/css/44d2b52637b511bc.css +1 -0
- package/dist/dashboard/out/app/onboarding.html +1 -1
- package/dist/dashboard/out/app/onboarding.txt +1 -1
- package/dist/dashboard/out/app.html +1 -1
- package/dist/dashboard/out/app.txt +2 -2
- package/dist/dashboard/out/cloud/link.html +1 -0
- package/dist/dashboard/out/cloud/link.txt +7 -0
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +1 -1
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +2 -2
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +2 -2
- package/dist/dashboard/out/login.html +2 -3
- package/dist/dashboard/out/login.txt +2 -2
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +2 -2
- package/dist/dashboard/out/pricing.html +2 -2
- package/dist/dashboard/out/pricing.txt +1 -1
- package/dist/dashboard/out/providers/setup/claude.html +1 -1
- package/dist/dashboard/out/providers/setup/claude.txt +1 -1
- package/dist/dashboard/out/providers/setup/codex.html +1 -1
- package/dist/dashboard/out/providers/setup/codex.txt +1 -1
- package/dist/dashboard/out/providers.html +1 -1
- package/dist/dashboard/out/providers.txt +1 -1
- package/dist/dashboard/out/signup.html +2 -2
- package/dist/dashboard/out/signup.txt +1 -1
- package/dist/dashboard-server/server.js +244 -28
- package/dist/health-worker-manager.d.ts +62 -0
- package/dist/health-worker-manager.js +144 -0
- package/dist/health-worker.d.ts +9 -0
- package/dist/health-worker.js +79 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/memory/context-compaction.d.ts +156 -0
- package/dist/memory/context-compaction.js +453 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.js +1 -0
- package/dist/protocol/channels.js +4 -4
- package/dist/protocol/framing.d.ts +72 -10
- package/dist/protocol/framing.js +194 -25
- package/dist/storage/adapter.d.ts +8 -1
- package/dist/storage/adapter.js +11 -0
- package/dist/storage/batched-sqlite-adapter.d.ts +71 -0
- package/dist/storage/batched-sqlite-adapter.js +183 -0
- package/dist/storage/dead-letter-queue.d.ts +196 -0
- package/dist/storage/dead-letter-queue.js +427 -0
- package/dist/storage/dlq-adapter.d.ts +195 -0
- package/dist/storage/dlq-adapter.js +664 -0
- package/dist/trajectory/config.d.ts +32 -14
- package/dist/trajectory/config.js +38 -16
- package/dist/trajectory/integration.js +217 -64
- package/dist/utils/git-remote.d.ts +47 -0
- package/dist/utils/git-remote.js +125 -0
- package/dist/utils/id-generator.d.ts +35 -0
- package/dist/utils/id-generator.js +60 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/precompiled-patterns.d.ts +110 -0
- package/dist/utils/precompiled-patterns.js +322 -0
- package/dist/wrapper/auth-detection.js +1 -1
- package/dist/wrapper/base-wrapper.d.ts +40 -0
- package/dist/wrapper/base-wrapper.js +60 -6
- package/dist/wrapper/client.d.ts +14 -4
- package/dist/wrapper/client.js +89 -31
- package/dist/wrapper/idle-detector.d.ts +102 -0
- package/dist/wrapper/idle-detector.js +279 -0
- package/dist/wrapper/parser.d.ts +4 -0
- package/dist/wrapper/parser.js +19 -1
- package/dist/wrapper/pty-wrapper.d.ts +14 -2
- package/dist/wrapper/pty-wrapper.js +132 -32
- package/dist/wrapper/shared.d.ts +1 -1
- package/dist/wrapper/shared.js +1 -1
- package/dist/wrapper/tmux-wrapper.d.ts +20 -2
- package/dist/wrapper/tmux-wrapper.js +163 -40
- package/package.json +3 -1
- package/scripts/run-migrations.js +43 -0
- package/scripts/verify-schema.js +134 -0
- package/tests/benchmarks/protocol.bench.ts +310 -0
- package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/899-fc02ed79e3de4302.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +0 -1
- package/dist/dashboard/out/_next/static/css/48a8fbe3e659080e.css +0 -1
- /package/dist/dashboard/out/_next/static/{sDcbGRTYLcpPvyTs_rsNb → R-uQOUcOLINtsp6ACeZa9}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{sDcbGRTYLcpPvyTs_rsNb → R-uQOUcOLINtsp6ACeZa9}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Remote Detection Utility
|
|
3
|
+
*
|
|
4
|
+
* Detects the git remote URL from a working directory and parses it
|
|
5
|
+
* to extract the repository full name (owner/repo).
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { execSync } from 'node:child_process';
|
|
10
|
+
/**
|
|
11
|
+
* Parse a git remote URL to extract owner/repo format.
|
|
12
|
+
*
|
|
13
|
+
* Supports:
|
|
14
|
+
* - git@github.com:owner/repo.git
|
|
15
|
+
* - https://github.com/owner/repo.git
|
|
16
|
+
* - https://github.com/owner/repo
|
|
17
|
+
* - git://github.com/owner/repo.git
|
|
18
|
+
*/
|
|
19
|
+
export function parseGitRemoteUrl(url) {
|
|
20
|
+
if (!url)
|
|
21
|
+
return null;
|
|
22
|
+
// SSH format: git@github.com:owner/repo.git
|
|
23
|
+
const sshMatch = url.match(/git@[^:]+:([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
24
|
+
if (sshMatch) {
|
|
25
|
+
return sshMatch[1];
|
|
26
|
+
}
|
|
27
|
+
// HTTPS/Git format: https://github.com/owner/repo.git
|
|
28
|
+
const httpsMatch = url.match(/(?:https?|git):\/\/[^/]+\/([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
29
|
+
if (httpsMatch) {
|
|
30
|
+
return httpsMatch[1];
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the git remote URL from a directory.
|
|
36
|
+
*
|
|
37
|
+
* @param workingDirectory The directory to check for git remote
|
|
38
|
+
* @param remoteName The remote name to use (default: 'origin')
|
|
39
|
+
* @returns The remote URL or null if not found
|
|
40
|
+
*/
|
|
41
|
+
export function getGitRemoteUrl(workingDirectory, remoteName = 'origin') {
|
|
42
|
+
try {
|
|
43
|
+
// First check if it's a git repository
|
|
44
|
+
const gitDir = path.join(workingDirectory, '.git');
|
|
45
|
+
if (!fs.existsSync(gitDir)) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
// Try to get the remote URL using git command
|
|
49
|
+
const result = execSync(`git remote get-url ${remoteName}`, {
|
|
50
|
+
cwd: workingDirectory,
|
|
51
|
+
encoding: 'utf-8',
|
|
52
|
+
timeout: 5000,
|
|
53
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
54
|
+
});
|
|
55
|
+
return result.trim() || null;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Git command failed - try parsing .git/config directly
|
|
59
|
+
try {
|
|
60
|
+
const configPath = path.join(workingDirectory, '.git', 'config');
|
|
61
|
+
if (!fs.existsSync(configPath)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const config = fs.readFileSync(configPath, 'utf-8');
|
|
65
|
+
// Parse git config to find remote URL
|
|
66
|
+
const remoteSection = new RegExp(`\\[remote\\s+"${remoteName}"\\][^\\[]*url\\s*=\\s*([^\\n]+)`, 'i');
|
|
67
|
+
const match = config.match(remoteSection);
|
|
68
|
+
return match?.[1]?.trim() || null;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the repository full name (owner/repo) from a working directory.
|
|
77
|
+
*
|
|
78
|
+
* @param workingDirectory The directory to check
|
|
79
|
+
* @returns The repo full name (e.g., "AgentWorkforce/relay") or null
|
|
80
|
+
*/
|
|
81
|
+
export function getRepoFullName(workingDirectory) {
|
|
82
|
+
const remoteUrl = getGitRemoteUrl(workingDirectory);
|
|
83
|
+
if (!remoteUrl) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
return parseGitRemoteUrl(remoteUrl);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Find the git root directory from a given path.
|
|
90
|
+
* Walks up the directory tree looking for .git folder.
|
|
91
|
+
*
|
|
92
|
+
* @param startPath The path to start searching from
|
|
93
|
+
* @returns The git root directory or null if not in a git repo
|
|
94
|
+
*/
|
|
95
|
+
export function findGitRoot(startPath) {
|
|
96
|
+
let currentPath = path.resolve(startPath);
|
|
97
|
+
const root = path.parse(currentPath).root;
|
|
98
|
+
while (currentPath !== root) {
|
|
99
|
+
if (fs.existsSync(path.join(currentPath, '.git'))) {
|
|
100
|
+
return currentPath;
|
|
101
|
+
}
|
|
102
|
+
currentPath = path.dirname(currentPath);
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get repository full name, walking up to find git root if needed.
|
|
108
|
+
*
|
|
109
|
+
* @param workingDirectory The directory to start from
|
|
110
|
+
* @returns The repo full name or null
|
|
111
|
+
*/
|
|
112
|
+
export function getRepoFullNameFromPath(workingDirectory) {
|
|
113
|
+
// First try the exact directory
|
|
114
|
+
let repoName = getRepoFullName(workingDirectory);
|
|
115
|
+
if (repoName) {
|
|
116
|
+
return repoName;
|
|
117
|
+
}
|
|
118
|
+
// Walk up to find git root
|
|
119
|
+
const gitRoot = findGitRoot(workingDirectory);
|
|
120
|
+
if (gitRoot && gitRoot !== workingDirectory) {
|
|
121
|
+
repoName = getRepoFullName(gitRoot);
|
|
122
|
+
}
|
|
123
|
+
return repoName;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=git-remote.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monotonic ID Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates unique, lexicographically sortable IDs that are faster than UUID v4.
|
|
5
|
+
*
|
|
6
|
+
* Format: <timestamp-base36>-<counter-base36>-<nodeId>
|
|
7
|
+
* Example: "lxyz5g8-0001-7d2a"
|
|
8
|
+
*
|
|
9
|
+
* Properties:
|
|
10
|
+
* - Lexicographically sortable by time
|
|
11
|
+
* - Unique across processes (node prefix)
|
|
12
|
+
* - ~16x faster than UUID v4
|
|
13
|
+
* - Shorter (20-24 chars vs 36 chars)
|
|
14
|
+
*/
|
|
15
|
+
export declare class IdGenerator {
|
|
16
|
+
private counter;
|
|
17
|
+
private readonly prefix;
|
|
18
|
+
private lastTs;
|
|
19
|
+
constructor(nodeId?: string);
|
|
20
|
+
/**
|
|
21
|
+
* Generate a unique, monotonically increasing ID.
|
|
22
|
+
*/
|
|
23
|
+
next(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Generate a short ID (just timestamp + counter, no node prefix).
|
|
26
|
+
* Use when you don't need cross-process uniqueness.
|
|
27
|
+
*/
|
|
28
|
+
short(): string;
|
|
29
|
+
}
|
|
30
|
+
export declare const idGen: IdGenerator;
|
|
31
|
+
/**
|
|
32
|
+
* Generate a unique ID (drop-in replacement for uuid()).
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateId(): string;
|
|
35
|
+
//# sourceMappingURL=id-generator.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monotonic ID Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates unique, lexicographically sortable IDs that are faster than UUID v4.
|
|
5
|
+
*
|
|
6
|
+
* Format: <timestamp-base36>-<counter-base36>-<nodeId>
|
|
7
|
+
* Example: "lxyz5g8-0001-7d2a"
|
|
8
|
+
*
|
|
9
|
+
* Properties:
|
|
10
|
+
* - Lexicographically sortable by time
|
|
11
|
+
* - Unique across processes (node prefix)
|
|
12
|
+
* - ~16x faster than UUID v4
|
|
13
|
+
* - Shorter (20-24 chars vs 36 chars)
|
|
14
|
+
*/
|
|
15
|
+
export class IdGenerator {
|
|
16
|
+
counter = 0;
|
|
17
|
+
prefix;
|
|
18
|
+
lastTs = 0;
|
|
19
|
+
constructor(nodeId) {
|
|
20
|
+
// Use process ID + random suffix for uniqueness across processes
|
|
21
|
+
this.prefix = nodeId ?? `${process.pid.toString(36)}${Math.random().toString(36).slice(2, 6)}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generate a unique, monotonically increasing ID.
|
|
25
|
+
*/
|
|
26
|
+
next() {
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
// Reset counter if timestamp changed
|
|
29
|
+
if (now !== this.lastTs) {
|
|
30
|
+
this.lastTs = now;
|
|
31
|
+
this.counter = 0;
|
|
32
|
+
}
|
|
33
|
+
const ts = now.toString(36);
|
|
34
|
+
const seq = (this.counter++).toString(36).padStart(4, '0');
|
|
35
|
+
return `${ts}-${seq}-${this.prefix}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Generate a short ID (just timestamp + counter, no node prefix).
|
|
39
|
+
* Use when you don't need cross-process uniqueness.
|
|
40
|
+
*/
|
|
41
|
+
short() {
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
if (now !== this.lastTs) {
|
|
44
|
+
this.lastTs = now;
|
|
45
|
+
this.counter = 0;
|
|
46
|
+
}
|
|
47
|
+
const ts = now.toString(36);
|
|
48
|
+
const seq = (this.counter++).toString(36).padStart(4, '0');
|
|
49
|
+
return `${ts}-${seq}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Singleton instance for the process
|
|
53
|
+
export const idGen = new IdGenerator();
|
|
54
|
+
/**
|
|
55
|
+
* Generate a unique ID (drop-in replacement for uuid()).
|
|
56
|
+
*/
|
|
57
|
+
export function generateId() {
|
|
58
|
+
return idGen.next();
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=id-generator.js.map
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Precompiled Pattern Matching
|
|
3
|
+
*
|
|
4
|
+
* Optimized regex patterns for high-performance message parsing.
|
|
5
|
+
* Inspired by russian-code-ts performance targets (<1ms for pattern matching).
|
|
6
|
+
*
|
|
7
|
+
* Strategies:
|
|
8
|
+
* 1. Precompile patterns at module load (not per-instance)
|
|
9
|
+
* 2. Combine multiple patterns into single regex where possible
|
|
10
|
+
* 3. Use non-capturing groups and atomic patterns
|
|
11
|
+
* 4. Cache compiled patterns by prefix
|
|
12
|
+
*/
|
|
13
|
+
export interface CompiledPatterns {
|
|
14
|
+
inline: RegExp;
|
|
15
|
+
fencedInline: RegExp;
|
|
16
|
+
escape: RegExp;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get or create compiled patterns for a given prefix configuration.
|
|
20
|
+
* Patterns are cached for reuse across parser instances.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getCompiledPatterns(prefix?: string, thinkingPrefix?: string): CompiledPatterns;
|
|
23
|
+
/**
|
|
24
|
+
* Fast check if text matches any instructional pattern.
|
|
25
|
+
* Single regex test instead of array.some().
|
|
26
|
+
*/
|
|
27
|
+
export declare function isInstructionalTextFast(body: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Fast placeholder target check using Set.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isPlaceholderTargetFast(target: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Strip ANSI escape codes from a string.
|
|
34
|
+
* Uses precompiled patterns for better performance.
|
|
35
|
+
*/
|
|
36
|
+
export declare function stripAnsiFast(str: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Precompiled static patterns used across parsing operations.
|
|
39
|
+
*/
|
|
40
|
+
export declare const StaticPatterns: {
|
|
41
|
+
readonly BLOCK_END: RegExp;
|
|
42
|
+
readonly BLOCK_METADATA_END: RegExp;
|
|
43
|
+
readonly CODE_FENCE: RegExp;
|
|
44
|
+
readonly FENCE_END_START: RegExp;
|
|
45
|
+
readonly FENCE_END_LINE: RegExp;
|
|
46
|
+
readonly FENCE_END: RegExp;
|
|
47
|
+
readonly ESCAPED_FENCE_START: RegExp;
|
|
48
|
+
readonly ESCAPED_FENCE_END: RegExp;
|
|
49
|
+
readonly ESCAPED_FENCE_END_CHECK: RegExp;
|
|
50
|
+
readonly ESCAPED_FENCE_START_CHECK: RegExp;
|
|
51
|
+
readonly BULLET_OR_NUMBERED_LIST: RegExp;
|
|
52
|
+
readonly PROMPTISH_LINE: RegExp;
|
|
53
|
+
readonly RELAY_INJECTION_PREFIX: RegExp;
|
|
54
|
+
readonly SPAWN_COMMAND: RegExp;
|
|
55
|
+
readonly RELEASE_COMMAND: RegExp;
|
|
56
|
+
readonly THINKING_START: RegExp;
|
|
57
|
+
readonly THINKING_END: RegExp;
|
|
58
|
+
readonly AGENT_NAME: RegExp;
|
|
59
|
+
readonly CLI_PROMPTS: {
|
|
60
|
+
readonly claude: RegExp;
|
|
61
|
+
readonly gemini: RegExp;
|
|
62
|
+
readonly codex: RegExp;
|
|
63
|
+
readonly droid: RegExp;
|
|
64
|
+
readonly opencode: RegExp;
|
|
65
|
+
readonly spawned: RegExp;
|
|
66
|
+
readonly other: RegExp;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Check if line is a spawn or release command.
|
|
71
|
+
*/
|
|
72
|
+
export declare function isSpawnOrReleaseCommandFast(line: string): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Check if a line contains an escaped fence end.
|
|
75
|
+
*/
|
|
76
|
+
export declare function isEscapedFenceEndFast(line: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Unescape fence markers in content.
|
|
79
|
+
*/
|
|
80
|
+
export declare function unescapeFenceMarkersFast(content: string): string;
|
|
81
|
+
interface PatternMetrics {
|
|
82
|
+
calls: number;
|
|
83
|
+
totalMs: number;
|
|
84
|
+
maxMs: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Track pattern matching performance (for debugging/profiling).
|
|
88
|
+
* Call with pattern name and execution time.
|
|
89
|
+
*/
|
|
90
|
+
export declare function trackPatternPerformance(name: string, ms: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* Get pattern performance metrics.
|
|
93
|
+
*/
|
|
94
|
+
export declare function getPatternMetrics(): Map<string, PatternMetrics & {
|
|
95
|
+
avgMs: number;
|
|
96
|
+
}>;
|
|
97
|
+
/**
|
|
98
|
+
* Reset pattern performance metrics.
|
|
99
|
+
*/
|
|
100
|
+
export declare function resetPatternMetrics(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Benchmark pattern matching performance.
|
|
103
|
+
* Useful for testing optimization impact.
|
|
104
|
+
*/
|
|
105
|
+
export declare function benchmarkPatterns(iterations?: number): Record<string, {
|
|
106
|
+
avgNs: number;
|
|
107
|
+
maxNs: number;
|
|
108
|
+
}>;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=precompiled-patterns.d.ts.map
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Precompiled Pattern Matching
|
|
3
|
+
*
|
|
4
|
+
* Optimized regex patterns for high-performance message parsing.
|
|
5
|
+
* Inspired by russian-code-ts performance targets (<1ms for pattern matching).
|
|
6
|
+
*
|
|
7
|
+
* Strategies:
|
|
8
|
+
* 1. Precompile patterns at module load (not per-instance)
|
|
9
|
+
* 2. Combine multiple patterns into single regex where possible
|
|
10
|
+
* 3. Use non-capturing groups and atomic patterns
|
|
11
|
+
* 4. Cache compiled patterns by prefix
|
|
12
|
+
*/
|
|
13
|
+
const patternCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Escape special regex characters in a string
|
|
16
|
+
*/
|
|
17
|
+
function escapeRegex(str) {
|
|
18
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get or create compiled patterns for a given prefix configuration.
|
|
22
|
+
* Patterns are cached for reuse across parser instances.
|
|
23
|
+
*/
|
|
24
|
+
export function getCompiledPatterns(prefix = '->relay:', thinkingPrefix = '->thinking:') {
|
|
25
|
+
const cacheKey = `${prefix}|${thinkingPrefix}`;
|
|
26
|
+
const cached = patternCache.get(cacheKey);
|
|
27
|
+
if (cached) {
|
|
28
|
+
return cached;
|
|
29
|
+
}
|
|
30
|
+
const escapedPrefix = escapeRegex(prefix);
|
|
31
|
+
const escapedThinking = escapeRegex(thinkingPrefix);
|
|
32
|
+
// Combined prompt character class for line start
|
|
33
|
+
// Includes: >, $, %, #, →, ➜, ›, », bullets (●•◦‣⁃-*⏺◆◇○□■), box chars (│┃┆┇┊┋╎╏), sparkle (✦)
|
|
34
|
+
const promptChars = String.raw `[>$%#→➜›»●•◦‣⁃\-*⏺◆◇○□■│┃┆┇┊┋╎╏✦]`;
|
|
35
|
+
const lineStartPrefix = String.raw `^(?:\s*(?:${promptChars}\s*)*)?`;
|
|
36
|
+
// Thread syntax: [thread:id] or [thread:project:id]
|
|
37
|
+
const threadSyntax = String.raw `(?:\s+\[thread:(?:([\w-]+):)?([\w-]+)\])?`;
|
|
38
|
+
const patterns = {
|
|
39
|
+
// Combined inline pattern for both relay and thinking prefixes
|
|
40
|
+
// Groups: 1=prefix type (relay/thinking), 2=target, 3=thread project, 4=thread id, 5=body
|
|
41
|
+
inline: new RegExp(`${lineStartPrefix}(${escapedPrefix}|${escapedThinking})(\\S+)${threadSyntax}\\s+(.+)$`),
|
|
42
|
+
// Combined fenced inline pattern: ->relay:Target <<<
|
|
43
|
+
// Groups: 1=prefix type, 2=target, 3=thread project, 4=thread id
|
|
44
|
+
fencedInline: new RegExp(`${lineStartPrefix}(${escapedPrefix}|${escapedThinking})(\\S+)${threadSyntax}\\s+<<<\\s*$`),
|
|
45
|
+
// Escape pattern for \->relay: or \->thinking:
|
|
46
|
+
escape: new RegExp(`^(\\s*)\\\\(${escapedPrefix}|${escapedThinking})`),
|
|
47
|
+
};
|
|
48
|
+
patternCache.set(cacheKey, patterns);
|
|
49
|
+
return patterns;
|
|
50
|
+
}
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// Combined Instructional Markers (Single Regex)
|
|
53
|
+
// =============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Combined instructional markers pattern.
|
|
56
|
+
* Instead of testing each pattern separately, we combine into one regex.
|
|
57
|
+
*
|
|
58
|
+
* Original patterns:
|
|
59
|
+
* - /\bSEND:\s*$/i
|
|
60
|
+
* - /\bPROTOCOL:\s*\(\d+\)/i
|
|
61
|
+
* - /\bExample:/i
|
|
62
|
+
* - /\\->relay:/
|
|
63
|
+
* - /\\->thinking:/
|
|
64
|
+
* - /^AgentName\s+/
|
|
65
|
+
* - /^Target\s+/
|
|
66
|
+
* - /\[Agent Relay\]/
|
|
67
|
+
* - /MULTI-LINE:/i
|
|
68
|
+
* - /RECEIVE:/i
|
|
69
|
+
*/
|
|
70
|
+
const INSTRUCTIONAL_COMBINED = new RegExp([
|
|
71
|
+
String.raw `\bSEND:\s*$`, // "SEND:" at end (instruction prefix)
|
|
72
|
+
String.raw `\bPROTOCOL:\s*\(\d+\)`, // "PROTOCOL: (1)" - numbered instructions
|
|
73
|
+
String.raw `\bExample:`, // "Example:" marker
|
|
74
|
+
String.raw `\\->relay:`, // Escaped relay prefix (documentation)
|
|
75
|
+
String.raw `\\->thinking:`, // Escaped thinking prefix (documentation)
|
|
76
|
+
String.raw `^AgentName\s+`, // Body starting with "AgentName"
|
|
77
|
+
String.raw `^Target\s+`, // Body starting with "Target"
|
|
78
|
+
String.raw `\[Agent Relay\]`, // Injected instruction header
|
|
79
|
+
String.raw `MULTI-LINE:`, // Multi-line format instruction
|
|
80
|
+
String.raw `RECEIVE:`, // Receive instruction marker
|
|
81
|
+
].join('|'), 'i' // Case insensitive
|
|
82
|
+
);
|
|
83
|
+
/**
|
|
84
|
+
* Fast check if text matches any instructional pattern.
|
|
85
|
+
* Single regex test instead of array.some().
|
|
86
|
+
*/
|
|
87
|
+
export function isInstructionalTextFast(body) {
|
|
88
|
+
return INSTRUCTIONAL_COMBINED.test(body);
|
|
89
|
+
}
|
|
90
|
+
// =============================================================================
|
|
91
|
+
// Placeholder Targets (Set for O(1) Lookup)
|
|
92
|
+
// =============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Placeholder target names - precomputed lowercase set for fast lookup.
|
|
95
|
+
*/
|
|
96
|
+
const PLACEHOLDER_TARGETS_SET = new Set([
|
|
97
|
+
'agentname',
|
|
98
|
+
'target',
|
|
99
|
+
'recipient',
|
|
100
|
+
'yourtarget',
|
|
101
|
+
'targetagent',
|
|
102
|
+
'someagent',
|
|
103
|
+
'otheragent',
|
|
104
|
+
'worker',
|
|
105
|
+
]);
|
|
106
|
+
/**
|
|
107
|
+
* Fast placeholder target check using Set.
|
|
108
|
+
*/
|
|
109
|
+
export function isPlaceholderTargetFast(target) {
|
|
110
|
+
return PLACEHOLDER_TARGETS_SET.has(target.toLowerCase());
|
|
111
|
+
}
|
|
112
|
+
// =============================================================================
|
|
113
|
+
// ANSI Stripping (Precompiled)
|
|
114
|
+
// =============================================================================
|
|
115
|
+
/**
|
|
116
|
+
* Precompiled ANSI escape sequence pattern.
|
|
117
|
+
* Global flag for replace operations.
|
|
118
|
+
*/
|
|
119
|
+
// eslint-disable-next-line no-control-regex
|
|
120
|
+
const ANSI_PATTERN_COMPILED = /\x1b\[[0-9;?]*[a-zA-Z]|\x1b\].*?(?:\x07|\x1b\\)|\r/g;
|
|
121
|
+
/**
|
|
122
|
+
* Precompiled orphaned CSI pattern.
|
|
123
|
+
*/
|
|
124
|
+
const ORPHANED_CSI_COMPILED = /^\s*(\[(?:\?|\d)\d*[A-Za-z])+\s*/g;
|
|
125
|
+
/**
|
|
126
|
+
* Strip ANSI escape codes from a string.
|
|
127
|
+
* Uses precompiled patterns for better performance.
|
|
128
|
+
*/
|
|
129
|
+
export function stripAnsiFast(str) {
|
|
130
|
+
// Reset lastIndex for global patterns
|
|
131
|
+
ANSI_PATTERN_COMPILED.lastIndex = 0;
|
|
132
|
+
ORPHANED_CSI_COMPILED.lastIndex = 0;
|
|
133
|
+
let result = str.replace(ANSI_PATTERN_COMPILED, '');
|
|
134
|
+
result = result.replace(ORPHANED_CSI_COMPILED, '');
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
// =============================================================================
|
|
138
|
+
// Static Patterns (Precompiled)
|
|
139
|
+
// =============================================================================
|
|
140
|
+
/**
|
|
141
|
+
* Precompiled static patterns used across parsing operations.
|
|
142
|
+
*/
|
|
143
|
+
export const StaticPatterns = {
|
|
144
|
+
// Block markers
|
|
145
|
+
BLOCK_END: /\[\[\/RELAY\]\]/,
|
|
146
|
+
BLOCK_METADATA_END: /\[\[\/RELAY_METADATA\]\]/,
|
|
147
|
+
CODE_FENCE: /^```/,
|
|
148
|
+
// Fence markers
|
|
149
|
+
FENCE_END_START: /^(?:\s*)?>>>/,
|
|
150
|
+
FENCE_END_LINE: />>>\s*$/,
|
|
151
|
+
FENCE_END: /^(?:\s*)?>>>|>>>\s*$/,
|
|
152
|
+
// Escape patterns
|
|
153
|
+
ESCAPED_FENCE_START: /\\<<</g,
|
|
154
|
+
ESCAPED_FENCE_END: /\\>>>/g,
|
|
155
|
+
ESCAPED_FENCE_END_CHECK: /\\>>>\s*$/,
|
|
156
|
+
ESCAPED_FENCE_START_CHECK: /^(?:\s*)?\\>>>/,
|
|
157
|
+
// Continuation helpers
|
|
158
|
+
BULLET_OR_NUMBERED_LIST: /^[ \t]*([\-*•◦‣⏺◆◇○□■]|[0-9]+[.)])\s+/,
|
|
159
|
+
PROMPTISH_LINE: /^[\s]*[>$%#➜›»][\s]*$/,
|
|
160
|
+
RELAY_INJECTION_PREFIX: /^\s*Relay message from /,
|
|
161
|
+
// Spawn/release commands
|
|
162
|
+
SPAWN_COMMAND: /->relay:spawn\s+\S+/i,
|
|
163
|
+
RELEASE_COMMAND: /->relay:release\s+\S+/i,
|
|
164
|
+
// Claude extended thinking blocks
|
|
165
|
+
THINKING_START: /<thinking>/,
|
|
166
|
+
THINKING_END: /<\/thinking>/,
|
|
167
|
+
// Agent name validation (PascalCase, 2-30 chars)
|
|
168
|
+
AGENT_NAME: /^[A-Z][a-zA-Z0-9]{1,29}$/,
|
|
169
|
+
// CLI prompt patterns by type
|
|
170
|
+
CLI_PROMPTS: {
|
|
171
|
+
claude: /^[>›»]\s*$/,
|
|
172
|
+
gemini: /^[>›»]\s*$/,
|
|
173
|
+
codex: /^[>›»]\s*$/,
|
|
174
|
+
droid: /^[>›»]\s*$/,
|
|
175
|
+
opencode: /^[>›»]\s*$/,
|
|
176
|
+
spawned: /^[>›»]\s*$/,
|
|
177
|
+
other: /^[>$%#➜›»]\s*$/,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
// =============================================================================
|
|
181
|
+
// Pattern Matching Utilities
|
|
182
|
+
// =============================================================================
|
|
183
|
+
/**
|
|
184
|
+
* Check if line is a spawn or release command.
|
|
185
|
+
*/
|
|
186
|
+
export function isSpawnOrReleaseCommandFast(line) {
|
|
187
|
+
return StaticPatterns.SPAWN_COMMAND.test(line) ||
|
|
188
|
+
StaticPatterns.RELEASE_COMMAND.test(line);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Check if a line contains an escaped fence end.
|
|
192
|
+
*/
|
|
193
|
+
export function isEscapedFenceEndFast(line) {
|
|
194
|
+
return StaticPatterns.ESCAPED_FENCE_END_CHECK.test(line) ||
|
|
195
|
+
StaticPatterns.ESCAPED_FENCE_START_CHECK.test(line);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Unescape fence markers in content.
|
|
199
|
+
*/
|
|
200
|
+
export function unescapeFenceMarkersFast(content) {
|
|
201
|
+
StaticPatterns.ESCAPED_FENCE_START.lastIndex = 0;
|
|
202
|
+
StaticPatterns.ESCAPED_FENCE_END.lastIndex = 0;
|
|
203
|
+
return content
|
|
204
|
+
.replace(StaticPatterns.ESCAPED_FENCE_START, '<<<')
|
|
205
|
+
.replace(StaticPatterns.ESCAPED_FENCE_END, '>>>');
|
|
206
|
+
}
|
|
207
|
+
const metrics = new Map();
|
|
208
|
+
/**
|
|
209
|
+
* Track pattern matching performance (for debugging/profiling).
|
|
210
|
+
* Call with pattern name and execution time.
|
|
211
|
+
*/
|
|
212
|
+
export function trackPatternPerformance(name, ms) {
|
|
213
|
+
const existing = metrics.get(name);
|
|
214
|
+
if (existing) {
|
|
215
|
+
existing.calls++;
|
|
216
|
+
existing.totalMs += ms;
|
|
217
|
+
existing.maxMs = Math.max(existing.maxMs, ms);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
metrics.set(name, { calls: 1, totalMs: ms, maxMs: ms });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get pattern performance metrics.
|
|
225
|
+
*/
|
|
226
|
+
export function getPatternMetrics() {
|
|
227
|
+
const result = new Map();
|
|
228
|
+
for (const [name, m] of metrics) {
|
|
229
|
+
result.set(name, {
|
|
230
|
+
...m,
|
|
231
|
+
avgMs: m.calls > 0 ? m.totalMs / m.calls : 0,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Reset pattern performance metrics.
|
|
238
|
+
*/
|
|
239
|
+
export function resetPatternMetrics() {
|
|
240
|
+
metrics.clear();
|
|
241
|
+
}
|
|
242
|
+
// =============================================================================
|
|
243
|
+
// Benchmark Utility
|
|
244
|
+
// =============================================================================
|
|
245
|
+
/**
|
|
246
|
+
* Benchmark pattern matching performance.
|
|
247
|
+
* Useful for testing optimization impact.
|
|
248
|
+
*/
|
|
249
|
+
export function benchmarkPatterns(iterations = 10000) {
|
|
250
|
+
const testStrings = [
|
|
251
|
+
'->relay:Agent Hello world',
|
|
252
|
+
'->relay:Lead [thread:task-123] Starting work',
|
|
253
|
+
' > ->relay:Worker <<<',
|
|
254
|
+
'Some random text without relay',
|
|
255
|
+
'\x1b[32m->relay:Test\x1b[0m message with ANSI',
|
|
256
|
+
'->relay:spawn Worker claude "task"',
|
|
257
|
+
'ACK: Task received',
|
|
258
|
+
'SEND: Protocol instruction',
|
|
259
|
+
'Example: how to use relay',
|
|
260
|
+
];
|
|
261
|
+
const results = {};
|
|
262
|
+
// Benchmark combined instructional check
|
|
263
|
+
{
|
|
264
|
+
let maxNs = 0;
|
|
265
|
+
const start = process.hrtime.bigint();
|
|
266
|
+
for (let i = 0; i < iterations; i++) {
|
|
267
|
+
for (const str of testStrings) {
|
|
268
|
+
const s = process.hrtime.bigint();
|
|
269
|
+
isInstructionalTextFast(str);
|
|
270
|
+
const elapsed = Number(process.hrtime.bigint() - s);
|
|
271
|
+
if (elapsed > maxNs)
|
|
272
|
+
maxNs = elapsed;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const totalNs = Number(process.hrtime.bigint() - start);
|
|
276
|
+
results['instructionalCheck'] = {
|
|
277
|
+
avgNs: totalNs / (iterations * testStrings.length),
|
|
278
|
+
maxNs,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
// Benchmark ANSI stripping
|
|
282
|
+
{
|
|
283
|
+
let maxNs = 0;
|
|
284
|
+
const start = process.hrtime.bigint();
|
|
285
|
+
for (let i = 0; i < iterations; i++) {
|
|
286
|
+
for (const str of testStrings) {
|
|
287
|
+
const s = process.hrtime.bigint();
|
|
288
|
+
stripAnsiFast(str);
|
|
289
|
+
const elapsed = Number(process.hrtime.bigint() - s);
|
|
290
|
+
if (elapsed > maxNs)
|
|
291
|
+
maxNs = elapsed;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
const totalNs = Number(process.hrtime.bigint() - start);
|
|
295
|
+
results['ansiStrip'] = {
|
|
296
|
+
avgNs: totalNs / (iterations * testStrings.length),
|
|
297
|
+
maxNs,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
// Benchmark placeholder check
|
|
301
|
+
{
|
|
302
|
+
const targets = ['AgentName', 'Lead', 'Worker', 'target', 'Developer'];
|
|
303
|
+
let maxNs = 0;
|
|
304
|
+
const start = process.hrtime.bigint();
|
|
305
|
+
for (let i = 0; i < iterations; i++) {
|
|
306
|
+
for (const t of targets) {
|
|
307
|
+
const s = process.hrtime.bigint();
|
|
308
|
+
isPlaceholderTargetFast(t);
|
|
309
|
+
const elapsed = Number(process.hrtime.bigint() - s);
|
|
310
|
+
if (elapsed > maxNs)
|
|
311
|
+
maxNs = elapsed;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const totalNs = Number(process.hrtime.bigint() - start);
|
|
315
|
+
results['placeholderCheck'] = {
|
|
316
|
+
avgNs: totalNs / (iterations * targets.length),
|
|
317
|
+
maxNs,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
return results;
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=precompiled-patterns.js.map
|
|
@@ -104,7 +104,7 @@ export function detectAuthRevocation(output, recentOutputOnly = false) {
|
|
|
104
104
|
/**
|
|
105
105
|
* Determine confidence level based on the matched pattern.
|
|
106
106
|
*/
|
|
107
|
-
function getConfidenceLevel(pattern,
|
|
107
|
+
function getConfidenceLevel(pattern, _matchedText) {
|
|
108
108
|
const patternStr = pattern.source.toLowerCase();
|
|
109
109
|
// High confidence: Explicit auth failure messages
|
|
110
110
|
if (patternStr.includes('session') && patternStr.includes('expired') ||
|