@aegisagentics/agent 0.1.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/README.md +239 -0
- package/npm/install.js +229 -0
- package/npm/lib/cli.js +80 -0
- package/npm/lib/codex-hooks.js +165 -0
- package/npm/lib/codex-plugin.js +186 -0
- package/npm/lib/codex-runtime.js +81 -0
- package/npm/lib/codex.js +110 -0
- package/npm/lib/config.js +106 -0
- package/npm/lib/release-download.js +275 -0
- package/npm/release-manifest.json +23 -0
- package/package.json +34 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export const DEFAULT_CODEX_PLUGIN_ID = "aegis@aegis";
|
|
5
|
+
export const DEFAULT_CODEX_PLUGIN_NAME = "aegis";
|
|
6
|
+
|
|
7
|
+
export function codexMarketplaceFile(paths) {
|
|
8
|
+
return path.join(paths.codexMarketplaceDir, ".agents", "plugins", "marketplace.json");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function buildCodexPluginInstallRequest({
|
|
12
|
+
id = 2,
|
|
13
|
+
marketplaceFile,
|
|
14
|
+
pluginName = DEFAULT_CODEX_PLUGIN_NAME
|
|
15
|
+
}) {
|
|
16
|
+
return {
|
|
17
|
+
jsonrpc: "2.0",
|
|
18
|
+
id,
|
|
19
|
+
method: "plugin/install",
|
|
20
|
+
params: {
|
|
21
|
+
marketplacePath: marketplaceFile,
|
|
22
|
+
pluginName
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildCodexPluginUninstallRequest({
|
|
28
|
+
id = 2,
|
|
29
|
+
pluginId = DEFAULT_CODEX_PLUGIN_ID
|
|
30
|
+
} = {}) {
|
|
31
|
+
return {
|
|
32
|
+
jsonrpc: "2.0",
|
|
33
|
+
id,
|
|
34
|
+
method: "plugin/uninstall",
|
|
35
|
+
params: {
|
|
36
|
+
pluginId
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function installCodexPlugin({
|
|
42
|
+
codexCommand = "codex",
|
|
43
|
+
marketplaceFile,
|
|
44
|
+
pluginName = DEFAULT_CODEX_PLUGIN_NAME,
|
|
45
|
+
timeoutMs = 15_000
|
|
46
|
+
}) {
|
|
47
|
+
const request = buildCodexPluginInstallRequest({
|
|
48
|
+
marketplaceFile,
|
|
49
|
+
pluginName
|
|
50
|
+
});
|
|
51
|
+
return runCodexPluginRequest({
|
|
52
|
+
codexCommand,
|
|
53
|
+
request,
|
|
54
|
+
timeoutMs
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function uninstallCodexPlugin({
|
|
59
|
+
codexCommand = "codex",
|
|
60
|
+
pluginId = DEFAULT_CODEX_PLUGIN_ID,
|
|
61
|
+
timeoutMs = 15_000
|
|
62
|
+
} = {}) {
|
|
63
|
+
const request = buildCodexPluginUninstallRequest({ pluginId });
|
|
64
|
+
return runCodexPluginRequest({
|
|
65
|
+
codexCommand,
|
|
66
|
+
request,
|
|
67
|
+
timeoutMs
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function runCodexPluginRequest({ codexCommand, request, timeoutMs }) {
|
|
72
|
+
const appServer = spawn(codexCommand, ["app-server", "--listen", "stdio://"], {
|
|
73
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
let stderr = "";
|
|
77
|
+
let stdoutBuffer = "";
|
|
78
|
+
let settled = false;
|
|
79
|
+
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
const timer = setTimeout(() => {
|
|
82
|
+
finish(
|
|
83
|
+
reject,
|
|
84
|
+
new Error(
|
|
85
|
+
`Timed out waiting for Codex app-server response to ${request.method}`
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
}, timeoutMs);
|
|
89
|
+
|
|
90
|
+
appServer.on("error", (error) => {
|
|
91
|
+
clearTimeout(timer);
|
|
92
|
+
finish(
|
|
93
|
+
reject,
|
|
94
|
+
new Error(
|
|
95
|
+
`Unable to start Codex CLI (${codexCommand}) for plugin management: ${error.message}`
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
appServer.stderr.setEncoding("utf8");
|
|
101
|
+
appServer.stderr.on("data", (chunk) => {
|
|
102
|
+
stderr += chunk;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
appServer.stdout.setEncoding("utf8");
|
|
106
|
+
appServer.stdout.on("data", (chunk) => {
|
|
107
|
+
stdoutBuffer += chunk;
|
|
108
|
+
const lines = stdoutBuffer.split(/\r?\n/);
|
|
109
|
+
stdoutBuffer = lines.pop() ?? "";
|
|
110
|
+
for (const line of lines) {
|
|
111
|
+
if (line.trim() === "") {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
let message;
|
|
115
|
+
try {
|
|
116
|
+
message = JSON.parse(line);
|
|
117
|
+
} catch {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
handleMessage(message);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
appServer.on("close", (code) => {
|
|
125
|
+
if (!settled) {
|
|
126
|
+
clearTimeout(timer);
|
|
127
|
+
finish(
|
|
128
|
+
reject,
|
|
129
|
+
new Error(
|
|
130
|
+
`Codex app-server exited before ${request.method} completed (exit ${code ?? "unknown"}): ${stderr.trim()}`
|
|
131
|
+
)
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
writeJsonRpc({
|
|
137
|
+
jsonrpc: "2.0",
|
|
138
|
+
id: 1,
|
|
139
|
+
method: "initialize",
|
|
140
|
+
params: {
|
|
141
|
+
capabilities: {},
|
|
142
|
+
clientInfo: {
|
|
143
|
+
name: "aegis-agent",
|
|
144
|
+
version: "0.1.0"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
function handleMessage(message) {
|
|
150
|
+
if (message.id === 1) {
|
|
151
|
+
writeJsonRpc(request);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (message.id !== request.id) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
clearTimeout(timer);
|
|
158
|
+
if (message.error) {
|
|
159
|
+
finish(
|
|
160
|
+
reject,
|
|
161
|
+
new Error(
|
|
162
|
+
`Codex ${request.method} failed: ${message.error.message ?? JSON.stringify(message.error)}`
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
finish(resolve, message.result ?? {});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function writeJsonRpc(message) {
|
|
171
|
+
appServer.stdin.write(`${JSON.stringify(message)}\n`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function finish(callback, value) {
|
|
175
|
+
if (settled) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
settled = true;
|
|
179
|
+
clearTimeout(timer);
|
|
180
|
+
if (!appServer.killed) {
|
|
181
|
+
appServer.kill();
|
|
182
|
+
}
|
|
183
|
+
callback(value);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { writeCodexMarketplace } from "./codex.js";
|
|
6
|
+
import { codexMarketplaceFile } from "./codex-plugin.js";
|
|
7
|
+
import { aegisPaths } from "./config.js";
|
|
8
|
+
|
|
9
|
+
export function detectCodexHome() {
|
|
10
|
+
if (process.env.AEGIS_CODEX_HOME?.trim()) {
|
|
11
|
+
return process.env.AEGIS_CODEX_HOME.trim();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const result = spawnSync(
|
|
15
|
+
"snap",
|
|
16
|
+
["run", "--shell", "codex", "-c", "printf '%s' \"$HOME\""],
|
|
17
|
+
{
|
|
18
|
+
encoding: "utf8",
|
|
19
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
if (result.status !== 0) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const home = result.stdout.trim();
|
|
26
|
+
return home === "" ? null : home;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function prepareCodexPluginInstallTarget({
|
|
30
|
+
codexHome = detectCodexHome(),
|
|
31
|
+
userPaths
|
|
32
|
+
}) {
|
|
33
|
+
if (codexHome === null || samePath(codexHome, userPaths.homeDir)) {
|
|
34
|
+
await writeCodexMarketplace({
|
|
35
|
+
binaryPath: userPaths.binaryFile,
|
|
36
|
+
marketplaceDir: userPaths.codexMarketplaceDir
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
binaryFile: userPaths.binaryFile,
|
|
40
|
+
codexHome: userPaths.homeDir,
|
|
41
|
+
marketplaceFile: codexMarketplaceFile(userPaths),
|
|
42
|
+
mirrored: false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const codexPaths = aegisPaths(codexHome);
|
|
47
|
+
await copyExecutable(userPaths.binaryFile, codexPaths.binaryFile);
|
|
48
|
+
await copyPrivateFile(userPaths.configFile, codexPaths.configFile);
|
|
49
|
+
await copyPrivateFile(userPaths.credentialsFile, codexPaths.credentialsFile);
|
|
50
|
+
await writeCodexMarketplace({
|
|
51
|
+
binaryPath: codexPaths.binaryFile,
|
|
52
|
+
marketplaceDir: codexPaths.codexMarketplaceDir
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
binaryFile: codexPaths.binaryFile,
|
|
57
|
+
codexHome,
|
|
58
|
+
marketplaceFile: codexMarketplaceFile(codexPaths),
|
|
59
|
+
mirrored: true
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function samePath(left, right) {
|
|
64
|
+
return path.resolve(left) === path.resolve(right);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function copyExecutable(source, destination) {
|
|
68
|
+
await copyFile(source, destination);
|
|
69
|
+
const sourceMode = (await fs.stat(source)).mode & 0o777;
|
|
70
|
+
await fs.chmod(destination, sourceMode || 0o755);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function copyPrivateFile(source, destination) {
|
|
74
|
+
await copyFile(source, destination);
|
|
75
|
+
await fs.chmod(destination, 0o600);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function copyFile(source, destination) {
|
|
79
|
+
await fs.mkdir(path.dirname(destination), { recursive: true });
|
|
80
|
+
await fs.copyFile(source, destination);
|
|
81
|
+
}
|
package/npm/lib/codex.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
const HOOK_EVENTS = [
|
|
5
|
+
["SessionStart", "startup|resume|clear"],
|
|
6
|
+
["UserPromptSubmit", null],
|
|
7
|
+
["PreToolUse", "*"],
|
|
8
|
+
["PostToolUse", "*"],
|
|
9
|
+
["Stop", null]
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export function buildCodexMarketplace({ binaryPath }) {
|
|
13
|
+
const marketplace = {
|
|
14
|
+
interface: {
|
|
15
|
+
developerName: "Aegis Agentics",
|
|
16
|
+
displayName: "Aegis ControlTower",
|
|
17
|
+
shortDescription: "Governed telemetry for Codex agent sessions.",
|
|
18
|
+
websiteURL: "https://aegisagentics.com"
|
|
19
|
+
},
|
|
20
|
+
name: "aegis",
|
|
21
|
+
plugins: [
|
|
22
|
+
{
|
|
23
|
+
category: "Security",
|
|
24
|
+
name: "aegis",
|
|
25
|
+
policy: {
|
|
26
|
+
authentication: "ON_INSTALL",
|
|
27
|
+
installation: "AVAILABLE"
|
|
28
|
+
},
|
|
29
|
+
source: {
|
|
30
|
+
path: "./plugins/aegis",
|
|
31
|
+
source: "local"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const plugin = {
|
|
38
|
+
author: {
|
|
39
|
+
name: "Aegis Agentics",
|
|
40
|
+
url: "https://aegisagentics.com"
|
|
41
|
+
},
|
|
42
|
+
description: "Aegis ControlTower monitoring for Codex sessions, turns, and tools.",
|
|
43
|
+
displayName: "Aegis ControlTower",
|
|
44
|
+
homepage: "https://aegisagentics.com",
|
|
45
|
+
hooks: "./hooks/hooks.json",
|
|
46
|
+
interface: {
|
|
47
|
+
capabilities: ["Read"],
|
|
48
|
+
category: "Security",
|
|
49
|
+
developerName: "Aegis Agentics",
|
|
50
|
+
displayName: "Aegis ControlTower",
|
|
51
|
+
shortDescription: "Monitor Codex agent activity in Aegis ControlTower"
|
|
52
|
+
},
|
|
53
|
+
keywords: ["aegis", "controltower", "governance", "telemetry", "codex"],
|
|
54
|
+
license: "UNLICENSED",
|
|
55
|
+
name: "aegis",
|
|
56
|
+
repository: "https://github.com/aegisagentics/controltower",
|
|
57
|
+
version: "0.1.0"
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const hooks = buildCodexHooks({ binaryPath });
|
|
61
|
+
|
|
62
|
+
return { hooks, marketplace, plugin };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function buildCodexHooks({ binaryPath }) {
|
|
66
|
+
return {
|
|
67
|
+
hooks: Object.fromEntries(
|
|
68
|
+
HOOK_EVENTS.map(([event, matcher]) => {
|
|
69
|
+
const group = {
|
|
70
|
+
hooks: [
|
|
71
|
+
{
|
|
72
|
+
command: `${binaryPath} hook --vendor=codex --event=${event}`,
|
|
73
|
+
timeout: event === "Stop" ? 30 : 10,
|
|
74
|
+
type: "command"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
if (matcher !== null) {
|
|
79
|
+
group.matcher = matcher;
|
|
80
|
+
}
|
|
81
|
+
return [event, [group]];
|
|
82
|
+
})
|
|
83
|
+
)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function writeCodexMarketplace({ binaryPath, marketplaceDir }) {
|
|
88
|
+
const { hooks, marketplace, plugin } = buildCodexMarketplace({ binaryPath });
|
|
89
|
+
const marketplaceFile = path.join(marketplaceDir, ".agents", "plugins", "marketplace.json");
|
|
90
|
+
const pluginFile = path.join(marketplaceDir, "plugins", "aegis", ".codex-plugin", "plugin.json");
|
|
91
|
+
const hooksFile = path.join(marketplaceDir, "plugins", "aegis", "hooks", "hooks.json");
|
|
92
|
+
|
|
93
|
+
await fs.mkdir(path.dirname(marketplaceFile), { recursive: true });
|
|
94
|
+
await fs.mkdir(path.dirname(pluginFile), { recursive: true });
|
|
95
|
+
await fs.mkdir(path.dirname(hooksFile), { recursive: true });
|
|
96
|
+
|
|
97
|
+
await writeJson(marketplaceFile, marketplace);
|
|
98
|
+
await writeJson(pluginFile, plugin);
|
|
99
|
+
await writeJson(hooksFile, hooks);
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
hooksFile,
|
|
103
|
+
marketplaceFile,
|
|
104
|
+
pluginFile
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function writeJson(filePath, payload) {
|
|
109
|
+
await fs.writeFile(filePath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
110
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
const VENDOR_ALIASES = new Map([
|
|
4
|
+
["cc", "claude-code"],
|
|
5
|
+
["claude", "claude-code"],
|
|
6
|
+
["claude-code", "claude-code"],
|
|
7
|
+
["claudecode", "claude-code"],
|
|
8
|
+
["codex", "codex"],
|
|
9
|
+
["cursor", "cursor"],
|
|
10
|
+
["goose", "goose"]
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
const VENDOR_ORDER = ["codex", "claude-code", "cursor", "goose"];
|
|
14
|
+
|
|
15
|
+
export function normalizeVendorList(value) {
|
|
16
|
+
const raw = Array.isArray(value) ? value : String(value ?? "").split(",");
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
|
|
19
|
+
for (const item of raw) {
|
|
20
|
+
const key = String(item).trim().toLowerCase();
|
|
21
|
+
if (key === "" || key === "all") {
|
|
22
|
+
if (key === "all") {
|
|
23
|
+
for (const vendor of VENDOR_ORDER) {
|
|
24
|
+
seen.add(vendor);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const normalized = VENDOR_ALIASES.get(key);
|
|
30
|
+
if (normalized === undefined) {
|
|
31
|
+
throw new Error(`Unknown Aegis agent vendor: ${item}`);
|
|
32
|
+
}
|
|
33
|
+
seen.add(normalized);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return VENDOR_ORDER.filter((vendor) => seen.has(vendor));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function aegisPaths(homeDir = process.env.HOME) {
|
|
40
|
+
if (!homeDir) {
|
|
41
|
+
throw new Error("Unable to resolve home directory for Aegis agent install.");
|
|
42
|
+
}
|
|
43
|
+
const configDir = path.join(homeDir, ".config", "aegis-agent");
|
|
44
|
+
const dataDir = path.join(homeDir, ".local", "share", "aegis-agent");
|
|
45
|
+
const binaryDir = path.join(dataDir, "bin");
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
binaryDir,
|
|
49
|
+
binaryFile: path.join(binaryDir, "aegis-agent"),
|
|
50
|
+
codexMarketplaceDir: path.join(dataDir, "codex-marketplace"),
|
|
51
|
+
configDir,
|
|
52
|
+
configFile: path.join(configDir, "config.json"),
|
|
53
|
+
credentialsFile: path.join(configDir, "credentials.json"),
|
|
54
|
+
dataDir,
|
|
55
|
+
homeDir,
|
|
56
|
+
queueDir: path.join(dataDir, "queue")
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function buildLocalConfig({
|
|
61
|
+
agentId,
|
|
62
|
+
apiBaseUrl,
|
|
63
|
+
capturePolicy,
|
|
64
|
+
installationId,
|
|
65
|
+
activityLogEndpoint,
|
|
66
|
+
otlpHttpBaseUrl,
|
|
67
|
+
otlpTracesEndpoint,
|
|
68
|
+
organizationId,
|
|
69
|
+
workspaceId,
|
|
70
|
+
workspaceKind
|
|
71
|
+
}) {
|
|
72
|
+
const normalizedApiBaseUrl = String(apiBaseUrl).replace(/\/+$/, "");
|
|
73
|
+
const normalizedOtlpHttpBaseUrl =
|
|
74
|
+
otlpHttpBaseUrl === undefined || otlpHttpBaseUrl === null || String(otlpHttpBaseUrl).trim() === ""
|
|
75
|
+
? undefined
|
|
76
|
+
: String(otlpHttpBaseUrl).trim().replace(/\/+$/, "");
|
|
77
|
+
const normalizedOtlpTracesEndpoint =
|
|
78
|
+
otlpTracesEndpoint === undefined || otlpTracesEndpoint === null || String(otlpTracesEndpoint).trim() === ""
|
|
79
|
+
? normalizedOtlpHttpBaseUrl === undefined
|
|
80
|
+
? undefined
|
|
81
|
+
: `${normalizedOtlpHttpBaseUrl}/v1/traces`
|
|
82
|
+
: String(otlpTracesEndpoint).trim().replace(/\/+$/, "");
|
|
83
|
+
if (normalizedOtlpTracesEndpoint === undefined) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
"OTLP HTTP base URL is required; pass otlpHttpBaseUrl or otlpTracesEndpoint"
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const normalizedActivityLogEndpoint =
|
|
89
|
+
activityLogEndpoint === undefined || activityLogEndpoint === null || String(activityLogEndpoint).trim() === ""
|
|
90
|
+
? `${normalizedApiBaseUrl}/v1/agent-activity/logs`
|
|
91
|
+
: String(activityLogEndpoint).trim().replace(/\/+$/, "");
|
|
92
|
+
return {
|
|
93
|
+
schemaVersion: "aegis.agent_config.v1",
|
|
94
|
+
agentId,
|
|
95
|
+
apiBaseUrl: normalizedApiBaseUrl,
|
|
96
|
+
activityLogEndpoint: normalizedActivityLogEndpoint,
|
|
97
|
+
captureEndpoint: `${normalizedApiBaseUrl}/v1/capture/artifacts`,
|
|
98
|
+
capturePolicy,
|
|
99
|
+
installationId,
|
|
100
|
+
organizationId,
|
|
101
|
+
otlpHttpBaseUrl: normalizedOtlpHttpBaseUrl,
|
|
102
|
+
otlpTracesEndpoint: normalizedOtlpTracesEndpoint,
|
|
103
|
+
workspaceId,
|
|
104
|
+
workspaceKind
|
|
105
|
+
};
|
|
106
|
+
}
|