@red-codes/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/dist/actions.d.ts +11 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +76 -0
- package/dist/actions.js.map +1 -0
- package/dist/adapters.d.ts +19 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +85 -0
- package/dist/adapters.js.map +1 -0
- package/dist/crypto-hash.d.ts +11 -0
- package/dist/crypto-hash.d.ts.map +1 -0
- package/dist/crypto-hash.js +14 -0
- package/dist/crypto-hash.js.map +1 -0
- package/dist/data/actions.json +42 -0
- package/dist/data/blast-radius.json +36 -0
- package/dist/data/destructive-patterns.json +94 -0
- package/dist/data/escalation.json +13 -0
- package/dist/data/git-action-patterns.json +7 -0
- package/dist/data/invariant-patterns.json +48 -0
- package/dist/data/tool-action-map.json +14 -0
- package/dist/execution-log/bridge.d.ts +12 -0
- package/dist/execution-log/bridge.d.ts.map +1 -0
- package/dist/execution-log/bridge.js +112 -0
- package/dist/execution-log/bridge.js.map +1 -0
- package/dist/execution-log/event-log.d.ts +7 -0
- package/dist/execution-log/event-log.d.ts.map +1 -0
- package/dist/execution-log/event-log.js +103 -0
- package/dist/execution-log/event-log.js.map +1 -0
- package/dist/execution-log/event-projections.d.ts +28 -0
- package/dist/execution-log/event-projections.d.ts.map +1 -0
- package/dist/execution-log/event-projections.js +272 -0
- package/dist/execution-log/event-projections.js.map +1 -0
- package/dist/execution-log/event-schema.d.ts +56 -0
- package/dist/execution-log/event-schema.d.ts.map +1 -0
- package/dist/execution-log/event-schema.js +160 -0
- package/dist/execution-log/event-schema.js.map +1 -0
- package/dist/execution-log/index.d.ts +7 -0
- package/dist/execution-log/index.d.ts.map +1 -0
- package/dist/execution-log/index.js +13 -0
- package/dist/execution-log/index.js.map +1 -0
- package/dist/governance-data.d.ts +177 -0
- package/dist/governance-data.d.ts.map +1 -0
- package/dist/governance-data.js +53 -0
- package/dist/governance-data.js.map +1 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +13 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/persona.d.ts +32 -0
- package/dist/persona.d.ts.map +1 -0
- package/dist/persona.js +138 -0
- package/dist/persona.js.map +1 -0
- package/dist/repo-root.d.ts +15 -0
- package/dist/repo-root.d.ts.map +1 -0
- package/dist/repo-root.js +56 -0
- package/dist/repo-root.js.map +1 -0
- package/dist/rng.d.ts +29 -0
- package/dist/rng.d.ts.map +1 -0
- package/dist/rng.js +48 -0
- package/dist/rng.js.map +1 -0
- package/dist/rtk.d.ts +22 -0
- package/dist/rtk.d.ts.map +1 -0
- package/dist/rtk.js +61 -0
- package/dist/rtk.js.map +1 -0
- package/dist/trust-store.d.ts +19 -0
- package/dist/trust-store.d.ts.map +1 -0
- package/dist/trust-store.js +98 -0
- package/dist/trust-store.js.map +1 -0
- package/dist/types.d.ts +849 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
package/dist/persona.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Agent persona resolver — merges persona from multiple sources (policy, env, per-action).
|
|
2
|
+
// Layered: policy defaults < environment overrides < per-action overrides.
|
|
3
|
+
const TRUST_TIERS = ['untrusted', 'limited', 'standard', 'elevated', 'admin'];
|
|
4
|
+
const AUTONOMY_LEVELS = ['supervised', 'semi-autonomous', 'autonomous'];
|
|
5
|
+
const RISK_TOLERANCES = ['conservative', 'moderate', 'aggressive'];
|
|
6
|
+
const PERSONA_ROLES = ['developer', 'reviewer', 'ops', 'security', 'ci'];
|
|
7
|
+
function isValidTrustTier(v) {
|
|
8
|
+
return TRUST_TIERS.includes(v);
|
|
9
|
+
}
|
|
10
|
+
function isValidAutonomy(v) {
|
|
11
|
+
return AUTONOMY_LEVELS.includes(v);
|
|
12
|
+
}
|
|
13
|
+
function isValidRiskTolerance(v) {
|
|
14
|
+
return RISK_TOLERANCES.includes(v);
|
|
15
|
+
}
|
|
16
|
+
function isValidRole(v) {
|
|
17
|
+
return PERSONA_ROLES.includes(v);
|
|
18
|
+
}
|
|
19
|
+
function mergeTags(...sources) {
|
|
20
|
+
const merged = new Set();
|
|
21
|
+
for (const tags of sources) {
|
|
22
|
+
if (tags) {
|
|
23
|
+
for (const t of tags)
|
|
24
|
+
merged.add(t);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return merged.size > 0 ? [...merged] : undefined;
|
|
28
|
+
}
|
|
29
|
+
function mergeModelMeta(...sources) {
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const meta of sources) {
|
|
32
|
+
if (!meta)
|
|
33
|
+
continue;
|
|
34
|
+
if (meta.model)
|
|
35
|
+
result.model = meta.model;
|
|
36
|
+
if (meta.provider)
|
|
37
|
+
result.provider = meta.provider;
|
|
38
|
+
if (meta.runtime)
|
|
39
|
+
result.runtime = meta.runtime;
|
|
40
|
+
if (meta.version)
|
|
41
|
+
result.version = meta.version;
|
|
42
|
+
}
|
|
43
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Merge persona from multiple sources. Later sources override earlier ones.
|
|
47
|
+
* Order: policy defaults < environment overrides < per-action overrides.
|
|
48
|
+
*/
|
|
49
|
+
export function resolvePersona(policyPersona, envPersona, actionPersona) {
|
|
50
|
+
const result = {
|
|
51
|
+
modelMeta: mergeModelMeta(policyPersona?.modelMeta, envPersona?.modelMeta, actionPersona?.modelMeta),
|
|
52
|
+
trustTier: actionPersona?.trustTier ?? envPersona?.trustTier ?? policyPersona?.trustTier,
|
|
53
|
+
autonomy: actionPersona?.autonomy ?? envPersona?.autonomy ?? policyPersona?.autonomy,
|
|
54
|
+
riskTolerance: actionPersona?.riskTolerance ?? envPersona?.riskTolerance ?? policyPersona?.riskTolerance,
|
|
55
|
+
role: actionPersona?.role ?? envPersona?.role ?? policyPersona?.role,
|
|
56
|
+
tags: mergeTags(policyPersona?.tags, envPersona?.tags, actionPersona?.tags),
|
|
57
|
+
};
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read persona fields from environment variables.
|
|
62
|
+
* Returns undefined if no persona env vars are set.
|
|
63
|
+
*
|
|
64
|
+
* Supported variables:
|
|
65
|
+
* - AGENTGUARD_PERSONA_MODEL
|
|
66
|
+
* - AGENTGUARD_PERSONA_PROVIDER
|
|
67
|
+
* - AGENTGUARD_PERSONA_RUNTIME
|
|
68
|
+
* - AGENTGUARD_PERSONA_VERSION
|
|
69
|
+
* - AGENTGUARD_PERSONA_TRUST_TIER
|
|
70
|
+
* - AGENTGUARD_PERSONA_AUTONOMY
|
|
71
|
+
* - AGENTGUARD_PERSONA_RISK_TOLERANCE
|
|
72
|
+
* - AGENTGUARD_PERSONA_ROLE
|
|
73
|
+
* - AGENTGUARD_PERSONA_TAGS (comma-separated)
|
|
74
|
+
*/
|
|
75
|
+
export function personaFromEnv(env = process.env) {
|
|
76
|
+
const model = env.AGENTGUARD_PERSONA_MODEL;
|
|
77
|
+
const provider = env.AGENTGUARD_PERSONA_PROVIDER;
|
|
78
|
+
const runtime = env.AGENTGUARD_PERSONA_RUNTIME;
|
|
79
|
+
const version = env.AGENTGUARD_PERSONA_VERSION;
|
|
80
|
+
const trustTier = env.AGENTGUARD_PERSONA_TRUST_TIER;
|
|
81
|
+
const autonomy = env.AGENTGUARD_PERSONA_AUTONOMY;
|
|
82
|
+
const riskTolerance = env.AGENTGUARD_PERSONA_RISK_TOLERANCE;
|
|
83
|
+
const role = env.AGENTGUARD_PERSONA_ROLE;
|
|
84
|
+
const tagsRaw = env.AGENTGUARD_PERSONA_TAGS;
|
|
85
|
+
let hasAny = false;
|
|
86
|
+
const result = {};
|
|
87
|
+
// Model metadata
|
|
88
|
+
const modelMeta = {};
|
|
89
|
+
if (model) {
|
|
90
|
+
modelMeta.model = model;
|
|
91
|
+
hasAny = true;
|
|
92
|
+
}
|
|
93
|
+
if (provider) {
|
|
94
|
+
modelMeta.provider = provider;
|
|
95
|
+
hasAny = true;
|
|
96
|
+
}
|
|
97
|
+
if (runtime) {
|
|
98
|
+
modelMeta.runtime = runtime;
|
|
99
|
+
hasAny = true;
|
|
100
|
+
}
|
|
101
|
+
if (version) {
|
|
102
|
+
modelMeta.version = version;
|
|
103
|
+
hasAny = true;
|
|
104
|
+
}
|
|
105
|
+
if (Object.keys(modelMeta).length > 0) {
|
|
106
|
+
result.modelMeta = modelMeta;
|
|
107
|
+
}
|
|
108
|
+
// Behavioral traits
|
|
109
|
+
if (trustTier && isValidTrustTier(trustTier)) {
|
|
110
|
+
result.trustTier = trustTier;
|
|
111
|
+
hasAny = true;
|
|
112
|
+
}
|
|
113
|
+
if (autonomy && isValidAutonomy(autonomy)) {
|
|
114
|
+
result.autonomy = autonomy;
|
|
115
|
+
hasAny = true;
|
|
116
|
+
}
|
|
117
|
+
if (riskTolerance && isValidRiskTolerance(riskTolerance)) {
|
|
118
|
+
result.riskTolerance = riskTolerance;
|
|
119
|
+
hasAny = true;
|
|
120
|
+
}
|
|
121
|
+
if (role && isValidRole(role)) {
|
|
122
|
+
result.role = role;
|
|
123
|
+
hasAny = true;
|
|
124
|
+
}
|
|
125
|
+
if (tagsRaw) {
|
|
126
|
+
const tags = tagsRaw
|
|
127
|
+
.split(',')
|
|
128
|
+
.map((t) => t.trim())
|
|
129
|
+
.filter((t) => t.length > 0);
|
|
130
|
+
if (tags.length > 0) {
|
|
131
|
+
result.tags = tags;
|
|
132
|
+
hasAny = true;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return hasAny ? result : undefined;
|
|
136
|
+
}
|
|
137
|
+
export { TRUST_TIERS, AUTONOMY_LEVELS, RISK_TOLERANCES, PERSONA_ROLES, isValidTrustTier, isValidAutonomy, isValidRiskTolerance, isValidRole, };
|
|
138
|
+
//# sourceMappingURL=persona.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.js","sourceRoot":"","sources":["../src/persona.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the main git repository root, resolving through worktrees.
|
|
3
|
+
* In a worktree, this returns the main repo root (not the worktree root).
|
|
4
|
+
* Falls back to process.cwd() if not in a git repo or git is unavailable.
|
|
5
|
+
* Result is cached per-process.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveMainRepoRoot(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Returns true if the current working directory is a git worktree
|
|
10
|
+
* (not the main repository checkout).
|
|
11
|
+
*/
|
|
12
|
+
export declare function isWorktree(): boolean;
|
|
13
|
+
/** Reset the cached root (for testing). */
|
|
14
|
+
export declare function _resetRepoRootCache(): void;
|
|
15
|
+
//# sourceMappingURL=repo-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-root.d.ts","sourceRoot":"","sources":["../src/repo-root.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAqB5C;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAWpC;AAED,2CAA2C;AAC3C,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Worktree-aware repository root resolution.
|
|
2
|
+
// In a git worktree, process.cwd() returns the worktree path, not the main repo root.
|
|
3
|
+
// This utility resolves the main repo root so governance paths (policy, storage, hooks)
|
|
4
|
+
// are consistent across all worktrees.
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
let _cachedMainRoot; // undefined = not yet computed
|
|
7
|
+
/**
|
|
8
|
+
* Returns the main git repository root, resolving through worktrees.
|
|
9
|
+
* In a worktree, this returns the main repo root (not the worktree root).
|
|
10
|
+
* Falls back to process.cwd() if not in a git repo or git is unavailable.
|
|
11
|
+
* Result is cached per-process.
|
|
12
|
+
*/
|
|
13
|
+
export function resolveMainRepoRoot() {
|
|
14
|
+
if (_cachedMainRoot !== undefined)
|
|
15
|
+
return _cachedMainRoot ?? process.cwd();
|
|
16
|
+
try {
|
|
17
|
+
// `git worktree list --porcelain` always lists the main worktree first
|
|
18
|
+
const output = execSync('git worktree list --porcelain', {
|
|
19
|
+
encoding: 'utf8',
|
|
20
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
21
|
+
timeout: 3000,
|
|
22
|
+
});
|
|
23
|
+
const firstLine = output.split('\n')[0];
|
|
24
|
+
if (firstLine?.startsWith('worktree ')) {
|
|
25
|
+
_cachedMainRoot = firstLine.slice('worktree '.length).trim();
|
|
26
|
+
return _cachedMainRoot;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Not in a git repo, or git not available
|
|
31
|
+
}
|
|
32
|
+
_cachedMainRoot = null;
|
|
33
|
+
return process.cwd();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if the current working directory is a git worktree
|
|
37
|
+
* (not the main repository checkout).
|
|
38
|
+
*/
|
|
39
|
+
export function isWorktree() {
|
|
40
|
+
try {
|
|
41
|
+
const toplevel = execSync('git rev-parse --show-toplevel', {
|
|
42
|
+
encoding: 'utf8',
|
|
43
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
44
|
+
timeout: 3000,
|
|
45
|
+
}).trim();
|
|
46
|
+
return toplevel !== resolveMainRepoRoot();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Reset the cached root (for testing). */
|
|
53
|
+
export function _resetRepoRootCache() {
|
|
54
|
+
_cachedMainRoot = undefined;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=repo-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-root.js","sourceRoot":"","sources":["../src/repo-root.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,sFAAsF;AACtF,wFAAwF;AACxF,uCAAuC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,IAAI,eAA0C,CAAC,CAAC,+BAA+B;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE3E,IAAI,CAAC;QACH,uEAAuE;QACvE,MAAM,MAAM,GAAG,QAAQ,CAAC,+BAA+B,EAAE;YACvD,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,SAAS,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,eAAe,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7D,OAAO,eAAe,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IAED,eAAe,GAAG,IAAI,CAAC;IACvB,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,+BAA+B,EAAE;YACzD,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,QAAQ,KAAK,mBAAmB,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,mBAAmB;IACjC,eAAe,GAAG,SAAS,CAAC;AAC9B,CAAC"}
|
package/dist/rng.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A seeded PRNG instance. All methods are deterministic given the same
|
|
3
|
+
* seed and the same sequence of calls.
|
|
4
|
+
*/
|
|
5
|
+
export interface SeededRng {
|
|
6
|
+
/** The seed used to initialize this RNG */
|
|
7
|
+
readonly seed: number;
|
|
8
|
+
/** Returns a random float in [0, 1) */
|
|
9
|
+
random(): number;
|
|
10
|
+
/** Returns a random integer in [min, max) */
|
|
11
|
+
randomInt(min: number, max: number): number;
|
|
12
|
+
/** Returns a random hex string of the given length */
|
|
13
|
+
randomHex(length: number): string;
|
|
14
|
+
/** Creates a fork with a derived seed (independent stream) */
|
|
15
|
+
fork(): SeededRng;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generate a seed from system entropy (non-deterministic).
|
|
19
|
+
* Used when recording a new session to capture the initial seed.
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateSeed(): number;
|
|
22
|
+
/**
|
|
23
|
+
* Create a seeded PRNG using the mulberry32 algorithm.
|
|
24
|
+
*
|
|
25
|
+
* Mulberry32 is a simple 32-bit state PRNG with good statistical properties.
|
|
26
|
+
* It passes BigCrush and is sufficient for ID generation and shuffling.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createSeededRng(seed: number): SeededRng;
|
|
29
|
+
//# sourceMappingURL=rng.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rng.d.ts","sourceRoot":"","sources":["../src/rng.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,MAAM,IAAI,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,sDAAsD;IACtD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,8DAA8D;IAC9D,IAAI,IAAI,SAAS,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAoCvD"}
|
package/dist/rng.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Seeded pseudo-random number generator for deterministic replay.
|
|
2
|
+
// Uses the mulberry32 algorithm — fast, simple, well-distributed outputs.
|
|
3
|
+
// Same seed + same call sequence = identical results.
|
|
4
|
+
/**
|
|
5
|
+
* Generate a seed from system entropy (non-deterministic).
|
|
6
|
+
* Used when recording a new session to capture the initial seed.
|
|
7
|
+
*/
|
|
8
|
+
export function generateSeed() {
|
|
9
|
+
return (Math.random() * 0xffffffff) >>> 0;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create a seeded PRNG using the mulberry32 algorithm.
|
|
13
|
+
*
|
|
14
|
+
* Mulberry32 is a simple 32-bit state PRNG with good statistical properties.
|
|
15
|
+
* It passes BigCrush and is sufficient for ID generation and shuffling.
|
|
16
|
+
*/
|
|
17
|
+
export function createSeededRng(seed) {
|
|
18
|
+
let state = seed >>> 0;
|
|
19
|
+
function next() {
|
|
20
|
+
state |= 0;
|
|
21
|
+
state = (state + 0x6d2b79f5) | 0;
|
|
22
|
+
let t = Math.imul(state ^ (state >>> 15), 1 | state);
|
|
23
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
24
|
+
return ((t ^ (t >>> 14)) >>> 0) / 0x100000000;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
get seed() {
|
|
28
|
+
return seed;
|
|
29
|
+
},
|
|
30
|
+
random: next,
|
|
31
|
+
randomInt(min, max) {
|
|
32
|
+
return Math.floor(next() * (max - min)) + min;
|
|
33
|
+
},
|
|
34
|
+
randomHex(length) {
|
|
35
|
+
const chars = '0123456789abcdef';
|
|
36
|
+
let result = '';
|
|
37
|
+
for (let i = 0; i < length; i++) {
|
|
38
|
+
result += chars[Math.floor(next() * 16)];
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
},
|
|
42
|
+
fork() {
|
|
43
|
+
const derivedSeed = (next() * 0xffffffff) >>> 0;
|
|
44
|
+
return createSeededRng(derivedSeed);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=rng.js.map
|
package/dist/rng.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rng.js","sourceRoot":"","sources":["../src/rng.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,0EAA0E;AAC1E,sDAAsD;AAmBtD;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC;IAEvB,SAAS,IAAI;QACX,KAAK,IAAI,CAAC,CAAC;QACX,KAAK,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;QACrD,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC;IAChD,CAAC;IAED,OAAO;QACL,IAAI,IAAI;YACN,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,EAAE,IAAI;QAEZ,SAAS,CAAC,GAAW,EAAE,GAAW;YAChC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QAChD,CAAC;QAED,SAAS,CAAC,MAAc;YACtB,MAAM,KAAK,GAAG,kBAAkB,CAAC;YACjC,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI;YACF,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YAChD,OAAO,eAAe,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/rtk.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface RtkDetectionResult {
|
|
2
|
+
readonly available: boolean;
|
|
3
|
+
readonly version?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface RtkRewriteResult {
|
|
6
|
+
readonly rewritten: boolean;
|
|
7
|
+
readonly command: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Detect whether rtk is installed and available on PATH.
|
|
11
|
+
* Result is cached for the lifetime of the process.
|
|
12
|
+
*/
|
|
13
|
+
export declare function detectRtk(): RtkDetectionResult;
|
|
14
|
+
/**
|
|
15
|
+
* Ask rtk to rewrite a command for token-optimized output.
|
|
16
|
+
* If rtk has an equivalent (exit 0), returns the rewritten command.
|
|
17
|
+
* If no equivalent (exit 1) or rtk is unavailable, returns the original command.
|
|
18
|
+
*/
|
|
19
|
+
export declare function rtkRewrite(command: string): RtkRewriteResult;
|
|
20
|
+
/** Reset the cached detection result. Exported for testing. */
|
|
21
|
+
export declare function resetRtkCache(): void;
|
|
22
|
+
//# sourceMappingURL=rtk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtk.d.ts","sourceRoot":"","sources":["../src/rtk.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAID;;;GAGG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAqB9C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAmB5D;AAED,+DAA+D;AAC/D,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
|
package/dist/rtk.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// RTK (rtk-ai/rtk) detection and integration utility.
|
|
2
|
+
// RTK is a CLI proxy that reduces LLM token consumption by 60-90%
|
|
3
|
+
// through intelligent command output filtering.
|
|
4
|
+
// All functions are safe to call when rtk is not installed — they return graceful defaults.
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
const RTK_DETECT_TIMEOUT = 2_000;
|
|
7
|
+
let cachedDetection = null;
|
|
8
|
+
/**
|
|
9
|
+
* Detect whether rtk is installed and available on PATH.
|
|
10
|
+
* Result is cached for the lifetime of the process.
|
|
11
|
+
*/
|
|
12
|
+
export function detectRtk() {
|
|
13
|
+
if (cachedDetection !== null)
|
|
14
|
+
return cachedDetection;
|
|
15
|
+
try {
|
|
16
|
+
const output = execSync('rtk --version', {
|
|
17
|
+
encoding: 'utf8',
|
|
18
|
+
timeout: RTK_DETECT_TIMEOUT,
|
|
19
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
20
|
+
}).trim();
|
|
21
|
+
// rtk --version outputs something like "rtk 0.30.0" or just "0.30.0"
|
|
22
|
+
const versionMatch = output.match(/(\d+\.\d+\.\d+)/);
|
|
23
|
+
cachedDetection = {
|
|
24
|
+
available: true,
|
|
25
|
+
version: versionMatch?.[1],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
cachedDetection = { available: false };
|
|
30
|
+
}
|
|
31
|
+
return cachedDetection;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Ask rtk to rewrite a command for token-optimized output.
|
|
35
|
+
* If rtk has an equivalent (exit 0), returns the rewritten command.
|
|
36
|
+
* If no equivalent (exit 1) or rtk is unavailable, returns the original command.
|
|
37
|
+
*/
|
|
38
|
+
export function rtkRewrite(command) {
|
|
39
|
+
const rtk = detectRtk();
|
|
40
|
+
if (!rtk.available)
|
|
41
|
+
return { rewritten: false, command };
|
|
42
|
+
try {
|
|
43
|
+
const rewritten = execSync(`rtk rewrite ${JSON.stringify(command)}`, {
|
|
44
|
+
encoding: 'utf8',
|
|
45
|
+
timeout: RTK_DETECT_TIMEOUT,
|
|
46
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
47
|
+
}).trim();
|
|
48
|
+
if (rewritten) {
|
|
49
|
+
return { rewritten: true, command: rewritten };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Exit code 1 = no rtk equivalent, or rtk error — use original
|
|
54
|
+
}
|
|
55
|
+
return { rewritten: false, command };
|
|
56
|
+
}
|
|
57
|
+
/** Reset the cached detection result. Exported for testing. */
|
|
58
|
+
export function resetRtkCache() {
|
|
59
|
+
cachedDetection = null;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=rtk.js.map
|
package/dist/rtk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtk.js","sourceRoot":"","sources":["../src/rtk.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,kEAAkE;AAClE,gDAAgD;AAChD,4FAA4F;AAE5F,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAYjC,IAAI,eAAe,GAA8B,IAAI,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,eAAe,KAAK,IAAI;QAAE,OAAO,eAAe,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,EAAE;YACvC,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,kBAAkB;YAC3B,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,qEAAqE;QACrE,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACrD,eAAe,GAAG;YAChB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;SAC3B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,QAAQ,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE;YACnE,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,kBAAkB;YAC3B,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QACjD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;IACjE,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACvC,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,aAAa;IAC3B,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface TrustEntry {
|
|
2
|
+
path: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
trustedAt: string;
|
|
5
|
+
trustedBy: 'user' | 'ci-override';
|
|
6
|
+
}
|
|
7
|
+
export interface TrustStore {
|
|
8
|
+
version: 1;
|
|
9
|
+
entries: Record<string, TrustEntry>;
|
|
10
|
+
}
|
|
11
|
+
export declare function loadTrustStore(): TrustStore;
|
|
12
|
+
export declare function saveTrustStore(store: TrustStore): void;
|
|
13
|
+
export declare function computeFileHash(filePath: string): Promise<string>;
|
|
14
|
+
export declare function verifyTrust(filePath: string): Promise<'trusted' | 'untrusted' | 'content_changed'>;
|
|
15
|
+
export declare function trustFile(filePath: string): Promise<TrustEntry>;
|
|
16
|
+
export declare function revokeTrust(filePath: string): void;
|
|
17
|
+
export declare function detectCiPlatform(): string | null;
|
|
18
|
+
export declare function isCiTrustOverride(): boolean;
|
|
19
|
+
//# sourceMappingURL=trust-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-store.d.ts","sourceRoot":"","sources":["../src/trust-store.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACrC;AAsBD,wBAAgB,cAAc,IAAI,UAAU,CAe3C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAItD;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEvE;AAED,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAOtD;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAarE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAUhD;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, realpathSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { computeSHA256 } from './crypto-hash.js';
|
|
5
|
+
const CURRENT_VERSION = 1;
|
|
6
|
+
function getTrustStorePath() {
|
|
7
|
+
const base = process.env.AGENTGUARD_HOME ?? join(homedir(), '.agentguard');
|
|
8
|
+
return join(base, 'trust.json');
|
|
9
|
+
}
|
|
10
|
+
function ensureDir(filePath) {
|
|
11
|
+
const dir = dirname(filePath);
|
|
12
|
+
if (!existsSync(dir))
|
|
13
|
+
mkdirSync(dir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
function canonicalPath(filePath) {
|
|
16
|
+
try {
|
|
17
|
+
return realpathSync(filePath);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return filePath;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function loadTrustStore() {
|
|
24
|
+
const storePath = getTrustStorePath();
|
|
25
|
+
if (!existsSync(storePath))
|
|
26
|
+
return { version: CURRENT_VERSION, entries: {} };
|
|
27
|
+
try {
|
|
28
|
+
const raw = JSON.parse(readFileSync(storePath, 'utf8'));
|
|
29
|
+
if (raw.version !== CURRENT_VERSION) {
|
|
30
|
+
process.stderr.write(`Warning: Trust store version ${String(raw.version)} not recognized, treating as empty\n`);
|
|
31
|
+
return { version: CURRENT_VERSION, entries: {} };
|
|
32
|
+
}
|
|
33
|
+
return { version: CURRENT_VERSION, entries: (raw.entries ?? {}) };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return { version: CURRENT_VERSION, entries: {} };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function saveTrustStore(store) {
|
|
40
|
+
const storePath = getTrustStorePath();
|
|
41
|
+
ensureDir(storePath);
|
|
42
|
+
writeFileSync(storePath, JSON.stringify(store, null, 2));
|
|
43
|
+
}
|
|
44
|
+
export async function computeFileHash(filePath) {
|
|
45
|
+
return computeSHA256(readFileSync(filePath));
|
|
46
|
+
}
|
|
47
|
+
export async function verifyTrust(filePath) {
|
|
48
|
+
const canonical = canonicalPath(filePath);
|
|
49
|
+
const store = loadTrustStore();
|
|
50
|
+
const entry = store.entries[canonical];
|
|
51
|
+
if (!entry)
|
|
52
|
+
return 'untrusted';
|
|
53
|
+
const currentHash = await computeFileHash(filePath);
|
|
54
|
+
return currentHash === entry.hash ? 'trusted' : 'content_changed';
|
|
55
|
+
}
|
|
56
|
+
export async function trustFile(filePath) {
|
|
57
|
+
const canonical = canonicalPath(filePath);
|
|
58
|
+
const hash = await computeFileHash(filePath);
|
|
59
|
+
const entry = {
|
|
60
|
+
path: canonical,
|
|
61
|
+
hash,
|
|
62
|
+
trustedAt: new Date().toISOString(),
|
|
63
|
+
trustedBy: 'user',
|
|
64
|
+
};
|
|
65
|
+
const store = loadTrustStore();
|
|
66
|
+
store.entries[canonical] = entry;
|
|
67
|
+
saveTrustStore(store);
|
|
68
|
+
return entry;
|
|
69
|
+
}
|
|
70
|
+
export function revokeTrust(filePath) {
|
|
71
|
+
const canonical = canonicalPath(filePath);
|
|
72
|
+
const store = loadTrustStore();
|
|
73
|
+
delete store.entries[canonical];
|
|
74
|
+
saveTrustStore(store);
|
|
75
|
+
}
|
|
76
|
+
export function detectCiPlatform() {
|
|
77
|
+
if (process.env.GITHUB_ACTIONS)
|
|
78
|
+
return 'github-actions';
|
|
79
|
+
if (process.env.GITLAB_CI)
|
|
80
|
+
return 'gitlab-ci';
|
|
81
|
+
if (process.env.JENKINS_URL)
|
|
82
|
+
return 'jenkins';
|
|
83
|
+
if (process.env.CIRCLECI)
|
|
84
|
+
return 'circleci';
|
|
85
|
+
if (process.env.TRAVIS)
|
|
86
|
+
return 'travis';
|
|
87
|
+
if (process.env.BUILDKITE)
|
|
88
|
+
return 'buildkite';
|
|
89
|
+
if (process.env.CODEBUILD_BUILD_ID)
|
|
90
|
+
return 'aws-codebuild';
|
|
91
|
+
if (process.env.TF_BUILD)
|
|
92
|
+
return 'azure-devops';
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
export function isCiTrustOverride() {
|
|
96
|
+
return process.env.AGENTGUARD_TRUST_PROJECT_POLICY === '1' && detectCiPlatform() !== null;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=trust-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-store.js","sourceRoot":"","sources":["../src/trust-store.ts"],"names":[],"mappings":"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"}
|