@agentrix/shared 2.10.0 → 2.13.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/dist/{errors-CjePCqwd.d.cts → errors-B5CcMP8s.d.cts} +36 -5
- package/dist/gitlabWebhook.cjs +22 -0
- package/dist/gitlabWebhook.d.cts +8 -0
- package/dist/gitlabWebhook.mjs +19 -0
- package/dist/index.cjs +243 -4
- package/dist/index.d.cts +388 -4
- package/dist/node.cjs +302 -1
- package/dist/node.d.cts +77 -3
- package/package.json +6 -1
package/dist/node.cjs
CHANGED
|
@@ -4,6 +4,8 @@ var node_fs = require('node:fs');
|
|
|
4
4
|
var node_path = require('node:path');
|
|
5
5
|
var errors = require('./errors-myQvpVrM.cjs');
|
|
6
6
|
var os = require('node:os');
|
|
7
|
+
var gitlabWebhook = require('./gitlabWebhook.cjs');
|
|
8
|
+
var node_crypto = require('node:crypto');
|
|
7
9
|
require('zod');
|
|
8
10
|
|
|
9
11
|
function _interopNamespaceDefault(e) {
|
|
@@ -213,11 +215,14 @@ async function loadSystemPrompt(claudeDir, promptFile) {
|
|
|
213
215
|
}
|
|
214
216
|
}
|
|
215
217
|
function replacePromptPlaceholders(template, cwd, extra) {
|
|
218
|
+
const now = /* @__PURE__ */ new Date();
|
|
216
219
|
const vars = {
|
|
217
220
|
WORKING_DIR: cwd,
|
|
218
221
|
PLATFORM: process.platform,
|
|
219
222
|
OS_VERSION: `${os__namespace.type()} ${os__namespace.release()}`,
|
|
220
|
-
DATE:
|
|
223
|
+
DATE: now.toISOString().split("T")[0],
|
|
224
|
+
TIME: now.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit", hour12: false }),
|
|
225
|
+
TIMEZONE: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
221
226
|
...extra
|
|
222
227
|
};
|
|
223
228
|
let result = template.replace(
|
|
@@ -234,6 +239,296 @@ function replacePromptPlaceholders(template, cwd, extra) {
|
|
|
234
239
|
return result;
|
|
235
240
|
}
|
|
236
241
|
|
|
242
|
+
const ALGORITHM = "aes-256-gcm";
|
|
243
|
+
const DEFAULT_PAT_VALIDATE_TIMEOUT_MS = 1e4;
|
|
244
|
+
const DEFAULT_GITLAB_PAT_REQUIRED_SCOPES = ["api", "read_repository", "write_repository"];
|
|
245
|
+
function hmacSha512(key, data) {
|
|
246
|
+
const hmac = node_crypto.createHmac("sha512", key);
|
|
247
|
+
hmac.update(data);
|
|
248
|
+
return new Uint8Array(hmac.digest());
|
|
249
|
+
}
|
|
250
|
+
function deriveLocalGitServerEncryptionKey(masterSecret) {
|
|
251
|
+
const decoded = Buffer.from(masterSecret, "base64");
|
|
252
|
+
const rootSeedKey = new TextEncoder().encode("Agentrix EnCoder Master Seed");
|
|
253
|
+
const rootI = hmacSha512(rootSeedKey, decoded);
|
|
254
|
+
const chainCode = rootI.slice(32);
|
|
255
|
+
const childData = new Uint8Array([0, ...new TextEncoder().encode("content")]);
|
|
256
|
+
const childI = hmacSha512(chainCode, childData);
|
|
257
|
+
return childI.slice(0, 32);
|
|
258
|
+
}
|
|
259
|
+
function parseScopes(rawScopes) {
|
|
260
|
+
if (!rawScopes) return [];
|
|
261
|
+
return rawScopes.split(",").map((scope) => scope.trim()).filter(Boolean);
|
|
262
|
+
}
|
|
263
|
+
function makeFailedResult(status, error, extras = {}) {
|
|
264
|
+
return { valid: false, status, error, ...extras };
|
|
265
|
+
}
|
|
266
|
+
function validateRequiredScopes(scopes, requiredScopes) {
|
|
267
|
+
if (!requiredScopes.length) return [];
|
|
268
|
+
const actual = new Set(scopes);
|
|
269
|
+
return requiredScopes.filter((scope) => !actual.has(scope));
|
|
270
|
+
}
|
|
271
|
+
async function fetchPatSelfInfo(apiUrl, pat, timeoutMs, log) {
|
|
272
|
+
let response;
|
|
273
|
+
try {
|
|
274
|
+
response = await fetch(`${apiUrl}/personal_access_tokens/self`, {
|
|
275
|
+
headers: { Authorization: `Bearer ${pat}` },
|
|
276
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
277
|
+
});
|
|
278
|
+
} catch (err) {
|
|
279
|
+
log?.warn?.("[PAT] Failed to fetch PAT expiry:", err);
|
|
280
|
+
return void 0;
|
|
281
|
+
}
|
|
282
|
+
if (!response.ok) {
|
|
283
|
+
return void 0;
|
|
284
|
+
}
|
|
285
|
+
try {
|
|
286
|
+
const tokenInfo = await response.json();
|
|
287
|
+
return {
|
|
288
|
+
expiresAt: tokenInfo.expires_at ?? void 0,
|
|
289
|
+
scopes: Array.isArray(tokenInfo.scopes) ? tokenInfo.scopes.map((scope) => scope.trim()).filter(Boolean) : void 0
|
|
290
|
+
};
|
|
291
|
+
} catch (err) {
|
|
292
|
+
log?.warn?.("[PAT] Failed to parse PAT self response:", err);
|
|
293
|
+
return void 0;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async function validateGitLabPatToken(apiUrl, pat, options = {}) {
|
|
297
|
+
const requiredScopes = options.requiredScopes ?? DEFAULT_GITLAB_PAT_REQUIRED_SCOPES;
|
|
298
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_PAT_VALIDATE_TIMEOUT_MS;
|
|
299
|
+
if (!pat.trim()) {
|
|
300
|
+
return { result: makeFailedResult("invalid", "Token is empty") };
|
|
301
|
+
}
|
|
302
|
+
let response;
|
|
303
|
+
try {
|
|
304
|
+
response = await fetch(`${apiUrl}/user`, {
|
|
305
|
+
headers: { Authorization: `Bearer ${pat}` },
|
|
306
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
307
|
+
});
|
|
308
|
+
} catch (err) {
|
|
309
|
+
options.log?.error?.("[PAT] GitLab API validation failed:", err);
|
|
310
|
+
return { result: makeFailedResult("network_error", `Cannot reach GitLab: ${err.message}`) };
|
|
311
|
+
}
|
|
312
|
+
if (!response.ok) {
|
|
313
|
+
if (response.status === 401 || response.status === 403) {
|
|
314
|
+
return { result: makeFailedResult("expired", `GitLab returned ${response.status}`) };
|
|
315
|
+
}
|
|
316
|
+
return { result: makeFailedResult("invalid", `GitLab returned ${response.status}`) };
|
|
317
|
+
}
|
|
318
|
+
let user;
|
|
319
|
+
try {
|
|
320
|
+
user = await response.json();
|
|
321
|
+
} catch {
|
|
322
|
+
return { result: makeFailedResult("invalid", "GitLab returned an invalid response") };
|
|
323
|
+
}
|
|
324
|
+
if (!user?.username) {
|
|
325
|
+
return { result: makeFailedResult("invalid", "GitLab response missing username") };
|
|
326
|
+
}
|
|
327
|
+
const scopesFromHeader = parseScopes(response.headers.get("x-oauth-scopes"));
|
|
328
|
+
const selfInfo = await fetchPatSelfInfo(apiUrl, pat, timeoutMs, options.log);
|
|
329
|
+
const scopesFromSelf = selfInfo?.scopes ?? [];
|
|
330
|
+
const effectiveScopes = scopesFromHeader.length > 0 ? scopesFromHeader : scopesFromSelf;
|
|
331
|
+
const expiresAt = selfInfo?.expiresAt;
|
|
332
|
+
const shouldEnforceScopes = effectiveScopes.length > 0;
|
|
333
|
+
const missingScopes = shouldEnforceScopes ? validateRequiredScopes(effectiveScopes, requiredScopes) : [];
|
|
334
|
+
if (shouldEnforceScopes && missingScopes.length > 0) {
|
|
335
|
+
return {
|
|
336
|
+
result: makeFailedResult(
|
|
337
|
+
"insufficient_scope",
|
|
338
|
+
`Token is missing required scopes: ${missingScopes.join(", ")}`,
|
|
339
|
+
{ username: user.username, scopes: effectiveScopes, missingScopes, expiresAt }
|
|
340
|
+
),
|
|
341
|
+
user
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
result: { valid: true, status: "valid", username: user.username, scopes: effectiveScopes, expiresAt },
|
|
346
|
+
user
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
class GitServerLocalStore {
|
|
350
|
+
credentialsDir;
|
|
351
|
+
constructor(options) {
|
|
352
|
+
this.credentialsDir = options.credentialsDir;
|
|
353
|
+
}
|
|
354
|
+
ensureCredentialsDir() {
|
|
355
|
+
if (!node_fs.existsSync(this.credentialsDir)) {
|
|
356
|
+
node_fs.mkdirSync(this.credentialsDir, { recursive: true });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
getPatFilePath(gitServerId) {
|
|
360
|
+
return node_path.join(this.credentialsDir, `${gitServerId}.pat.enc`);
|
|
361
|
+
}
|
|
362
|
+
getPatMetaFilePath(gitServerId) {
|
|
363
|
+
return node_path.join(this.credentialsDir, `${gitServerId}.pat.meta.json`);
|
|
364
|
+
}
|
|
365
|
+
getGitServerConfigFilePath(gitServerId) {
|
|
366
|
+
return node_path.join(this.credentialsDir, `${gitServerId}.git-server.json`);
|
|
367
|
+
}
|
|
368
|
+
getGitLabWebhookBridgeFilePath(gitServerId) {
|
|
369
|
+
return node_path.join(this.credentialsDir, `${gitServerId}.gitlab-webhook.enc`);
|
|
370
|
+
}
|
|
371
|
+
encryptJsonFile(filePath, value, encryptionKey) {
|
|
372
|
+
this.ensureCredentialsDir();
|
|
373
|
+
const iv = node_crypto.randomBytes(16);
|
|
374
|
+
const key = encryptionKey.slice(0, 32);
|
|
375
|
+
const cipher = node_crypto.createCipheriv(ALGORITHM, key, iv);
|
|
376
|
+
let encrypted = cipher.update(JSON.stringify(value), "utf8", "hex");
|
|
377
|
+
encrypted += cipher.final("hex");
|
|
378
|
+
const authTag = cipher.getAuthTag();
|
|
379
|
+
const payload = {
|
|
380
|
+
iv: iv.toString("hex"),
|
|
381
|
+
authTag: authTag.toString("hex"),
|
|
382
|
+
encrypted
|
|
383
|
+
};
|
|
384
|
+
node_fs.writeFileSync(filePath, JSON.stringify(payload), { mode: 384 });
|
|
385
|
+
}
|
|
386
|
+
decryptJsonFile(filePath, encryptionKey) {
|
|
387
|
+
if (!node_fs.existsSync(filePath)) return null;
|
|
388
|
+
try {
|
|
389
|
+
const raw = node_fs.readFileSync(filePath, "utf8");
|
|
390
|
+
const { iv, authTag, encrypted } = JSON.parse(raw);
|
|
391
|
+
const key = encryptionKey.slice(0, 32);
|
|
392
|
+
const decipher = node_crypto.createDecipheriv(ALGORITHM, key, Buffer.from(iv, "hex"));
|
|
393
|
+
decipher.setAuthTag(Buffer.from(authTag, "hex"));
|
|
394
|
+
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
|
395
|
+
decrypted += decipher.final("utf8");
|
|
396
|
+
return JSON.parse(decrypted);
|
|
397
|
+
} catch {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
saveGitServerConfig(gitServerId, input) {
|
|
402
|
+
this.ensureCredentialsDir();
|
|
403
|
+
const existing = this.loadGitServerConfig(gitServerId) ?? {};
|
|
404
|
+
const next = {
|
|
405
|
+
...existing,
|
|
406
|
+
...input
|
|
407
|
+
};
|
|
408
|
+
node_fs.writeFileSync(this.getGitServerConfigFilePath(gitServerId), JSON.stringify(next, null, 2), { mode: 384 });
|
|
409
|
+
}
|
|
410
|
+
loadGitServerConfig(gitServerId) {
|
|
411
|
+
const filePath = this.getGitServerConfigFilePath(gitServerId);
|
|
412
|
+
if (!node_fs.existsSync(filePath)) return null;
|
|
413
|
+
try {
|
|
414
|
+
return JSON.parse(node_fs.readFileSync(filePath, "utf8"));
|
|
415
|
+
} catch {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
deleteGitServerConfig(gitServerId) {
|
|
420
|
+
const configPath = this.getGitServerConfigFilePath(gitServerId);
|
|
421
|
+
if (node_fs.existsSync(configPath)) {
|
|
422
|
+
node_fs.unlinkSync(configPath);
|
|
423
|
+
}
|
|
424
|
+
const bridgePath = this.getGitLabWebhookBridgeFilePath(gitServerId);
|
|
425
|
+
if (node_fs.existsSync(bridgePath)) {
|
|
426
|
+
node_fs.unlinkSync(bridgePath);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
listGitServerIds() {
|
|
430
|
+
this.ensureCredentialsDir();
|
|
431
|
+
const ids = /* @__PURE__ */ new Set();
|
|
432
|
+
for (const file of node_fs.readdirSync(this.credentialsDir)) {
|
|
433
|
+
if (file.endsWith(".git-server.json")) {
|
|
434
|
+
ids.add(file.slice(0, -".git-server.json".length));
|
|
435
|
+
} else if (file.endsWith(".pat.enc")) {
|
|
436
|
+
ids.add(file.slice(0, -".pat.enc".length));
|
|
437
|
+
} else if (file.endsWith(".gitlab-webhook.enc")) {
|
|
438
|
+
ids.add(file.slice(0, -".gitlab-webhook.enc".length));
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return [...ids].sort();
|
|
442
|
+
}
|
|
443
|
+
listPats() {
|
|
444
|
+
this.ensureCredentialsDir();
|
|
445
|
+
const files = node_fs.readdirSync(this.credentialsDir).filter((file) => file.endsWith(".pat.enc"));
|
|
446
|
+
return files.map((file) => ({
|
|
447
|
+
gitServerId: file.replace(".pat.enc", ""),
|
|
448
|
+
exists: true
|
|
449
|
+
}));
|
|
450
|
+
}
|
|
451
|
+
loadGitLabWebhookBridgeSecrets(gitServerId, encryptionKey) {
|
|
452
|
+
return this.decryptJsonFile(
|
|
453
|
+
this.getGitLabWebhookBridgeFilePath(gitServerId),
|
|
454
|
+
encryptionKey
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
saveGitLabWebhookBridgeSecrets(gitServerId, secrets, encryptionKey) {
|
|
458
|
+
this.encryptJsonFile(this.getGitLabWebhookBridgeFilePath(gitServerId), secrets, encryptionKey);
|
|
459
|
+
}
|
|
460
|
+
ensureGitLabWebhookSecret(gitServerId, encryptionKey) {
|
|
461
|
+
const current = this.loadGitLabWebhookBridgeSecrets(gitServerId, encryptionKey);
|
|
462
|
+
if (current?.webhookSecret) {
|
|
463
|
+
return current.webhookSecret;
|
|
464
|
+
}
|
|
465
|
+
const webhookSecret = node_crypto.randomBytes(32).toString("hex");
|
|
466
|
+
this.saveGitLabWebhookBridgeSecrets(gitServerId, {
|
|
467
|
+
...current ?? {},
|
|
468
|
+
webhookSecret,
|
|
469
|
+
projectTriggerTokens: current?.projectTriggerTokens ?? {}
|
|
470
|
+
}, encryptionKey);
|
|
471
|
+
return webhookSecret;
|
|
472
|
+
}
|
|
473
|
+
loadPatMeta(gitServerId) {
|
|
474
|
+
const filePath = this.getPatMetaFilePath(gitServerId);
|
|
475
|
+
if (!node_fs.existsSync(filePath)) return null;
|
|
476
|
+
try {
|
|
477
|
+
return JSON.parse(node_fs.readFileSync(filePath, "utf8"));
|
|
478
|
+
} catch {
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
savePatMeta(gitServerId, meta) {
|
|
483
|
+
this.ensureCredentialsDir();
|
|
484
|
+
node_fs.writeFileSync(this.getPatMetaFilePath(gitServerId), JSON.stringify(meta, null, 2), { mode: 384 });
|
|
485
|
+
}
|
|
486
|
+
savePat(gitServerId, pat, encryptionKey) {
|
|
487
|
+
this.ensureCredentialsDir();
|
|
488
|
+
const iv = node_crypto.randomBytes(16);
|
|
489
|
+
const key = encryptionKey.slice(0, 32);
|
|
490
|
+
const cipher = node_crypto.createCipheriv(ALGORITHM, key, iv);
|
|
491
|
+
let encrypted = cipher.update(pat, "utf8", "hex");
|
|
492
|
+
encrypted += cipher.final("hex");
|
|
493
|
+
const authTag = cipher.getAuthTag();
|
|
494
|
+
const payload = {
|
|
495
|
+
iv: iv.toString("hex"),
|
|
496
|
+
authTag: authTag.toString("hex"),
|
|
497
|
+
encrypted
|
|
498
|
+
};
|
|
499
|
+
node_fs.writeFileSync(this.getPatFilePath(gitServerId), JSON.stringify(payload), { mode: 384 });
|
|
500
|
+
}
|
|
501
|
+
loadPat(gitServerId, encryptionKey) {
|
|
502
|
+
const filePath = this.getPatFilePath(gitServerId);
|
|
503
|
+
if (!node_fs.existsSync(filePath)) return null;
|
|
504
|
+
try {
|
|
505
|
+
const raw = node_fs.readFileSync(filePath, "utf8");
|
|
506
|
+
const { iv, authTag, encrypted } = JSON.parse(raw);
|
|
507
|
+
const key = encryptionKey.slice(0, 32);
|
|
508
|
+
const decipher = node_crypto.createDecipheriv(ALGORITHM, key, Buffer.from(iv, "hex"));
|
|
509
|
+
decipher.setAuthTag(Buffer.from(authTag, "hex"));
|
|
510
|
+
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
|
511
|
+
decrypted += decipher.final("utf8");
|
|
512
|
+
return decrypted;
|
|
513
|
+
} catch {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
hasPat(gitServerId) {
|
|
518
|
+
return node_fs.existsSync(this.getPatFilePath(gitServerId));
|
|
519
|
+
}
|
|
520
|
+
deletePat(gitServerId) {
|
|
521
|
+
const filePath = this.getPatFilePath(gitServerId);
|
|
522
|
+
if (node_fs.existsSync(filePath)) {
|
|
523
|
+
node_fs.unlinkSync(filePath);
|
|
524
|
+
}
|
|
525
|
+
const metaPath = this.getPatMetaFilePath(gitServerId);
|
|
526
|
+
if (node_fs.existsSync(metaPath)) {
|
|
527
|
+
node_fs.unlinkSync(metaPath);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
237
532
|
exports.AgentConfigValidationError = errors.AgentConfigValidationError;
|
|
238
533
|
exports.AgentError = errors.AgentError;
|
|
239
534
|
exports.AgentLoadError = errors.AgentLoadError;
|
|
@@ -245,10 +540,16 @@ exports.FrameworkNotSupportedError = errors.FrameworkNotSupportedError;
|
|
|
245
540
|
exports.MissingAgentFileError = errors.MissingAgentFileError;
|
|
246
541
|
exports.getAgentContext = errors.getAgentContext;
|
|
247
542
|
exports.setAgentContext = errors.setAgentContext;
|
|
543
|
+
exports.buildGitLabWebhookEndpointPath = gitlabWebhook.buildGitLabWebhookEndpointPath;
|
|
544
|
+
exports.buildGitLabWebhookUrl = gitlabWebhook.buildGitLabWebhookUrl;
|
|
545
|
+
exports.DEFAULT_GITLAB_PAT_REQUIRED_SCOPES = DEFAULT_GITLAB_PAT_REQUIRED_SCOPES;
|
|
546
|
+
exports.GitServerLocalStore = GitServerLocalStore;
|
|
248
547
|
exports.assertAgentExists = assertAgentExists;
|
|
249
548
|
exports.assertFileExists = assertFileExists;
|
|
549
|
+
exports.deriveLocalGitServerEncryptionKey = deriveLocalGitServerEncryptionKey;
|
|
250
550
|
exports.discoverPlugins = discoverPlugins;
|
|
251
551
|
exports.loadAgentConfig = loadAgentConfig;
|
|
252
552
|
exports.replacePromptPlaceholders = replacePromptPlaceholders;
|
|
253
553
|
exports.validateAgentDirectory = validateAgentDirectory;
|
|
254
554
|
exports.validateFrameworkDirectory = validateFrameworkDirectory;
|
|
555
|
+
exports.validateGitLabPatToken = validateGitLabPatToken;
|
package/dist/node.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { dE as LoadAgentOptions, dC as AgentConfig, dD as ValidationResult, dz as FrameworkType } from './errors-B5CcMP8s.cjs';
|
|
2
|
+
export { dM as AgentConfigValidationError, dv as AgentContext, dK as AgentError, dO as AgentLoadError, dA as AgentMetadata, dI as AgentMetadataSchema, dL as AgentNotFoundError, dw as AgentrixContext, dB as ClaudeAgentConfig, dJ as ClaudeConfigSchema, dH as FRAMEWORK_TYPES, dN as FrameworkNotSupportedError, dG as HookFactory, dP as MissingAgentFileError, dF as RepositoryInitHookInput, dy as getAgentContext, dx as setAgentContext } from './errors-B5CcMP8s.cjs';
|
|
3
|
+
export { buildGitLabWebhookEndpointPath, buildGitLabWebhookUrl } from './gitlabWebhook.cjs';
|
|
3
4
|
import '@anthropic-ai/claude-agent-sdk';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
@@ -49,4 +50,77 @@ declare function assertAgentExists(agentDir: string, agentId: string): void;
|
|
|
49
50
|
*/
|
|
50
51
|
declare function discoverPlugins(pluginsDir: string): string[];
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
declare const DEFAULT_GITLAB_PAT_REQUIRED_SCOPES: readonly ["api", "read_repository", "write_repository"];
|
|
54
|
+
interface GitServerLocalConfig {
|
|
55
|
+
baseUrl?: string;
|
|
56
|
+
apiUrl?: string;
|
|
57
|
+
}
|
|
58
|
+
interface GitLabWebhookBridgeSecrets {
|
|
59
|
+
webhookSecret?: string;
|
|
60
|
+
projectTriggerTokens?: Record<string, string>;
|
|
61
|
+
}
|
|
62
|
+
interface PatMeta {
|
|
63
|
+
username: string;
|
|
64
|
+
email: string;
|
|
65
|
+
lastValidatedAt?: string;
|
|
66
|
+
expiresAt?: string | null;
|
|
67
|
+
}
|
|
68
|
+
interface PatValidationResult {
|
|
69
|
+
valid: boolean;
|
|
70
|
+
status: 'valid' | 'invalid' | 'expired' | 'insufficient_scope' | 'network_error';
|
|
71
|
+
username?: string;
|
|
72
|
+
scopes?: string[];
|
|
73
|
+
missingScopes?: string[];
|
|
74
|
+
expiresAt?: string | null;
|
|
75
|
+
error?: string;
|
|
76
|
+
}
|
|
77
|
+
interface GitServerLocalStoreOptions {
|
|
78
|
+
credentialsDir: string;
|
|
79
|
+
}
|
|
80
|
+
interface GitLabPatValidationOptions {
|
|
81
|
+
requiredScopes?: readonly string[];
|
|
82
|
+
timeoutMs?: number;
|
|
83
|
+
log?: {
|
|
84
|
+
warn?: (message: string, error?: unknown) => void;
|
|
85
|
+
error?: (message: string, error?: unknown) => void;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
declare function deriveLocalGitServerEncryptionKey(masterSecret: string): Uint8Array;
|
|
89
|
+
declare function validateGitLabPatToken(apiUrl: string, pat: string, options?: GitLabPatValidationOptions): Promise<{
|
|
90
|
+
result: PatValidationResult;
|
|
91
|
+
user?: {
|
|
92
|
+
username: string;
|
|
93
|
+
email?: string;
|
|
94
|
+
};
|
|
95
|
+
}>;
|
|
96
|
+
declare class GitServerLocalStore {
|
|
97
|
+
private readonly credentialsDir;
|
|
98
|
+
constructor(options: GitServerLocalStoreOptions);
|
|
99
|
+
private ensureCredentialsDir;
|
|
100
|
+
private getPatFilePath;
|
|
101
|
+
private getPatMetaFilePath;
|
|
102
|
+
private getGitServerConfigFilePath;
|
|
103
|
+
private getGitLabWebhookBridgeFilePath;
|
|
104
|
+
private encryptJsonFile;
|
|
105
|
+
private decryptJsonFile;
|
|
106
|
+
saveGitServerConfig(gitServerId: string, input: GitServerLocalConfig): void;
|
|
107
|
+
loadGitServerConfig(gitServerId: string): GitServerLocalConfig | null;
|
|
108
|
+
deleteGitServerConfig(gitServerId: string): void;
|
|
109
|
+
listGitServerIds(): string[];
|
|
110
|
+
listPats(): Array<{
|
|
111
|
+
gitServerId: string;
|
|
112
|
+
exists: boolean;
|
|
113
|
+
}>;
|
|
114
|
+
loadGitLabWebhookBridgeSecrets(gitServerId: string, encryptionKey: Uint8Array): GitLabWebhookBridgeSecrets | null;
|
|
115
|
+
saveGitLabWebhookBridgeSecrets(gitServerId: string, secrets: GitLabWebhookBridgeSecrets, encryptionKey: Uint8Array): void;
|
|
116
|
+
ensureGitLabWebhookSecret(gitServerId: string, encryptionKey: Uint8Array): string;
|
|
117
|
+
loadPatMeta(gitServerId: string): PatMeta | null;
|
|
118
|
+
savePatMeta(gitServerId: string, meta: PatMeta): void;
|
|
119
|
+
savePat(gitServerId: string, pat: string, encryptionKey: Uint8Array): void;
|
|
120
|
+
loadPat(gitServerId: string, encryptionKey: Uint8Array): string | null;
|
|
121
|
+
hasPat(gitServerId: string): boolean;
|
|
122
|
+
deletePat(gitServerId: string): void;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { AgentConfig, DEFAULT_GITLAB_PAT_REQUIRED_SCOPES, FrameworkType, GitServerLocalStore, LoadAgentOptions, ValidationResult, assertAgentExists, assertFileExists, deriveLocalGitServerEncryptionKey, discoverPlugins, loadAgentConfig, replacePromptPlaceholders, validateAgentDirectory, validateFrameworkDirectory, validateGitLabPatToken };
|
|
126
|
+
export type { GitLabPatValidationOptions, GitLabWebhookBridgeSecrets, GitServerLocalConfig, GitServerLocalStoreOptions, PatMeta, PatValidationResult };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentrix/shared",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Shared types and schemas for Agentrix projects",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"types": "./dist/index.d.cts",
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"./node": {
|
|
13
13
|
"types": "./dist/node.d.cts",
|
|
14
14
|
"default": "./dist/node.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./gitlab-webhook": {
|
|
17
|
+
"types": "./dist/gitlabWebhook.d.cts",
|
|
18
|
+
"import": "./dist/gitlabWebhook.mjs",
|
|
19
|
+
"default": "./dist/gitlabWebhook.cjs"
|
|
15
20
|
}
|
|
16
21
|
},
|
|
17
22
|
"scripts": {
|