@team-ai/teamai-cli 0.30.4 → 0.30.5
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/cli.js
CHANGED
|
@@ -61601,6 +61601,7 @@ __export(local_agent_exports, {
|
|
|
61601
61601
|
import fs35 from "fs";
|
|
61602
61602
|
import os9 from "os";
|
|
61603
61603
|
import path76 from "path";
|
|
61604
|
+
import { createHash as createHash10 } from "crypto";
|
|
61604
61605
|
import { execFile as execFile4 } from "child_process";
|
|
61605
61606
|
import { promisify as promisify3 } from "util";
|
|
61606
61607
|
function modelAgentKind(tool) {
|
|
@@ -61640,6 +61641,65 @@ async function acquireLocalAgentLock(waitMs = 0) {
|
|
|
61640
61641
|
function getConfigPath() {
|
|
61641
61642
|
return path76.join(getLocalAgentHome(), CONFIG_FILE);
|
|
61642
61643
|
}
|
|
61644
|
+
function credentialKey(context) {
|
|
61645
|
+
const agentType = normalizeAgentType(context.tool ?? "workbuddy");
|
|
61646
|
+
return `${agentType}:${resolveLocalAgentId(context)}`;
|
|
61647
|
+
}
|
|
61648
|
+
function credentialEndpointDir(endpoint) {
|
|
61649
|
+
const endpointDigest = createHash10("sha256").update(normalizeEndpoint(endpoint)).digest("hex").slice(0, 16);
|
|
61650
|
+
return path76.join("credentials", endpointDigest);
|
|
61651
|
+
}
|
|
61652
|
+
function credentialRelativePath(endpoint, key) {
|
|
61653
|
+
const digest = createHash10("sha256").update(key).digest("hex");
|
|
61654
|
+
return path76.join(credentialEndpointDir(endpoint), `${digest}.token`);
|
|
61655
|
+
}
|
|
61656
|
+
async function readAgentCredential(config, context) {
|
|
61657
|
+
const entry = context ? config.agentCredentials?.[credentialKey(context)] : void 0;
|
|
61658
|
+
const candidate = entry ?? (!context ? Object.values(config.agentCredentials ?? {})[0] : void 0);
|
|
61659
|
+
if (candidate) {
|
|
61660
|
+
const credentialRoot = path76.join(getLocalAgentHome(), "credentials");
|
|
61661
|
+
const credentialPath = path76.resolve(getLocalAgentHome(), candidate.file);
|
|
61662
|
+
if (!credentialPath.startsWith(credentialRoot + path76.sep)) {
|
|
61663
|
+
throw new Error("HTTP local agent credential path is outside its credential directory.");
|
|
61664
|
+
}
|
|
61665
|
+
const value = (await readFileSafe(credentialPath))?.trim();
|
|
61666
|
+
if (value) return value;
|
|
61667
|
+
throw new Error(`HTTP local agent credential is missing for ${candidate.agentType}. Re-run HTTP setup for that agent.`);
|
|
61668
|
+
}
|
|
61669
|
+
const legacy = config.token?.trim();
|
|
61670
|
+
if (legacy) return legacy;
|
|
61671
|
+
if (context && Object.keys(config.agentCredentials ?? {}).length > 0) {
|
|
61672
|
+
throw new Error(
|
|
61673
|
+
`No HTTP credential is configured for ${normalizeAgentType(context.tool ?? "workbuddy")}. Re-run HTTP setup with this agent and its token.`
|
|
61674
|
+
);
|
|
61675
|
+
}
|
|
61676
|
+
return void 0;
|
|
61677
|
+
}
|
|
61678
|
+
async function writeAgentCredential(config, context, token) {
|
|
61679
|
+
const key = credentialKey(context);
|
|
61680
|
+
const tool = context.tool ?? "workbuddy";
|
|
61681
|
+
const agentType = normalizeAgentType(tool);
|
|
61682
|
+
const localAgentId = resolveLocalAgentId(context);
|
|
61683
|
+
const file = credentialRelativePath(config.endpoint, key);
|
|
61684
|
+
await ensureDir(path76.join(getLocalAgentHome(), path76.dirname(file)));
|
|
61685
|
+
await writeTokenFile(path76.join(getLocalAgentHome(), file), token);
|
|
61686
|
+
config.agentCredentials = {
|
|
61687
|
+
...config.agentCredentials,
|
|
61688
|
+
[key]: {
|
|
61689
|
+
tool,
|
|
61690
|
+
agentType,
|
|
61691
|
+
localAgentId,
|
|
61692
|
+
file,
|
|
61693
|
+
createdAt: config.agentCredentials?.[key]?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
61694
|
+
}
|
|
61695
|
+
};
|
|
61696
|
+
return key;
|
|
61697
|
+
}
|
|
61698
|
+
async function promoteLegacyCredential(config, context) {
|
|
61699
|
+
if (!config.token || config.agentCredentials?.[credentialKey(context)]) return;
|
|
61700
|
+
await writeAgentCredential(config, context, config.token);
|
|
61701
|
+
await saveLocalAgentConfig(config);
|
|
61702
|
+
}
|
|
61643
61703
|
function getManifestPath() {
|
|
61644
61704
|
return path76.join(getLocalAgentHome(), MANIFEST_FILE);
|
|
61645
61705
|
}
|
|
@@ -61821,6 +61881,8 @@ function mergeWorkspaceBindings(existing2, incoming, canonicalKey) {
|
|
|
61821
61881
|
}
|
|
61822
61882
|
const base = existingRank >= incomingRank ? { ...existing2 } : { ...incoming };
|
|
61823
61883
|
base.enrolledAt ??= existing2.enrolledAt ?? incoming.enrolledAt;
|
|
61884
|
+
const agentKeys = [.../* @__PURE__ */ new Set([...existing2.agentKeys ?? [], ...incoming.agentKeys ?? []])];
|
|
61885
|
+
if (agentKeys.length > 0) base.agentKeys = agentKeys;
|
|
61824
61886
|
if (!base.ideType) base.ideType = existing2.ideType ?? incoming.ideType;
|
|
61825
61887
|
return base;
|
|
61826
61888
|
}
|
|
@@ -62085,12 +62147,13 @@ async function workspaceCacheGitignore(workspacePath, repoPath) {
|
|
|
62085
62147
|
const file = path76.join(teamaiDir, ".gitignore");
|
|
62086
62148
|
return await readFileSafe(file) === WORKSPACE_CACHE_GITIGNORE ? file : null;
|
|
62087
62149
|
}
|
|
62088
|
-
function authHeaders5(config, json = true) {
|
|
62150
|
+
async function authHeaders5(config, json = true, context) {
|
|
62089
62151
|
const headers = {};
|
|
62090
62152
|
if (json) headers["Content-Type"] = "application/json";
|
|
62091
|
-
|
|
62092
|
-
|
|
62093
|
-
headers
|
|
62153
|
+
const token = await readAgentCredential(config, context);
|
|
62154
|
+
if (token) {
|
|
62155
|
+
headers.Authorization = `Bearer ${token}`;
|
|
62156
|
+
headers["X-API-Token"] = token;
|
|
62094
62157
|
}
|
|
62095
62158
|
return headers;
|
|
62096
62159
|
}
|
|
@@ -62098,7 +62161,7 @@ async function localAgentFetch(config, tag, route, init3, opts) {
|
|
|
62098
62161
|
const method = init3?.method ?? "GET";
|
|
62099
62162
|
const url = `${config.endpoint}${resolveRoute(config, route)}`;
|
|
62100
62163
|
const headers = {
|
|
62101
|
-
...authHeaders5(config, init3?.body !== void 0),
|
|
62164
|
+
...await authHeaders5(config, init3?.body !== void 0, opts?.context),
|
|
62102
62165
|
...init3?.headers
|
|
62103
62166
|
};
|
|
62104
62167
|
logHttpRequest(tag, method, url, headers, init3?.body);
|
|
@@ -62134,12 +62197,13 @@ async function appendErrorLog(entry) {
|
|
|
62134
62197
|
} catch {
|
|
62135
62198
|
}
|
|
62136
62199
|
}
|
|
62137
|
-
async function fetchUserProjects(config) {
|
|
62200
|
+
async function fetchUserProjects(config, context) {
|
|
62138
62201
|
const response = await localAgentFetch(
|
|
62139
62202
|
config,
|
|
62140
62203
|
localAgentTag({}),
|
|
62141
62204
|
"projects",
|
|
62142
|
-
{ method: "GET" }
|
|
62205
|
+
{ method: "GET" },
|
|
62206
|
+
{ context }
|
|
62143
62207
|
);
|
|
62144
62208
|
return response.projects ?? [];
|
|
62145
62209
|
}
|
|
@@ -62181,8 +62245,14 @@ async function execPluginCommand(cmd, timeoutMs) {
|
|
|
62181
62245
|
);
|
|
62182
62246
|
});
|
|
62183
62247
|
}
|
|
62184
|
-
async function fetchPluginConfig(config, tag) {
|
|
62185
|
-
return localAgentFetch(
|
|
62248
|
+
async function fetchPluginConfig(config, tag, context) {
|
|
62249
|
+
return localAgentFetch(
|
|
62250
|
+
config,
|
|
62251
|
+
tag,
|
|
62252
|
+
"getConfig",
|
|
62253
|
+
{ method: "GET" },
|
|
62254
|
+
{ redactResponseLog: true, context }
|
|
62255
|
+
);
|
|
62186
62256
|
}
|
|
62187
62257
|
function getPluginPullStatePath() {
|
|
62188
62258
|
return path76.join(getLocalAgentHome(), "plugin-pull.json");
|
|
@@ -62220,7 +62290,16 @@ async function maybeReconcilePlugins(context) {
|
|
|
62220
62290
|
const child = spawn13(
|
|
62221
62291
|
process.execPath,
|
|
62222
62292
|
[process.argv[1], "source", "reconcile-plugins"],
|
|
62223
|
-
{
|
|
62293
|
+
{
|
|
62294
|
+
detached: true,
|
|
62295
|
+
windowsHide: true,
|
|
62296
|
+
stdio: "ignore",
|
|
62297
|
+
env: {
|
|
62298
|
+
...process.env,
|
|
62299
|
+
TEAMAI_PLUGIN_LOCAL_AGENT_ID: localAgentId,
|
|
62300
|
+
TEAMAI_PLUGIN_TOOL: tool
|
|
62301
|
+
}
|
|
62302
|
+
}
|
|
62224
62303
|
);
|
|
62225
62304
|
child.unref();
|
|
62226
62305
|
} catch (e) {
|
|
@@ -62236,7 +62315,8 @@ async function runPluginReconcileWorker() {
|
|
|
62236
62315
|
const tag = "[local-agent] [plugin-reconcile]";
|
|
62237
62316
|
const statePath = getPluginPullStatePath();
|
|
62238
62317
|
try {
|
|
62239
|
-
const
|
|
62318
|
+
const context = { tool: process.env.TEAMAI_PLUGIN_TOOL ?? "workbuddy" };
|
|
62319
|
+
const resp = await fetchPluginConfig(config, tag, context);
|
|
62240
62320
|
const { vars, plugins } = parseGetConfig(resp);
|
|
62241
62321
|
const declaredSlugs = plugins.length ? ` [${plugins.map((p2) => p2.slug).join(", ")}]` : "";
|
|
62242
62322
|
log.debug(`${tag} get-config: ${plugins.length} plugin(s) declared${declaredSlugs}`);
|
|
@@ -62317,10 +62397,20 @@ async function persistWorkspaceBinding(config, cwd, resolvedPath, projectId, pro
|
|
|
62317
62397
|
}
|
|
62318
62398
|
await saveLocalAgentConfig(config);
|
|
62319
62399
|
}
|
|
62320
|
-
async function enrollWorkspace(config, resolvedPath) {
|
|
62400
|
+
async function enrollWorkspace(config, resolvedPath, agentKeys = []) {
|
|
62321
62401
|
const enrolledAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
62322
62402
|
const binding = config.workspaceBindings[resolvedPath];
|
|
62323
|
-
|
|
62403
|
+
const mergedAgentKeys = [.../* @__PURE__ */ new Set([...binding?.agentKeys ?? [], ...agentKeys])];
|
|
62404
|
+
config.workspaceBindings[resolvedPath] = binding ? {
|
|
62405
|
+
...binding,
|
|
62406
|
+
enrolledAt: binding.enrolledAt ?? enrolledAt,
|
|
62407
|
+
...mergedAgentKeys.length > 0 ? { agentKeys: mergedAgentKeys } : {}
|
|
62408
|
+
} : {
|
|
62409
|
+
projectId: 0,
|
|
62410
|
+
boundAt: enrolledAt,
|
|
62411
|
+
enrolledAt,
|
|
62412
|
+
...mergedAgentKeys.length > 0 ? { agentKeys: mergedAgentKeys } : {}
|
|
62413
|
+
};
|
|
62324
62414
|
}
|
|
62325
62415
|
async function inheritWorktreeBinding(config, cwd, resolvedPath) {
|
|
62326
62416
|
const anchors = await resolveAnchors(cwd);
|
|
@@ -62358,7 +62448,7 @@ async function bindWorkspaceToProject(workspacePath, projectId) {
|
|
|
62358
62448
|
log.success(`\u5DF2\u5C06\u5DE5\u4F5C\u533A\u7ED1\u5B9A\u5230\u9879\u76EE\uFF1A${project.name} [id=${project.id}]`);
|
|
62359
62449
|
return binding;
|
|
62360
62450
|
}
|
|
62361
|
-
async function ensureWorkspaceBinding(config, workspacePath, sessionId, cwd) {
|
|
62451
|
+
async function ensureWorkspaceBinding(config, workspacePath, agentContext, sessionId, cwd) {
|
|
62362
62452
|
if (!isWorkspaceEnrolled(config, workspacePath)) return;
|
|
62363
62453
|
if (hasWorkspaceBindingDecision(config.workspaceBindings[workspacePath])) return;
|
|
62364
62454
|
if (await inheritWorktreeBinding(config, cwd, workspacePath)) return;
|
|
@@ -62371,7 +62461,7 @@ async function ensureWorkspaceBinding(config, workspacePath, sessionId, cwd) {
|
|
|
62371
62461
|
}
|
|
62372
62462
|
let projects;
|
|
62373
62463
|
try {
|
|
62374
|
-
projects = await fetchUserProjects(config);
|
|
62464
|
+
projects = await fetchUserProjects(config, agentContext);
|
|
62375
62465
|
} catch (e) {
|
|
62376
62466
|
log.debug(`local-agent: failed to load user projects: ${e.message}`);
|
|
62377
62467
|
return;
|
|
@@ -62407,7 +62497,7 @@ function isBindPromptTool(tool) {
|
|
|
62407
62497
|
const kind = modelAgentKind(tool);
|
|
62408
62498
|
return kind === "codebuddy" || kind === "workbuddy";
|
|
62409
62499
|
}
|
|
62410
|
-
async function emitBindingHint(config, workspacePath, sessionId, cwd) {
|
|
62500
|
+
async function emitBindingHint(config, workspacePath, agentContext, sessionId, cwd) {
|
|
62411
62501
|
if (!isWorkspaceEnrolled(config, workspacePath)) return;
|
|
62412
62502
|
if (hasWorkspaceBindingDecision(config.workspaceBindings[workspacePath])) return;
|
|
62413
62503
|
if (await inheritWorktreeBinding(config, cwd, workspacePath)) return;
|
|
@@ -62420,7 +62510,7 @@ async function emitBindingHint(config, workspacePath, sessionId, cwd) {
|
|
|
62420
62510
|
}
|
|
62421
62511
|
let projects;
|
|
62422
62512
|
try {
|
|
62423
|
-
projects = await fetchUserProjects(config);
|
|
62513
|
+
projects = await fetchUserProjects(config, agentContext);
|
|
62424
62514
|
} catch {
|
|
62425
62515
|
return;
|
|
62426
62516
|
}
|
|
@@ -62634,14 +62724,19 @@ function stampWorkspaceTool(config, currentPath, tool) {
|
|
|
62634
62724
|
const binding = config.workspaceBindings[currentPath];
|
|
62635
62725
|
if (!binding?.enrolledAt) return false;
|
|
62636
62726
|
const normalized = normalizeAgentType(tool);
|
|
62637
|
-
|
|
62727
|
+
const key = credentialKey({ tool });
|
|
62728
|
+
const agentKeys = binding.agentKeys ?? [];
|
|
62729
|
+
if (binding.ideType === normalized && agentKeys.includes(key)) return false;
|
|
62638
62730
|
binding.ideType = normalized;
|
|
62731
|
+
binding.agentKeys = [.../* @__PURE__ */ new Set([...agentKeys, key])];
|
|
62639
62732
|
return true;
|
|
62640
62733
|
}
|
|
62641
62734
|
function selectToolWorkspaces(config, currentPath, currentTool) {
|
|
62642
62735
|
return Object.keys(config.workspaceBindings).filter((wsPath) => {
|
|
62643
62736
|
const b2 = config.workspaceBindings[wsPath];
|
|
62644
62737
|
if (!b2.enrolledAt) return false;
|
|
62738
|
+
const key = credentialKey({ tool: currentTool });
|
|
62739
|
+
if (b2.agentKeys?.includes(key)) return true;
|
|
62645
62740
|
const wsTool = b2.ideType ?? (wsPath === currentPath ? currentTool : void 0);
|
|
62646
62741
|
return wsTool === currentTool;
|
|
62647
62742
|
});
|
|
@@ -63399,7 +63494,7 @@ async function hookDeliveryProblem(teamConfig, localConfig2, tool, block) {
|
|
|
63399
63494
|
const length = parts.filter(Boolean).join("\n\n").length;
|
|
63400
63495
|
return length > hook.limit ? `${tool} cannot load this project's instructions: with the HTTP prompts they are ${length} characters, over the ${hook.limit}-character limit of its prompt section, so ${tool} skips them. Shorten the prompts for this project.` : null;
|
|
63401
63496
|
}
|
|
63402
|
-
async function ackCommand(config, tag, command, status2, version2, error2) {
|
|
63497
|
+
async function ackCommand(config, tag, context, command, status2, version2, error2) {
|
|
63403
63498
|
await localAgentFetch(config, tag, "ack", {
|
|
63404
63499
|
method: "POST",
|
|
63405
63500
|
body: JSON.stringify({
|
|
@@ -63409,7 +63504,7 @@ async function ackCommand(config, tag, command, status2, version2, error2) {
|
|
|
63409
63504
|
error: error2 ?? "",
|
|
63410
63505
|
version: version2
|
|
63411
63506
|
})
|
|
63412
|
-
});
|
|
63507
|
+
}, { context });
|
|
63413
63508
|
}
|
|
63414
63509
|
function requireModelString(value, field) {
|
|
63415
63510
|
if (typeof value !== "string" || !value.trim()) {
|
|
@@ -64386,7 +64481,7 @@ async function processCommands(config, commands, context) {
|
|
|
64386
64481
|
}
|
|
64387
64482
|
try {
|
|
64388
64483
|
const version2 = await executeCommand(config, command, context);
|
|
64389
|
-
await ackCommand(config, tag, command, "success", version2);
|
|
64484
|
+
await ackCommand(config, tag, context, command, "success", version2);
|
|
64390
64485
|
if (command.type === "apply_model_config") modelConfigApplied = true;
|
|
64391
64486
|
log.debug(`${tag} command ${command.id} (${command.type ?? ""}) succeeded`);
|
|
64392
64487
|
if (command.type === "uninstall_teamai") {
|
|
@@ -64397,7 +64492,7 @@ async function processCommands(config, commands, context) {
|
|
|
64397
64492
|
const error2 = e.message;
|
|
64398
64493
|
log.error(`${tag} command ${command.id} failed: ${error2}`);
|
|
64399
64494
|
try {
|
|
64400
|
-
await ackCommand(config, tag, command, "failed", void 0, error2);
|
|
64495
|
+
await ackCommand(config, tag, context, command, "failed", void 0, error2);
|
|
64401
64496
|
} catch (ackError) {
|
|
64402
64497
|
log.debug(`${tag} failed to ack command ${command.id}: ${ackError.message}`);
|
|
64403
64498
|
}
|
|
@@ -64428,10 +64523,10 @@ async function syncLocalAgent(context) {
|
|
|
64428
64523
|
if (workspacePath && isWorkspaceEnrolled(config, workspacePath)) {
|
|
64429
64524
|
const sid = context.event?.sessionId;
|
|
64430
64525
|
if (context.event?.type === "session_start") {
|
|
64431
|
-
await ensureWorkspaceBinding(config, workspacePath, sid, context.cwd);
|
|
64526
|
+
await ensureWorkspaceBinding(config, workspacePath, context, sid, context.cwd);
|
|
64432
64527
|
}
|
|
64433
64528
|
if (context.event?.type === "prompt_submit") {
|
|
64434
|
-
await emitBindingHint(config, workspacePath, sid, context.cwd);
|
|
64529
|
+
await emitBindingHint(config, workspacePath, context, sid, context.cwd);
|
|
64435
64530
|
}
|
|
64436
64531
|
}
|
|
64437
64532
|
}
|
|
@@ -64460,7 +64555,8 @@ async function syncLocalAgent(context) {
|
|
|
64460
64555
|
await localAgentFetch(config, tag, "report", {
|
|
64461
64556
|
method: "POST",
|
|
64462
64557
|
body: JSON.stringify(reportPayload)
|
|
64463
|
-
});
|
|
64558
|
+
}, { context });
|
|
64559
|
+
await promoteLegacyCredential(config, context);
|
|
64464
64560
|
log.debug(`${tag} report OK`);
|
|
64465
64561
|
}
|
|
64466
64562
|
const syncPayload = await buildSyncPayload(config, context);
|
|
@@ -64469,7 +64565,7 @@ async function syncLocalAgent(context) {
|
|
|
64469
64565
|
tag,
|
|
64470
64566
|
"sync",
|
|
64471
64567
|
{ method: "POST", body: JSON.stringify(syncPayload) },
|
|
64472
|
-
{ redactResponseLog: true }
|
|
64568
|
+
{ redactResponseLog: true, context }
|
|
64473
64569
|
);
|
|
64474
64570
|
const cmds = syncResponse.cmds;
|
|
64475
64571
|
const commands = cmds && cmds.length > 0 ? cmds : syncResponse.commands ?? [];
|
|
@@ -64482,7 +64578,7 @@ async function syncLocalAgent(context) {
|
|
|
64482
64578
|
await localAgentFetch(config, tag, "report", {
|
|
64483
64579
|
method: "POST",
|
|
64484
64580
|
body: JSON.stringify(reportPayload)
|
|
64485
|
-
});
|
|
64581
|
+
}, { context });
|
|
64486
64582
|
log.debug(`${tag} model config report OK`);
|
|
64487
64583
|
}
|
|
64488
64584
|
}
|
|
@@ -64611,8 +64707,16 @@ async function reportAndSyncFromHook(stdin, tool) {
|
|
|
64611
64707
|
}
|
|
64612
64708
|
}
|
|
64613
64709
|
async function writeTokenFile(tokenPath, token) {
|
|
64614
|
-
await
|
|
64615
|
-
|
|
64710
|
+
await ensureDir(path76.dirname(tokenPath));
|
|
64711
|
+
const tmp = `${tokenPath}.${process.pid}.${createHash10("sha256").update(`${tokenPath}:${Date.now()}:${Math.random()}`).digest("hex").slice(0, 12)}.tmp`;
|
|
64712
|
+
try {
|
|
64713
|
+
await fs35.promises.writeFile(tmp, token + "\n", { mode: 384, flag: "wx" });
|
|
64714
|
+
await fs35.promises.chmod(tmp, 384);
|
|
64715
|
+
await fs35.promises.rename(tmp, tokenPath);
|
|
64716
|
+
} catch (error2) {
|
|
64717
|
+
await fs35.promises.rm(tmp, { force: true }).catch(() => void 0);
|
|
64718
|
+
throw error2;
|
|
64719
|
+
}
|
|
64616
64720
|
}
|
|
64617
64721
|
async function initLocalAgentHttp(options2) {
|
|
64618
64722
|
const endpoint = normalizeEndpoint(options2.endpoint);
|
|
@@ -64623,20 +64727,45 @@ async function initLocalAgentHttp(options2) {
|
|
|
64623
64727
|
if (existing2 && !options2.force && normalizeEndpoint(existing2.endpoint) !== endpoint) {
|
|
64624
64728
|
throw new Error("HTTP local agent is initialized with another endpoint. Re-run with --force to overwrite.");
|
|
64625
64729
|
}
|
|
64730
|
+
const requestedAgents = [...new Set((options2.filterAgents ?? []).map((agent) => agent.trim()).filter(Boolean))];
|
|
64731
|
+
if (options2.token?.startsWith("sk-") && requestedAgents.length !== 1) {
|
|
64732
|
+
throw new Error("A ClawPro instance token requires exactly one --agent.");
|
|
64733
|
+
}
|
|
64734
|
+
const sameEndpoint = Boolean(existing2 && normalizeEndpoint(existing2.endpoint) === endpoint);
|
|
64626
64735
|
const config = {
|
|
64627
64736
|
endpoint,
|
|
64628
|
-
token
|
|
64629
|
-
|
|
64737
|
+
// A token without --agent keeps the legacy machine-wide behavior. An
|
|
64738
|
+
// agent-scoped setup writes a credential file below and must not replace it.
|
|
64739
|
+
token: requestedAgents.length !== 1 ? options2.token ?? (sameEndpoint ? existing2?.token : void 0) : sameEndpoint ? existing2?.token : void 0,
|
|
64740
|
+
agentCredentials: sameEndpoint ? existing2?.agentCredentials : void 0,
|
|
64741
|
+
createdAt: sameEndpoint ? existing2?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
64630
64742
|
workspaceStateVersion: 1,
|
|
64631
|
-
workspaceBindings: existing2?.workspaceBindings ?? {},
|
|
64632
|
-
userGroupId: existing2?.userGroupId,
|
|
64633
|
-
userGroupName: existing2?.userGroupName
|
|
64634
|
-
|
|
64743
|
+
workspaceBindings: sameEndpoint ? existing2?.workspaceBindings ?? {} : {},
|
|
64744
|
+
userGroupId: sameEndpoint ? existing2?.userGroupId : void 0,
|
|
64745
|
+
userGroupName: sameEndpoint ? existing2?.userGroupName : void 0,
|
|
64746
|
+
routes: sameEndpoint ? existing2?.routes : void 0
|
|
64747
|
+
};
|
|
64748
|
+
const configuredKeys = [];
|
|
64749
|
+
if (requestedAgents.length === 1 && options2.token) {
|
|
64750
|
+
configuredKeys.push(await writeAgentCredential(
|
|
64751
|
+
config,
|
|
64752
|
+
{ tool: requestedAgents[0] },
|
|
64753
|
+
options2.token
|
|
64754
|
+
));
|
|
64755
|
+
} else if (requestedAgents.length === 1) {
|
|
64756
|
+
const key = credentialKey({ tool: requestedAgents[0] });
|
|
64757
|
+
if (config.agentCredentials?.[key]) configuredKeys.push(key);
|
|
64758
|
+
}
|
|
64635
64759
|
const workspacePath = await resolveWorkspacePath(options2.workspacePath ?? process.cwd());
|
|
64636
|
-
if (workspacePath) await enrollWorkspace(config, workspacePath);
|
|
64760
|
+
if (workspacePath) await enrollWorkspace(config, workspacePath, configuredKeys);
|
|
64637
64761
|
await ensureDir(getLocalAgentHome());
|
|
64638
64762
|
await saveLocalAgentConfig(config);
|
|
64639
|
-
if (
|
|
64763
|
+
if (existing2 && !sameEndpoint) {
|
|
64764
|
+
await remove(path76.join(getLocalAgentHome(), credentialEndpointDir(existing2.endpoint))).catch((error2) => {
|
|
64765
|
+
log.warn(`Could not remove credentials for the previous HTTP endpoint: ${error2.message}`);
|
|
64766
|
+
});
|
|
64767
|
+
}
|
|
64768
|
+
if (options2.token && requestedAgents.length !== 1) {
|
|
64640
64769
|
await writeTokenFile(getTokenPath(), options2.token);
|
|
64641
64770
|
}
|
|
64642
64771
|
const teamConfig = createLocalAgentTeamConfig(endpoint);
|
|
@@ -65242,7 +65371,7 @@ __export(git_exclude_delivered_exports, {
|
|
|
65242
65371
|
describeUnreadableGitExcludeSetting: () => describeUnreadableGitExcludeSetting,
|
|
65243
65372
|
reportDeliveredGitExclude: () => reportDeliveredGitExclude
|
|
65244
65373
|
});
|
|
65245
|
-
import { createHash as
|
|
65374
|
+
import { createHash as createHash11 } from "crypto";
|
|
65246
65375
|
import path79 from "path";
|
|
65247
65376
|
function createDeliveryRecorder() {
|
|
65248
65377
|
const reports = /* @__PURE__ */ new Map();
|
|
@@ -65293,7 +65422,7 @@ function deliveredOwnerElsewhere(localConfig2) {
|
|
|
65293
65422
|
}
|
|
65294
65423
|
function partitionId(localConfig2) {
|
|
65295
65424
|
const dataHome = getDataHome(localConfig2);
|
|
65296
|
-
return /-([0-9a-f]{16})$/.exec(path79.basename(dataHome))?.[1] ??
|
|
65425
|
+
return /-([0-9a-f]{16})$/.exec(path79.basename(dataHome))?.[1] ?? createHash11("sha256").update(path79.resolve(dataHome)).digest("hex").slice(0, 16);
|
|
65297
65426
|
}
|
|
65298
65427
|
function partitionOwner(localConfig2, name) {
|
|
65299
65428
|
return {
|
|
@@ -66046,15 +66175,19 @@ async function initHttp(url, options2) {
|
|
|
66046
66175
|
await reconcileHooksForInit(teamConfig, localConfig2, filterAgents2);
|
|
66047
66176
|
const { initLocalAgentHttp: initLocalAgentHttp2 } = await Promise.resolve().then(() => (init_local_agent(), local_agent_exports));
|
|
66048
66177
|
try {
|
|
66178
|
+
const explicitLocalAgentToken = options2.token?.trim() || process.env.TEAMAI_API_TOKEN?.trim() || process.env.TEAMAI_API_KEY?.trim();
|
|
66049
66179
|
await initLocalAgentHttp2({
|
|
66050
66180
|
endpoint: url,
|
|
66051
|
-
token:
|
|
66181
|
+
token: explicitLocalAgentToken || (filterAgents2 ? void 0 : apiKey),
|
|
66052
66182
|
force: options2.force,
|
|
66053
66183
|
filterAgents: filterAgents2,
|
|
66054
66184
|
workspacePath: projectRoot ?? process.cwd()
|
|
66055
66185
|
});
|
|
66056
66186
|
} catch (e) {
|
|
66057
|
-
log.
|
|
66187
|
+
log.error(`Local agent init failed: ${e.message}`);
|
|
66188
|
+
process.exitCode = 1;
|
|
66189
|
+
closePrompt();
|
|
66190
|
+
return;
|
|
66058
66191
|
}
|
|
66059
66192
|
await runInitScript(localConfig2, "postInit", options2.dryRun, true);
|
|
66060
66193
|
log.success("teamai initialized (HTTP read-only)!");
|
|
@@ -67395,7 +67528,7 @@ __export(learnings_publish_exports, {
|
|
|
67395
67528
|
publishLearningsMaintenance: () => publishLearningsMaintenance,
|
|
67396
67529
|
publishQueuedLearnings: () => publishQueuedLearnings
|
|
67397
67530
|
});
|
|
67398
|
-
import { createHash as
|
|
67531
|
+
import { createHash as createHash12 } from "crypto";
|
|
67399
67532
|
import path83 from "path";
|
|
67400
67533
|
import fs40 from "fs";
|
|
67401
67534
|
function commitMessageFor(username) {
|
|
@@ -67596,7 +67729,7 @@ async function hasUncommittedChange(checkout, rel) {
|
|
|
67596
67729
|
}
|
|
67597
67730
|
async function contentDigest(file) {
|
|
67598
67731
|
if (!fs40.existsSync(file)) return null;
|
|
67599
|
-
return
|
|
67732
|
+
return createHash12("sha256").update(await fs40.promises.readFile(file)).digest("hex");
|
|
67600
67733
|
}
|
|
67601
67734
|
async function maintenanceRecordsDir(checkout) {
|
|
67602
67735
|
const gitPath2 = (await createGitWithBlockTimeout(checkout).raw(["rev-parse", "--git-path", "teamai-maintenance"])).trim();
|
|
@@ -71050,7 +71183,7 @@ var init_definition = __esm({
|
|
|
71050
71183
|
});
|
|
71051
71184
|
|
|
71052
71185
|
// src/scorers/cache.ts
|
|
71053
|
-
import { createHash as
|
|
71186
|
+
import { createHash as createHash13 } from "crypto";
|
|
71054
71187
|
import fs48 from "fs/promises";
|
|
71055
71188
|
import path95 from "path";
|
|
71056
71189
|
function cacheDir(config) {
|
|
@@ -71193,7 +71326,7 @@ async function syncScorerDefinitions(config, options2 = {}) {
|
|
|
71193
71326
|
}
|
|
71194
71327
|
const { name } = parsed.definition;
|
|
71195
71328
|
if (parsed.definition.isolation === "verified") result.verified.push(relativePath);
|
|
71196
|
-
const sourceHash =
|
|
71329
|
+
const sourceHash = createHash13("sha256").update(content).digest("hex");
|
|
71197
71330
|
const revision = await (reachable ??= remotelyReachableRevision(knowledgeRoot));
|
|
71198
71331
|
const holds = await revisionHoldsSources(knowledgeRoot, revision, [{ path: relativePath, content }]);
|
|
71199
71332
|
const previous = await withoutStaleTeamRevision(knowledgeRoot, await readCache2(config, name));
|
|
@@ -74358,7 +74491,7 @@ __export(cache_exports, {
|
|
|
74358
74491
|
syncWorkflowDefinitions: () => syncWorkflowDefinitions,
|
|
74359
74492
|
workflowsRunBy: () => workflowsRunBy
|
|
74360
74493
|
});
|
|
74361
|
-
import { createHash as
|
|
74494
|
+
import { createHash as createHash14 } from "crypto";
|
|
74362
74495
|
import fs49 from "fs/promises";
|
|
74363
74496
|
import os11 from "os";
|
|
74364
74497
|
import path97 from "path";
|
|
@@ -74563,7 +74696,7 @@ async function syncWorkflowDefinitions(config, options2 = {}) {
|
|
|
74563
74696
|
checked.push({ stem, relativePath, diagnostics: resolved2.diagnostics });
|
|
74564
74697
|
continue;
|
|
74565
74698
|
}
|
|
74566
|
-
const hash2 =
|
|
74699
|
+
const hash2 = createHash14("sha256").update(content);
|
|
74567
74700
|
for (const source of resolved2.sources) {
|
|
74568
74701
|
hash2.update("\0").update(source.path).update("\0").update(source.content);
|
|
74569
74702
|
}
|
|
@@ -74700,7 +74833,7 @@ async function loadWorkflowTree(config, cached) {
|
|
|
74700
74833
|
if (failed4) return { failed: failed4 };
|
|
74701
74834
|
const teamRevision = cached.teamRevision !== void 0 && revisions.every((revision) => revision === cached.teamRevision) ? cached.teamRevision : void 0;
|
|
74702
74835
|
if (hashes.length === 0) return { workflows, sourceHash: cached.sourceHash, ...teamRevision ? { teamRevision } : {} };
|
|
74703
|
-
const hash2 =
|
|
74836
|
+
const hash2 = createHash14("sha256").update(cached.sourceHash);
|
|
74704
74837
|
for (const [name, sourceHash] of hashes.sort(([left], [right]) => left.localeCompare(right))) {
|
|
74705
74838
|
hash2.update("\0").update(name).update("\0").update(sourceHash);
|
|
74706
74839
|
}
|
|
@@ -77195,7 +77328,7 @@ __export(team_push_exports, {
|
|
|
77195
77328
|
withDroppedRollouts: () => withDroppedRollouts
|
|
77196
77329
|
});
|
|
77197
77330
|
import fs55 from "fs";
|
|
77198
|
-
import { createHash as
|
|
77331
|
+
import { createHash as createHash15 } from "crypto";
|
|
77199
77332
|
import path105 from "path";
|
|
77200
77333
|
async function readExistingStats(statsPath) {
|
|
77201
77334
|
try {
|
|
@@ -77364,7 +77497,7 @@ function tokenDelta(cur, prev) {
|
|
|
77364
77497
|
};
|
|
77365
77498
|
}
|
|
77366
77499
|
function segmentKey(transcript2) {
|
|
77367
|
-
return
|
|
77500
|
+
return createHash15("sha256").update(transcript2).digest("hex").slice(0, 16);
|
|
77368
77501
|
}
|
|
77369
77502
|
function reportedSegments(entry) {
|
|
77370
77503
|
const segments2 = {};
|
|
@@ -78236,7 +78369,7 @@ var init_delivery_schema = __esm({
|
|
|
78236
78369
|
});
|
|
78237
78370
|
|
|
78238
78371
|
// src/workflow/snapshot.ts
|
|
78239
|
-
import { createHash as
|
|
78372
|
+
import { createHash as createHash16 } from "crypto";
|
|
78240
78373
|
import fs56 from "fs";
|
|
78241
78374
|
import path106 from "path";
|
|
78242
78375
|
function withCommitIds(schema) {
|
|
@@ -78253,7 +78386,7 @@ function snapshotText(snapshot) {
|
|
|
78253
78386
|
`;
|
|
78254
78387
|
}
|
|
78255
78388
|
function definitionHash(definition, workflows = {}) {
|
|
78256
|
-
return
|
|
78389
|
+
return createHash16("sha256").update(canonicalJson2({ definition, workflows })).digest("hex");
|
|
78257
78390
|
}
|
|
78258
78391
|
function snapshotBody(snapshot) {
|
|
78259
78392
|
const { snapshot: _format, run: _run, owner: _owner, ownedAt: _ownedAt, stateRevision: _revision, write: _write, ...body } = snapshot;
|
|
@@ -79216,7 +79349,7 @@ var init_records = __esm({
|
|
|
79216
79349
|
});
|
|
79217
79350
|
|
|
79218
79351
|
// src/scorers/label.ts
|
|
79219
|
-
import { createHash as
|
|
79352
|
+
import { createHash as createHash17 } from "crypto";
|
|
79220
79353
|
function sumUsage(first2, second) {
|
|
79221
79354
|
if (!first2 || !second) return first2 ?? second;
|
|
79222
79355
|
const tokens = (left, right) => left === void 0 && right === void 0 ? void 0 : (left ?? 0) + (right ?? 0);
|
|
@@ -79244,10 +79377,10 @@ function labelKey(label) {
|
|
|
79244
79377
|
return canonicalJson2({ scorer: label.scorer, sourceHash: label.rubric.sourceHash, subject: label.subject, judge: label.judge.kind });
|
|
79245
79378
|
}
|
|
79246
79379
|
function labelId(label) {
|
|
79247
|
-
return
|
|
79380
|
+
return createHash17("sha256").update(labelKey(label)).digest("hex");
|
|
79248
79381
|
}
|
|
79249
79382
|
function labelVersion(label) {
|
|
79250
|
-
return
|
|
79383
|
+
return createHash17("sha256").update(canonicalJson2(label)).digest("hex");
|
|
79251
79384
|
}
|
|
79252
79385
|
function newestLabels(labels) {
|
|
79253
79386
|
const newest = /* @__PURE__ */ new Map();
|
|
@@ -88979,7 +89112,7 @@ var init_scrub = __esm({
|
|
|
88979
89112
|
});
|
|
88980
89113
|
|
|
88981
89114
|
// src/session-flow/agent-session.ts
|
|
88982
|
-
import { createHash as
|
|
89115
|
+
import { createHash as createHash20 } from "crypto";
|
|
88983
89116
|
import fs77 from "fs";
|
|
88984
89117
|
import path129 from "path";
|
|
88985
89118
|
function noAdapter(platform3, use, os25 = process.platform) {
|
|
@@ -89061,7 +89194,7 @@ async function writeCopyOnce(target, { session, sourcePlatform, cwd }) {
|
|
|
89061
89194
|
} catch (e) {
|
|
89062
89195
|
return { status: "failed", failure: { code: "invalid_workspace", cwd, message: messageOf(e) } };
|
|
89063
89196
|
}
|
|
89064
|
-
const key =
|
|
89197
|
+
const key = createHash20("sha256").update(`${targetPlatform}\0${targetId}`).digest("hex").slice(0, 16);
|
|
89065
89198
|
const lockPath = path129.join(getTeamaiHomeDir(), "locks", `session-copy-${key}.lock`);
|
|
89066
89199
|
for (let attempt = 1; !await acquireLock(lockPath); attempt++) {
|
|
89067
89200
|
if (attempt === COPY_LOCK_ATTEMPTS) {
|
|
@@ -90269,12 +90402,12 @@ var init_settings = __esm({
|
|
|
90269
90402
|
});
|
|
90270
90403
|
|
|
90271
90404
|
// src/scorers/entry.ts
|
|
90272
|
-
import { createHash as
|
|
90405
|
+
import { createHash as createHash21 } from "crypto";
|
|
90273
90406
|
function entryIdOf(scorer, subject) {
|
|
90274
|
-
return `s${
|
|
90407
|
+
return `s${createHash21("sha256").update(canonicalJson2({ scorer, subject })).digest("hex").slice(0, 13)}`;
|
|
90275
90408
|
}
|
|
90276
90409
|
function sessionEntryIdOf(scorer, sourceHash, subject) {
|
|
90277
|
-
return `s${
|
|
90410
|
+
return `s${createHash21("sha256").update(canonicalJson2({ scorer, sourceHash, subject })).digest("hex").slice(0, 13)}`;
|
|
90278
90411
|
}
|
|
90279
90412
|
function isLeaseRef(value) {
|
|
90280
90413
|
return LEASE_REF.test(value);
|
|
@@ -90426,11 +90559,11 @@ var init_evidence = __esm({
|
|
|
90426
90559
|
});
|
|
90427
90560
|
|
|
90428
90561
|
// src/scorers/sampling.ts
|
|
90429
|
-
import { createHash as
|
|
90562
|
+
import { createHash as createHash22 } from "crypto";
|
|
90430
90563
|
function isSampled(scorer, subject, samplingRate) {
|
|
90431
90564
|
if (samplingRate <= 0) return false;
|
|
90432
90565
|
if (samplingRate >= 100) return true;
|
|
90433
|
-
const digest =
|
|
90566
|
+
const digest = createHash22("sha256").update(canonicalJson2({ scorer, ...subject })).digest();
|
|
90434
90567
|
return digest.readUInt32BE(0) % 1e4 < samplingRate * 100;
|
|
90435
90568
|
}
|
|
90436
90569
|
var init_sampling = __esm({
|
|
@@ -91094,7 +91227,7 @@ var init_workspace = __esm({
|
|
|
91094
91227
|
});
|
|
91095
91228
|
|
|
91096
91229
|
// src/workflow/worktree.ts
|
|
91097
|
-
import { createHash as
|
|
91230
|
+
import { createHash as createHash23 } from "crypto";
|
|
91098
91231
|
import { execFile as execFile6, spawn as spawn6 } from "child_process";
|
|
91099
91232
|
import fs83 from "fs/promises";
|
|
91100
91233
|
import path137 from "path";
|
|
@@ -91155,7 +91288,7 @@ function git(cwd, args, options2) {
|
|
|
91155
91288
|
}
|
|
91156
91289
|
function worktreePath2(main2, branch) {
|
|
91157
91290
|
const safe = branch.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-|-$/g, "") || "step";
|
|
91158
|
-
const hash2 =
|
|
91291
|
+
const hash2 = createHash23("sha256").update(branch).digest("hex").slice(0, 12);
|
|
91159
91292
|
return path137.join(main2, ".teamai", "workflow-worktrees", `${safe}-${hash2}`);
|
|
91160
91293
|
}
|
|
91161
91294
|
function stepCheckout(active, branch) {
|
|
@@ -92020,7 +92153,7 @@ var init_scoring_evidence = __esm({
|
|
|
92020
92153
|
import * as fs85 from "fs";
|
|
92021
92154
|
import * as path139 from "path";
|
|
92022
92155
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
92023
|
-
import { createHash as
|
|
92156
|
+
import { createHash as createHash24, randomUUID as randomUUID13 } from "crypto";
|
|
92024
92157
|
function utcNow() {
|
|
92025
92158
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
92026
92159
|
}
|
|
@@ -92152,7 +92285,7 @@ function assertNoSymlinkedAncestors(target, root) {
|
|
|
92152
92285
|
}
|
|
92153
92286
|
async function withSessionPublicationLock(repoRoot, fn) {
|
|
92154
92287
|
const real = await fs85.promises.realpath(repoRoot).catch(() => path139.resolve(repoRoot));
|
|
92155
|
-
const key =
|
|
92288
|
+
const key = createHash24("sha256").update(real).digest("hex").slice(0, 16);
|
|
92156
92289
|
const lockPath = path139.join(getTeamaiHomeDir(), "locks", `session-publish-${key}.lock`);
|
|
92157
92290
|
for (let attempt = 1; !await acquireLock(lockPath); attempt++) {
|
|
92158
92291
|
if (attempt === INDEX_LOCK_ATTEMPTS) return { status: "busy", lockPath };
|
|
@@ -92166,7 +92299,7 @@ async function withSessionPublicationLock(repoRoot, fn) {
|
|
|
92166
92299
|
}
|
|
92167
92300
|
async function withSessionIndexLock(repoRoot, fn) {
|
|
92168
92301
|
const real = await fs85.promises.realpath(repoRoot).catch(() => path139.resolve(repoRoot));
|
|
92169
|
-
const key =
|
|
92302
|
+
const key = createHash24("sha256").update(path139.join(real, "sessions")).digest("hex").slice(0, 16);
|
|
92170
92303
|
const lockPath = path139.join(getTeamaiHomeDir(), "locks", `sessions-${key}.lock`);
|
|
92171
92304
|
for (let attempt = 1; !await acquireLock(lockPath); attempt++) {
|
|
92172
92305
|
if (attempt === INDEX_LOCK_ATTEMPTS) return { status: "busy", lockPath };
|
|
@@ -106305,7 +106438,7 @@ __export(source_exports, {
|
|
|
106305
106438
|
sourceSyncWarnings: () => sourceSyncWarnings
|
|
106306
106439
|
});
|
|
106307
106440
|
import path158 from "path";
|
|
106308
|
-
import { createHash as
|
|
106441
|
+
import { createHash as createHash25 } from "crypto";
|
|
106309
106442
|
function sourceLockPath() {
|
|
106310
106443
|
return path158.join(getUserHome(), ".teamai", ".source-lifecycle-lock");
|
|
106311
106444
|
}
|
|
@@ -106345,7 +106478,7 @@ async function listSourceNames() {
|
|
|
106345
106478
|
}
|
|
106346
106479
|
}
|
|
106347
106480
|
function getSourceRepoId(source) {
|
|
106348
|
-
return
|
|
106481
|
+
return createHash25("sha256").update(source.repo.trim()).digest("hex");
|
|
106349
106482
|
}
|
|
106350
106483
|
function getSourceRepoCacheDir(source) {
|
|
106351
106484
|
return path158.join(getUserHome(), ".teamai", "source-repos", getSourceRepoId(source));
|
|
@@ -106367,7 +106500,7 @@ async function listInstallationRecords() {
|
|
|
106367
106500
|
return records2;
|
|
106368
106501
|
}
|
|
106369
106502
|
function getSourceManifestPath(sourceName, localConfig2) {
|
|
106370
|
-
const installationId =
|
|
106503
|
+
const installationId = createHash25("sha256").update(JSON.stringify([
|
|
106371
106504
|
path158.resolve(resolveBaseDir(localConfig2)),
|
|
106372
106505
|
path158.resolve(localConfig2.repo.localPath)
|
|
106373
106506
|
])).digest("hex");
|
|
@@ -106755,6 +106888,7 @@ async function sourceAddHttp(endpoint, options2) {
|
|
|
106755
106888
|
endpoint: trimmed2,
|
|
106756
106889
|
token: options2.token,
|
|
106757
106890
|
force: true,
|
|
106891
|
+
filterAgents: normalizeAgentList(options2.agent),
|
|
106758
106892
|
workspacePath: mainConfig?.projectRoot ?? process.cwd()
|
|
106759
106893
|
});
|
|
106760
106894
|
log.success(`HTTP source added (${trimmed2}).`);
|
|
@@ -107483,6 +107617,7 @@ var init_source2 = __esm({
|
|
|
107483
107617
|
init_builtin_skills();
|
|
107484
107618
|
init_home();
|
|
107485
107619
|
init_update();
|
|
107620
|
+
init_known_agents();
|
|
107486
107621
|
init_path_safety();
|
|
107487
107622
|
init_types5();
|
|
107488
107623
|
}
|
|
@@ -107994,13 +108129,13 @@ __export(builtin_skills_exports, {
|
|
|
107994
108129
|
skillsGuardBase: () => skillsGuardBase
|
|
107995
108130
|
});
|
|
107996
108131
|
import fs95 from "fs";
|
|
107997
|
-
import { createHash as
|
|
108132
|
+
import { createHash as createHash26 } from "crypto";
|
|
107998
108133
|
import path161 from "path";
|
|
107999
108134
|
function isCliOwnedSkillName(name) {
|
|
108000
108135
|
return BUILTIN_SKILL_NAMES.has(name) || LEGACY_BUILTIN_SKILL_NAMES.has(name);
|
|
108001
108136
|
}
|
|
108002
108137
|
function packagedSkillDigest(content) {
|
|
108003
|
-
return
|
|
108138
|
+
return createHash26("sha256").update(content).digest("hex");
|
|
108004
108139
|
}
|
|
108005
108140
|
async function ownedSkillFiles(skillName, paths) {
|
|
108006
108141
|
const owned = /* @__PURE__ */ new Map();
|
|
@@ -108126,7 +108261,7 @@ async function removeOwnedFiles(dir, owned, baseDir, backupDir) {
|
|
|
108126
108261
|
}
|
|
108127
108262
|
function skillBackupDir(baseDir, tool, skillRoot, skillName) {
|
|
108128
108263
|
const rootSlug = skillRoot.replace(/[\\/:]+/g, "-").replace(/^-+/, "");
|
|
108129
|
-
const baseSlug = `${path161.basename(baseDir) || "root"}-${
|
|
108264
|
+
const baseSlug = `${path161.basename(baseDir) || "root"}-${createHash26("sha256").update(baseDir).digest("hex").slice(0, 8)}`;
|
|
108130
108265
|
return path161.join(getUserHome(), ".teamai", "removed-skills", PRUNE_RUN_ID, baseSlug, tool, rootSlug, skillName);
|
|
108131
108266
|
}
|
|
108132
108267
|
async function skillsGuardBase(scopeRoot, skillsDir) {
|
|
@@ -113272,7 +113407,7 @@ __export(types_exports, {
|
|
|
113272
113407
|
usesBranchWorktree: () => usesBranchWorktree
|
|
113273
113408
|
});
|
|
113274
113409
|
import path171 from "path";
|
|
113275
|
-
import { createHash as
|
|
113410
|
+
import { createHash as createHash27 } from "crypto";
|
|
113276
113411
|
function parseInstallScope(value) {
|
|
113277
113412
|
const parsed = InstallScopeSchema.safeParse(value);
|
|
113278
113413
|
if (!parsed.success) throw new Error(`Invalid scope "${value}". Use "workspace" or "user".`);
|
|
@@ -113340,7 +113475,7 @@ function managedMcpManifestKey(tool, projectScope) {
|
|
|
113340
113475
|
return projectScope ? `${owner}:project` : owner;
|
|
113341
113476
|
}
|
|
113342
113477
|
function managedMcpWorkspaceId(workspaceRoot) {
|
|
113343
|
-
return
|
|
113478
|
+
return createHash27("sha1").update(workspaceRoot).digest("hex").slice(0, 12);
|
|
113344
113479
|
}
|
|
113345
113480
|
function managedMcpManifestPath(dataHome, workspaceRoot) {
|
|
113346
113481
|
if (workspaceRoot) {
|
|
@@ -114801,7 +114936,7 @@ var init_types5 = __esm({
|
|
|
114801
114936
|
|
|
114802
114937
|
// src/claude-hook-host.ts
|
|
114803
114938
|
import fs99 from "fs";
|
|
114804
|
-
import { createHash as
|
|
114939
|
+
import { createHash as createHash28 } from "crypto";
|
|
114805
114940
|
import path172 from "path";
|
|
114806
114941
|
function copilotRunsEntries(data) {
|
|
114807
114942
|
const file = data;
|
|
@@ -114809,7 +114944,7 @@ function copilotRunsEntries(data) {
|
|
|
114809
114944
|
return Object.entries(file.hooks).flatMap(([event, entries2]) => !Array.isArray(entries2) ? [] : entries2.filter((entry) => entry?.type === "command").flatMap((entry) => [entry.bash, entry.powershell, entry.command].filter((command) => typeof command === "string").map((command) => [event, entry.matcher, command])));
|
|
114810
114945
|
}
|
|
114811
114946
|
function copilotCopyKey(event, matcher, command) {
|
|
114812
|
-
return
|
|
114947
|
+
return createHash28("sha256").update(JSON.stringify([event, matcher && matcher !== "*" ? matcher : "", command])).digest("hex");
|
|
114813
114948
|
}
|
|
114814
114949
|
function claudeHookOtherHostSkip(copilotEvent, copilotMatcher, command) {
|
|
114815
114950
|
if (!copilotEvent) return CURSOR_HOOK_SKIP;
|
|
@@ -114891,7 +115026,7 @@ var init_claude_hook_host = __esm({
|
|
|
114891
115026
|
});
|
|
114892
115027
|
|
|
114893
115028
|
// src/copilot-hook-claim.ts
|
|
114894
|
-
import { createHash as
|
|
115029
|
+
import { createHash as createHash29 } from "crypto";
|
|
114895
115030
|
import fs100 from "fs";
|
|
114896
115031
|
import path173 from "path";
|
|
114897
115032
|
function claimDay(raw) {
|
|
@@ -114919,7 +115054,7 @@ function claimCopilotHookEvent(event, matcher, raw, env3 = process.env) {
|
|
|
114919
115054
|
if (!day) return true;
|
|
114920
115055
|
const root = path173.join(getTeamaiHomeDir(), CLAIMS_DIR);
|
|
114921
115056
|
removeOldClaims(root, day);
|
|
114922
|
-
const key =
|
|
115057
|
+
const key = createHash29("sha256").update(JSON.stringify([env3.COPILOT_AGENT_SESSION_ID ?? "", event, matcher, raw])).digest("hex");
|
|
114923
115058
|
try {
|
|
114924
115059
|
fs100.mkdirSync(path173.join(root, day), { recursive: true });
|
|
114925
115060
|
fs100.writeFileSync(path173.join(root, day, key), "", { flag: "wx" });
|
|
@@ -115558,7 +115693,7 @@ __export(hooks_exports2, {
|
|
|
115558
115693
|
unregisterCheckoutFromSharedManifest: () => unregisterCheckoutFromSharedManifest
|
|
115559
115694
|
});
|
|
115560
115695
|
import path176 from "path";
|
|
115561
|
-
import { createHash as
|
|
115696
|
+
import { createHash as createHash30 } from "crypto";
|
|
115562
115697
|
import { isDeepStrictEqual as isDeepStrictEqual10 } from "util";
|
|
115563
115698
|
import { realpathSync as realpathSync6 } from "fs";
|
|
115564
115699
|
import { lstat as lstat2, readdir as readdir2, rm as rm2 } from "fs/promises";
|
|
@@ -116303,7 +116438,7 @@ function copilotPowershellCommand(command) {
|
|
|
116303
116438
|
return match[1] === "bash" ? `${match[2]} 2>$null; exit 0` : `& ${match[1]} -lc "${match[2]} 2>/dev/null"; exit 0`;
|
|
116304
116439
|
}
|
|
116305
116440
|
function copilotGlobalSource(file) {
|
|
116306
|
-
return
|
|
116441
|
+
return createHash30("sha256").update(path176.resolve(file)).digest("hex");
|
|
116307
116442
|
}
|
|
116308
116443
|
function toCopilotEntry(def, globalSource) {
|
|
116309
116444
|
const command = globalSource && def.source === "builtin" ? def.command.replace("--tool copilot", `--tool copilot --copilot-global ${copilotGlobalSource(globalSource)}`) : def.command;
|
|
@@ -117621,7 +117756,7 @@ async function codexTrustTargets(teamConfig, localConfig2, selectedAgents) {
|
|
|
117621
117756
|
};
|
|
117622
117757
|
}
|
|
117623
117758
|
async function codexTrustFingerprint(targets) {
|
|
117624
|
-
const hash2 =
|
|
117759
|
+
const hash2 = createHash30("sha256").update(JSON.stringify({ ...targets, inputs: void 0 }));
|
|
117625
117760
|
for (const file of targets.inputs) hash2.update(`\0${file}\0${await readFileSafe(file) ?? ""}`);
|
|
117626
117761
|
hash2.update(`\0${codexBuildsIdentity()}`);
|
|
117627
117762
|
return hash2.digest("hex");
|
|
@@ -124100,7 +124235,7 @@ var init_overlay = __esm({
|
|
|
124100
124235
|
});
|
|
124101
124236
|
|
|
124102
124237
|
// src/workflow/place/worktree-snapshot.ts
|
|
124103
|
-
import { createHash as
|
|
124238
|
+
import { createHash as createHash31 } from "crypto";
|
|
124104
124239
|
import { execFile as execFile9 } from "child_process";
|
|
124105
124240
|
import fs106 from "fs/promises";
|
|
124106
124241
|
import path185 from "path";
|
|
@@ -124128,7 +124263,7 @@ async function hashPath(workspace, relative3) {
|
|
|
124128
124263
|
try {
|
|
124129
124264
|
const stats = await fs106.lstat(full);
|
|
124130
124265
|
const bytes = stats.isSymbolicLink() ? await fs106.readlink(full) : await fs106.readFile(full);
|
|
124131
|
-
return
|
|
124266
|
+
return createHash31("sha256").update(bytes).digest("hex");
|
|
124132
124267
|
} catch {
|
|
124133
124268
|
return "missing";
|
|
124134
124269
|
}
|
|
@@ -124458,7 +124593,7 @@ var init_setup = __esm({
|
|
|
124458
124593
|
});
|
|
124459
124594
|
|
|
124460
124595
|
// src/workflow/place/writer.ts
|
|
124461
|
-
import { createHash as
|
|
124596
|
+
import { createHash as createHash32 } from "crypto";
|
|
124462
124597
|
import fs109 from "fs/promises";
|
|
124463
124598
|
import path188 from "path";
|
|
124464
124599
|
async function mergeBranches({ dir, run: run3, step, executor, merge }) {
|
|
@@ -124491,7 +124626,7 @@ async function conflictsPath(dir) {
|
|
|
124491
124626
|
return path188.resolve(dir, printed);
|
|
124492
124627
|
}
|
|
124493
124628
|
function hashText(text2) {
|
|
124494
|
-
return
|
|
124629
|
+
return createHash32("sha256").update(text2).digest("hex");
|
|
124495
124630
|
}
|
|
124496
124631
|
async function rememberConflicts(dir) {
|
|
124497
124632
|
const current = await conflictContents(dir);
|
|
@@ -131159,7 +131294,7 @@ var init_session_cmd = __esm({
|
|
|
131159
131294
|
// src/dashboard/workspaces.ts
|
|
131160
131295
|
import fs119 from "fs/promises";
|
|
131161
131296
|
import path206 from "path";
|
|
131162
|
-
import { createHash as
|
|
131297
|
+
import { createHash as createHash33 } from "crypto";
|
|
131163
131298
|
async function configAt(home) {
|
|
131164
131299
|
try {
|
|
131165
131300
|
return LocalConfigSchema.parse(import_yaml42.default.parse(await fs119.readFile(path206.join(home, "config.yaml"), "utf8")));
|
|
@@ -131194,7 +131329,7 @@ async function dashboardWorkspaces(events) {
|
|
|
131194
131329
|
if (!config) return;
|
|
131195
131330
|
seen.add(anchor);
|
|
131196
131331
|
result.push({
|
|
131197
|
-
id:
|
|
131332
|
+
id: createHash33("sha256").update(anchor).digest("hex").slice(0, 24),
|
|
131198
131333
|
label: path206.basename(root),
|
|
131199
131334
|
scope: "project",
|
|
131200
131335
|
root,
|
|
@@ -132259,7 +132394,7 @@ __export(distribution_exports, {
|
|
|
132259
132394
|
saveProjects: () => saveProjects,
|
|
132260
132395
|
saveRoles: () => saveRoles
|
|
132261
132396
|
});
|
|
132262
|
-
import { createHash as
|
|
132397
|
+
import { createHash as createHash34 } from "crypto";
|
|
132263
132398
|
function assertRolesEditable(ownConfig) {
|
|
132264
132399
|
if (!ownConfig.roleAssignment) return;
|
|
132265
132400
|
throw new HttpError(409, `Roles are assigned in ${ROLE_ASSIGNMENTS_FILE} in the team repo and cannot be changed here. Open a merge request against that file, or ask a code owner of manifest/ to.`);
|
|
@@ -132273,7 +132408,7 @@ function selectionOf2(config) {
|
|
|
132273
132408
|
}
|
|
132274
132409
|
function revisionOf(config) {
|
|
132275
132410
|
const identity2 = { scope: config.scope, dataHome: config.dataHome ?? null, projectRoot: config.projectRoot ?? null };
|
|
132276
|
-
return
|
|
132411
|
+
return createHash34("sha256").update(JSON.stringify({ identity: identity2, selection: selectionOf2(config) })).digest("hex").slice(0, 16);
|
|
132277
132412
|
}
|
|
132278
132413
|
async function readManifest3(kind, load2, repoPath) {
|
|
132279
132414
|
try {
|
|
@@ -135181,7 +135316,7 @@ var init_graph_index_schema = __esm({
|
|
|
135181
135316
|
});
|
|
135182
135317
|
|
|
135183
135318
|
// src/wiki-engine/code-knowledge/code-collector.ts
|
|
135184
|
-
import { createHash as
|
|
135319
|
+
import { createHash as createHash35 } from "crypto";
|
|
135185
135320
|
import { execFile as execFile10 } from "child_process";
|
|
135186
135321
|
import { readFile as readFile7, readdir as readdir4, stat as stat5 } from "fs/promises";
|
|
135187
135322
|
import path215 from "path";
|
|
@@ -135225,7 +135360,7 @@ async function collectCode(options2) {
|
|
|
135225
135360
|
path: filePath,
|
|
135226
135361
|
relativePath,
|
|
135227
135362
|
language,
|
|
135228
|
-
sha256:
|
|
135363
|
+
sha256: createHash35("sha256").update(content).digest("hex"),
|
|
135229
135364
|
content,
|
|
135230
135365
|
isKeyFile: isKeyFile(relativePath, language)
|
|
135231
135366
|
});
|
|
@@ -142785,7 +142920,7 @@ var init_code_knowledge_recall = __esm({
|
|
|
142785
142920
|
});
|
|
142786
142921
|
|
|
142787
142922
|
// src/codebase-freshness.ts
|
|
142788
|
-
import { createHash as
|
|
142923
|
+
import { createHash as createHash36 } from "crypto";
|
|
142789
142924
|
import { lstat as lstat5, readFile as readFile16, readdir as readdir10, realpath as realpath10, stat as stat11 } from "fs/promises";
|
|
142790
142925
|
import path235 from "path";
|
|
142791
142926
|
function errorCode(error2) {
|
|
@@ -142971,7 +143106,7 @@ async function checkOneSource(source, manifest, checkout) {
|
|
|
142971
143106
|
if (!fileStat.isFile()) return unknown();
|
|
142972
143107
|
try {
|
|
142973
143108
|
const content = await readFile16(actualPath, "utf8");
|
|
142974
|
-
const actualHash =
|
|
143109
|
+
const actualHash = createHash36("sha256").update(content).digest("hex");
|
|
142975
143110
|
return {
|
|
142976
143111
|
...source,
|
|
142977
143112
|
freshness: actualHash === expectedHash ? "current" : "stale",
|
|
@@ -153408,7 +153543,7 @@ sourceCmd.command("remove <name>").description("Remove a source and clean up its
|
|
|
153408
153543
|
const { sourceRemove: sourceRemove2 } = await Promise.resolve().then(() => (init_source2(), source_exports));
|
|
153409
153544
|
await sourceRemove2(name, globalOpts);
|
|
153410
153545
|
});
|
|
153411
|
-
sourceCmd.command("add-http <endpoint>").description("Add an HTTP source (report/sync/ack) alongside a git main repo").option("--token <key>", "API token for the HTTP endpoint (stored 0600, never committed)").option("--force", "Overwrite an existing HTTP source config").action(async (endpoint, cmdOpts) => {
|
|
153546
|
+
sourceCmd.command("add-http <endpoint>").description("Add an HTTP source (report/sync/ack) alongside a git main repo").option("--token <key>", "API token for the HTTP endpoint (stored 0600, never committed)").option("--agent <name>", "Agent instance that owns this token (repeat setup for each agent)", (val, acc) => acc.concat(val), []).option("--force", "Overwrite an existing HTTP source config").action(async (endpoint, cmdOpts) => {
|
|
153412
153547
|
const globalOpts = program2.opts();
|
|
153413
153548
|
const { sourceAddHttp: sourceAddHttp2 } = await Promise.resolve().then(() => (init_source2(), source_exports));
|
|
153414
153549
|
await sourceAddHttp2(endpoint, { ...globalOpts, ...cmdOpts });
|
package/package.json
CHANGED
|
@@ -175,6 +175,7 @@ Generated: do not edit by hand. Regenerate with
|
|
|
175
175
|
- `teamai source remove <name>` — Remove a source and clean up its skills
|
|
176
176
|
- `teamai source add-http <endpoint>` — Add an HTTP source (report/sync/ack) alongside a git main repo
|
|
177
177
|
- `--token <key>` — API token for the HTTP endpoint (stored 0600, never committed)
|
|
178
|
+
- `--agent <name>` — Agent instance that owns this token (repeat setup for each agent)
|
|
178
179
|
- `--force` — Overwrite an existing HTTP source config
|
|
179
180
|
- `teamai source remove-http` — Remove the HTTP source and clean up its resources
|
|
180
181
|
- `teamai source list` — List all configured sources
|
|
@@ -104,11 +104,19 @@ was skipped and why.
|
|
|
104
104
|
cannot use Git. If the admin provides an HTTP endpoint + API key instead, use:
|
|
105
105
|
|
|
106
106
|
```bash
|
|
107
|
-
teamai init --http https://your-team-host/api --token <api-key>
|
|
107
|
+
teamai init --http https://your-team-host/api --token <api-key> --agent <tool>
|
|
108
108
|
```
|
|
109
109
|
|
|
110
110
|
This is a read-only consumer mode — `push` / `contribute` are not available, but
|
|
111
|
-
skills and rules still sync.
|
|
111
|
+
skills and rules still sync. Run it from each workspace that should be managed:
|
|
112
|
+
the user-level hooks are shared by the machine, but an unrelated workspace is
|
|
113
|
+
not reported or allowed to receive workspace resources. ClawPro project binding
|
|
114
|
+
is optional; skipping it keeps general workspace sync enabled while declining
|
|
115
|
+
resources tied to a specific project. Treat each linked Git worktree as a
|
|
116
|
+
separate workspace and run HTTP setup in each one that should be managed.
|
|
117
|
+
ClawPro instance tokens are Agent-specific. On a machine with multiple AI tools,
|
|
118
|
+
run setup once per tool with its own `--agent` and token; TeamAI keeps those
|
|
119
|
+
credentials separate while allowing them to manage the same workspace.
|
|
112
120
|
|
|
113
121
|
**Claude Code or Codex kept in a different directory (`CLAUDE_CONFIG_DIR`,
|
|
114
122
|
`CODEX_HOME`):** `init` records that directory (as `toolRoots.claude` /
|