@team-ai/teamai-cli 0.30.1 → 0.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +182 -37
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -61809,23 +61809,99 @@ async function canonicalizeWorkspacePath(value) {
|
|
|
61809
61809
|
}
|
|
61810
61810
|
function mergeWorkspaceBindings(existing2, incoming, canonicalKey) {
|
|
61811
61811
|
if (!existing2) return incoming;
|
|
61812
|
-
const
|
|
61813
|
-
const
|
|
61812
|
+
const rank2 = (binding) => (binding.projectId ?? 0) > 0 ? 2 : binding.projectId === 0 ? 1 : 0;
|
|
61813
|
+
const existingRank = rank2(existing2);
|
|
61814
|
+
const incomingRank = rank2(incoming);
|
|
61815
|
+
const existingReal = existingRank === 2;
|
|
61816
|
+
const incomingReal = incomingRank === 2;
|
|
61814
61817
|
if (existingReal && incomingReal && existing2.projectId !== incoming.projectId) {
|
|
61815
61818
|
log.warn(
|
|
61816
61819
|
`local-agent: workspace ${canonicalKey} has conflicting project bindings (${existing2.projectId} vs ${incoming.projectId}); keeping ${existing2.projectId}`
|
|
61817
61820
|
);
|
|
61818
61821
|
}
|
|
61819
|
-
const base =
|
|
61822
|
+
const base = existingRank >= incomingRank ? { ...existing2 } : { ...incoming };
|
|
61823
|
+
base.enrolledAt ??= existing2.enrolledAt ?? incoming.enrolledAt;
|
|
61820
61824
|
if (!base.ideType) base.ideType = existing2.ideType ?? incoming.ideType;
|
|
61821
61825
|
return base;
|
|
61822
61826
|
}
|
|
61827
|
+
function isWorkspaceEnrolled(config, workspacePath) {
|
|
61828
|
+
return config.workspaceBindings[workspacePath]?.enrolledAt !== void 0;
|
|
61829
|
+
}
|
|
61830
|
+
function hasWorkspaceBindingDecision(binding) {
|
|
61831
|
+
return binding?.projectId !== void 0;
|
|
61832
|
+
}
|
|
61833
|
+
async function inferWorkspaceEnrollments(config) {
|
|
61834
|
+
const inferred = {};
|
|
61835
|
+
const add = async (workspacePath, enrolledAt = config.createdAt, ideType) => {
|
|
61836
|
+
const canonical2 = await canonicalizeWorkspacePath(workspacePath);
|
|
61837
|
+
inferred[canonical2] ??= { enrolledAt, ...ideType ? { ideType } : {} };
|
|
61838
|
+
};
|
|
61839
|
+
const inheritedAnchors = /* @__PURE__ */ new Set();
|
|
61840
|
+
const missingBindings = /* @__PURE__ */ new Set();
|
|
61841
|
+
const anchorsByPath = /* @__PURE__ */ new Map();
|
|
61842
|
+
const positiveBindings = Object.entries(config.workspaceBindings).filter(([, binding]) => (binding.projectId ?? 0) > 0);
|
|
61843
|
+
for (const [workspacePath] of positiveBindings) {
|
|
61844
|
+
try {
|
|
61845
|
+
await fs35.promises.stat(workspacePath);
|
|
61846
|
+
} catch (error2) {
|
|
61847
|
+
if (error2.code === "ENOENT") missingBindings.add(workspacePath);
|
|
61848
|
+
continue;
|
|
61849
|
+
}
|
|
61850
|
+
const anchors = await resolveAnchors(workspacePath);
|
|
61851
|
+
anchorsByPath.set(workspacePath, anchors);
|
|
61852
|
+
if (anchors && anchors.projectAnchor !== anchors.workspaceRoot) {
|
|
61853
|
+
inheritedAnchors.add(await canonicalizeWorkspacePath(anchors.projectAnchor));
|
|
61854
|
+
}
|
|
61855
|
+
}
|
|
61856
|
+
const bindingTransactions = /* @__PURE__ */ new Map();
|
|
61857
|
+
for (const [workspacePath, binding] of positiveBindings) {
|
|
61858
|
+
if (!binding.boundAt) continue;
|
|
61859
|
+
const key = `${binding.projectId}\0${binding.boundAt}`;
|
|
61860
|
+
const paths = bindingTransactions.get(key) ?? [];
|
|
61861
|
+
paths.push(workspacePath);
|
|
61862
|
+
bindingTransactions.set(key, paths);
|
|
61863
|
+
}
|
|
61864
|
+
for (const paths of bindingTransactions.values()) {
|
|
61865
|
+
if (!paths.some((workspacePath) => missingBindings.has(workspacePath))) continue;
|
|
61866
|
+
for (const workspacePath of paths) {
|
|
61867
|
+
if (missingBindings.has(workspacePath)) continue;
|
|
61868
|
+
const anchors = anchorsByPath.get(workspacePath);
|
|
61869
|
+
if (anchors && anchors.projectAnchor === anchors.workspaceRoot) inheritedAnchors.add(workspacePath);
|
|
61870
|
+
}
|
|
61871
|
+
}
|
|
61872
|
+
for (const [workspacePath, binding] of Object.entries(config.workspaceBindings)) {
|
|
61873
|
+
if ((binding.projectId ?? 0) > 0 && !missingBindings.has(workspacePath) && !inheritedAnchors.has(workspacePath)) {
|
|
61874
|
+
await add(workspacePath, binding.boundAt ?? config.createdAt, binding.ideType);
|
|
61875
|
+
}
|
|
61876
|
+
}
|
|
61877
|
+
const manifest = await readJson(getManifestPath());
|
|
61878
|
+
for (const key of Object.keys(manifest?.scopes ?? {})) {
|
|
61879
|
+
const parsed = parseScopeKey(key);
|
|
61880
|
+
if (parsed.scope === "project" && parsed.workspacePath) await add(parsed.workspacePath);
|
|
61881
|
+
}
|
|
61882
|
+
const models = await readJson(getModelManifestPath());
|
|
61883
|
+
for (const workspacePath of Object.keys(models?.workspaceModels ?? {})) await add(workspacePath);
|
|
61884
|
+
const projectHomes = await listDirs(path76.join(getTeamaiHomePath(), "projects")).catch(() => []);
|
|
61885
|
+
const mcpOwnershipFiles = [
|
|
61886
|
+
path76.join(getTeamaiHomePath(), "managed-local-mcp.json"),
|
|
61887
|
+
...projectHomes.map((dir) => path76.join(getTeamaiHomePath(), "projects", dir, "managed-local-mcp.json"))
|
|
61888
|
+
];
|
|
61889
|
+
for (const file of mcpOwnershipFiles) {
|
|
61890
|
+
const records2 = await readJson(file);
|
|
61891
|
+
for (const [key, owned] of Object.entries(records2 ?? {})) {
|
|
61892
|
+
const match = /^[^:]+:local:(.+)$/.exec(key);
|
|
61893
|
+
if (match?.[1] && owned.length > 0) await add(match[1]);
|
|
61894
|
+
}
|
|
61895
|
+
}
|
|
61896
|
+
return inferred;
|
|
61897
|
+
}
|
|
61823
61898
|
async function loadLocalAgentConfig(options2 = {}) {
|
|
61824
61899
|
const fileConfig = await readJson(getConfigPath());
|
|
61825
61900
|
if (fileConfig && "disabled" in fileConfig && fileConfig.disabled === true) return null;
|
|
61826
61901
|
if (fileConfig && "endpoint" in fileConfig && fileConfig.endpoint) {
|
|
61902
|
+
const { workspaceEnrollments: legacyEnrollments, ...storedConfig } = fileConfig;
|
|
61827
61903
|
const config = {
|
|
61828
|
-
...
|
|
61904
|
+
...storedConfig,
|
|
61829
61905
|
endpoint: normalizeEndpoint(fileConfig.endpoint),
|
|
61830
61906
|
workspaceBindings: fileConfig.workspaceBindings ?? {}
|
|
61831
61907
|
};
|
|
@@ -61836,20 +61912,15 @@ async function loadLocalAgentConfig(options2 = {}) {
|
|
|
61836
61912
|
removedLegacyPaths.push(wsPath);
|
|
61837
61913
|
}
|
|
61838
61914
|
}
|
|
61915
|
+
let migrationChanged = removedLegacyPaths.length > 0;
|
|
61839
61916
|
if (removedLegacyPaths.length > 0 && options2.dryRun) {
|
|
61840
61917
|
log.info(`[dry-run] Would remove ${removedLegacyPaths.length} legacy group-based workspace binding(s).`);
|
|
61841
61918
|
} else if (removedLegacyPaths.length > 0) {
|
|
61842
61919
|
log.warn(
|
|
61843
61920
|
`Removed ${removedLegacyPaths.length} legacy group-based workspace binding(s); you will be prompted to re-bind on the next session.`
|
|
61844
61921
|
);
|
|
61845
|
-
try {
|
|
61846
|
-
await saveLocalAgentConfig(config);
|
|
61847
|
-
} catch (e) {
|
|
61848
|
-
log.debug(`local-agent: failed to persist binding cleanup: ${e.message}`);
|
|
61849
|
-
}
|
|
61850
61922
|
}
|
|
61851
61923
|
const migrated = {};
|
|
61852
|
-
let migrationChanged = false;
|
|
61853
61924
|
for (const [wsPath, binding] of Object.entries(config.workspaceBindings)) {
|
|
61854
61925
|
const canonicalKey = await canonicalizeWorkspacePath(wsPath);
|
|
61855
61926
|
if (canonicalKey !== wsPath) migrationChanged = true;
|
|
@@ -61857,6 +61928,20 @@ async function loadLocalAgentConfig(options2 = {}) {
|
|
|
61857
61928
|
migrated[canonicalKey] = mergeWorkspaceBindings(migrated[canonicalKey], binding, canonicalKey);
|
|
61858
61929
|
}
|
|
61859
61930
|
config.workspaceBindings = migrated;
|
|
61931
|
+
if (fileConfig.workspaceStateVersion !== 1) {
|
|
61932
|
+
const enrollments = legacyEnrollments ?? await inferWorkspaceEnrollments(config);
|
|
61933
|
+
for (const [wsPath, enrollment] of Object.entries(enrollments)) {
|
|
61934
|
+
const canonicalKey = await canonicalizeWorkspacePath(wsPath);
|
|
61935
|
+
const binding = config.workspaceBindings[canonicalKey] ?? {};
|
|
61936
|
+
config.workspaceBindings[canonicalKey] = {
|
|
61937
|
+
...binding,
|
|
61938
|
+
enrolledAt: binding.enrolledAt ?? enrollment.enrolledAt,
|
|
61939
|
+
ideType: enrollment.ideType ?? binding.ideType
|
|
61940
|
+
};
|
|
61941
|
+
}
|
|
61942
|
+
config.workspaceStateVersion = 1;
|
|
61943
|
+
migrationChanged = true;
|
|
61944
|
+
}
|
|
61860
61945
|
if (migrationChanged && !options2.dryRun) {
|
|
61861
61946
|
await saveLocalAgentConfig(config);
|
|
61862
61947
|
}
|
|
@@ -61872,6 +61957,7 @@ async function loadLocalAgentConfig(options2 = {}) {
|
|
|
61872
61957
|
endpoint,
|
|
61873
61958
|
token,
|
|
61874
61959
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
61960
|
+
workspaceStateVersion: 1,
|
|
61875
61961
|
workspaceBindings: {}
|
|
61876
61962
|
};
|
|
61877
61963
|
if (options2.dryRun) return backfilled;
|
|
@@ -61889,6 +61975,7 @@ async function loadLocalAgentConfig(options2 = {}) {
|
|
|
61889
61975
|
endpoint: normalizeEndpoint(envEndpoint),
|
|
61890
61976
|
token: process.env.TEAMAI_API_TOKEN ?? process.env.TEAMAI_TOKEN,
|
|
61891
61977
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
61978
|
+
workspaceStateVersion: 1,
|
|
61892
61979
|
workspaceBindings: {}
|
|
61893
61980
|
};
|
|
61894
61981
|
}
|
|
@@ -61896,6 +61983,7 @@ async function saveLocalAgentConfig(config) {
|
|
|
61896
61983
|
await writeJsonAtomic(getConfigPath(), {
|
|
61897
61984
|
...config,
|
|
61898
61985
|
endpoint: normalizeEndpoint(config.endpoint),
|
|
61986
|
+
workspaceStateVersion: 1,
|
|
61899
61987
|
workspaceBindings: config.workspaceBindings ?? {}
|
|
61900
61988
|
});
|
|
61901
61989
|
}
|
|
@@ -62302,11 +62390,18 @@ async function persistWorkspaceBinding(config, cwd, resolvedPath, projectId, pro
|
|
|
62302
62390
|
}
|
|
62303
62391
|
await saveLocalAgentConfig(config);
|
|
62304
62392
|
}
|
|
62393
|
+
async function enrollWorkspace(config, resolvedPath) {
|
|
62394
|
+
const binding = config.workspaceBindings[resolvedPath] ?? {};
|
|
62395
|
+
config.workspaceBindings[resolvedPath] = {
|
|
62396
|
+
...binding,
|
|
62397
|
+
enrolledAt: binding.enrolledAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
62398
|
+
};
|
|
62399
|
+
}
|
|
62305
62400
|
async function inheritWorktreeBinding(config, cwd, resolvedPath) {
|
|
62306
62401
|
const anchors = await resolveAnchors(cwd);
|
|
62307
62402
|
if (!anchors || anchors.projectAnchor === anchors.workspaceRoot) return false;
|
|
62308
62403
|
const anchorBinding = config.workspaceBindings[anchors.projectAnchor];
|
|
62309
|
-
if (!anchorBinding) return false;
|
|
62404
|
+
if (!hasWorkspaceBindingDecision(anchorBinding)) return false;
|
|
62310
62405
|
config.workspaceBindings[resolvedPath] = {
|
|
62311
62406
|
...config.workspaceBindings[resolvedPath],
|
|
62312
62407
|
projectId: anchorBinding.projectId,
|
|
@@ -62321,6 +62416,11 @@ async function bindWorkspaceToProject(workspacePath, projectId) {
|
|
|
62321
62416
|
if (!config) {
|
|
62322
62417
|
throw new Error("HTTP local agent is not initialized. Run `teamai init --http <ENDPOINT> --token <API_TOKEN>` first.");
|
|
62323
62418
|
}
|
|
62419
|
+
if (!isWorkspaceEnrolled(config, workspacePath)) {
|
|
62420
|
+
throw new Error(
|
|
62421
|
+
"Current workspace is not enrolled. Run `teamai init --http <ENDPOINT> --token <API_TOKEN>` here first."
|
|
62422
|
+
);
|
|
62423
|
+
}
|
|
62324
62424
|
const projects = await fetchUserProjects(config);
|
|
62325
62425
|
const project = projectId ? projects.find((item) => item.id === projectId) : await promptForProjectBinding(workspacePath, projects);
|
|
62326
62426
|
if (!project) return null;
|
|
@@ -62334,7 +62434,8 @@ async function bindWorkspaceToProject(workspacePath, projectId) {
|
|
|
62334
62434
|
return binding;
|
|
62335
62435
|
}
|
|
62336
62436
|
async function ensureWorkspaceBinding(config, workspacePath, sessionId, cwd) {
|
|
62337
|
-
if (config
|
|
62437
|
+
if (!isWorkspaceEnrolled(config, workspacePath)) return;
|
|
62438
|
+
if (hasWorkspaceBindingDecision(config.workspaceBindings[workspacePath])) return;
|
|
62338
62439
|
if (await inheritWorktreeBinding(config, cwd, workspacePath)) return;
|
|
62339
62440
|
const markerKey = sessionId || `ppid-${process.ppid}`;
|
|
62340
62441
|
const hintMarker = path76.join(os9.tmpdir(), `teamai-bind-session-${markerKey}`);
|
|
@@ -62382,7 +62483,8 @@ function isBindPromptTool(tool) {
|
|
|
62382
62483
|
return kind === "codebuddy" || kind === "workbuddy";
|
|
62383
62484
|
}
|
|
62384
62485
|
async function emitBindingHint(config, workspacePath, sessionId, cwd) {
|
|
62385
|
-
if (config
|
|
62486
|
+
if (!isWorkspaceEnrolled(config, workspacePath)) return;
|
|
62487
|
+
if (hasWorkspaceBindingDecision(config.workspaceBindings[workspacePath])) return;
|
|
62386
62488
|
if (await inheritWorktreeBinding(config, cwd, workspacePath)) return;
|
|
62387
62489
|
const markerKey = sessionId || `ppid-${process.ppid}`;
|
|
62388
62490
|
const hintMarker = path76.join(os9.tmpdir(), `teamai-bind-hint-${markerKey}`);
|
|
@@ -62605,18 +62707,19 @@ async function pruneDeadWorkspaceBindings(config) {
|
|
|
62605
62707
|
function stampWorkspaceTool(config, currentPath, tool) {
|
|
62606
62708
|
if (!currentPath) return false;
|
|
62607
62709
|
const binding = config.workspaceBindings[currentPath];
|
|
62608
|
-
if (!binding) return false;
|
|
62710
|
+
if (!binding?.enrolledAt) return false;
|
|
62609
62711
|
const normalized = normalizeAgentType(tool);
|
|
62610
|
-
if (binding.ideType
|
|
62611
|
-
|
|
62612
|
-
|
|
62712
|
+
if (binding.ideType !== normalized) {
|
|
62713
|
+
binding.ideType = normalized;
|
|
62714
|
+
return true;
|
|
62715
|
+
}
|
|
62716
|
+
return false;
|
|
62613
62717
|
}
|
|
62614
62718
|
function selectToolWorkspaces(config, currentPath, currentTool) {
|
|
62615
|
-
|
|
62616
|
-
if (currentPath) paths.add(currentPath);
|
|
62617
|
-
return Array.from(paths).filter((wsPath) => {
|
|
62719
|
+
return Object.keys(config.workspaceBindings).filter((wsPath) => {
|
|
62618
62720
|
const b2 = config.workspaceBindings[wsPath];
|
|
62619
|
-
|
|
62721
|
+
if (!b2.enrolledAt) return false;
|
|
62722
|
+
const wsTool = b2.ideType ?? (wsPath === currentPath ? currentTool : void 0);
|
|
62620
62723
|
return wsTool === currentTool;
|
|
62621
62724
|
});
|
|
62622
62725
|
}
|
|
@@ -62676,9 +62779,9 @@ async function buildReportPayload(config, context) {
|
|
|
62676
62779
|
const workspace = {
|
|
62677
62780
|
path: wsPath,
|
|
62678
62781
|
name: path76.basename(wsPath),
|
|
62679
|
-
ide_type: currentTool
|
|
62680
|
-
project_id: wsBinding?.projectId
|
|
62782
|
+
ide_type: currentTool
|
|
62681
62783
|
};
|
|
62784
|
+
if ((wsBinding?.projectId ?? 0) > 0) workspace.project_id = wsBinding.projectId;
|
|
62682
62785
|
if (wsScope.skills.length > 0) workspace.skills = wsScope.skills;
|
|
62683
62786
|
if (wsScope.rules.length > 0) workspace.rules = wsScope.rules;
|
|
62684
62787
|
const wsMcps = await scanMcpFromManifest("project", tool, wsPath);
|
|
@@ -62707,7 +62810,7 @@ async function buildSyncPayload(config, context) {
|
|
|
62707
62810
|
path: wsPath,
|
|
62708
62811
|
name: path76.basename(wsPath),
|
|
62709
62812
|
ide_type: currentTool,
|
|
62710
|
-
project_id: wsBinding
|
|
62813
|
+
...(wsBinding?.projectId ?? 0) > 0 ? { project_id: wsBinding.projectId } : {}
|
|
62711
62814
|
};
|
|
62712
62815
|
});
|
|
62713
62816
|
}
|
|
@@ -63779,9 +63882,9 @@ async function applyModelConfig(config, command, context) {
|
|
|
63779
63882
|
if (scope === "project" && !workspacePath) {
|
|
63780
63883
|
throw new Error("apply_model_config: workspace command is missing workspace_path");
|
|
63781
63884
|
}
|
|
63782
|
-
if (workspacePath && config
|
|
63885
|
+
if (workspacePath && !isWorkspaceEnrolled(config, workspacePath)) {
|
|
63783
63886
|
throw new Error(
|
|
63784
|
-
`apply_model_config: workspace "${path76.basename(workspacePath)}" is not
|
|
63887
|
+
`apply_model_config: workspace "${path76.basename(workspacePath)}" is not enrolled`
|
|
63785
63888
|
);
|
|
63786
63889
|
}
|
|
63787
63890
|
if (agentKind === "claude" && workspacePath) {
|
|
@@ -64301,6 +64404,24 @@ async function runMcpCommand(config, command, context) {
|
|
|
64301
64404
|
return command.version;
|
|
64302
64405
|
}
|
|
64303
64406
|
async function executeCommand(config, command, context) {
|
|
64407
|
+
if (normalizeScope(command.scope) === "project") {
|
|
64408
|
+
const workspacePath2 = await resolveWorkspacePath(command.workspace_path ?? context.cwd);
|
|
64409
|
+
if (!workspacePath2) throw new Error(`${command.type ?? "workspace command"} is missing workspace_path`);
|
|
64410
|
+
if (!isWorkspaceEnrolled(config, workspacePath2)) {
|
|
64411
|
+
throw new Error(`Workspace is not enrolled for TeamAI management: ${workspacePath2}`);
|
|
64412
|
+
}
|
|
64413
|
+
if (command.project_id !== void 0) {
|
|
64414
|
+
if (!Number.isInteger(command.project_id) || command.project_id <= 0) {
|
|
64415
|
+
throw new Error(`Workspace command has invalid project_id: ${command.project_id}`);
|
|
64416
|
+
}
|
|
64417
|
+
const binding = config.workspaceBindings[workspacePath2];
|
|
64418
|
+
if (!binding || binding.projectId !== command.project_id) {
|
|
64419
|
+
throw new Error(
|
|
64420
|
+
`Workspace project binding does not match command project_id ${command.project_id}: ${workspacePath2}`
|
|
64421
|
+
);
|
|
64422
|
+
}
|
|
64423
|
+
}
|
|
64424
|
+
}
|
|
64304
64425
|
if (command.type === "apply_model_config") {
|
|
64305
64426
|
await applyModelConfig(config, command, context);
|
|
64306
64427
|
return;
|
|
@@ -64379,9 +64500,9 @@ async function reportAndSyncLocalAgent(context) {
|
|
|
64379
64500
|
async function syncLocalAgent(context) {
|
|
64380
64501
|
const config = await loadLocalAgentConfig();
|
|
64381
64502
|
if (!config) return false;
|
|
64503
|
+
const workspacePath = await resolveWorkspacePath(context.cwd);
|
|
64382
64504
|
if (isBindPromptEnabled() && isBindPromptTool(context.tool)) {
|
|
64383
|
-
|
|
64384
|
-
if (workspacePath) {
|
|
64505
|
+
if (workspacePath && isWorkspaceEnrolled(config, workspacePath)) {
|
|
64385
64506
|
const sid = context.event?.sessionId;
|
|
64386
64507
|
if (context.event?.type === "session_start") {
|
|
64387
64508
|
await ensureWorkspaceBinding(config, workspacePath, sid, context.cwd);
|
|
@@ -64404,8 +64525,7 @@ async function syncLocalAgent(context) {
|
|
|
64404
64525
|
await maybeReconcilePlugins(context);
|
|
64405
64526
|
}
|
|
64406
64527
|
const pruned = await pruneDeadWorkspaceBindings(config);
|
|
64407
|
-
const
|
|
64408
|
-
const stamped = stampWorkspaceTool(config, currentPath, context.tool ?? "workbuddy");
|
|
64528
|
+
const stamped = stampWorkspaceTool(config, workspacePath, context.tool ?? "workbuddy");
|
|
64409
64529
|
if (pruned || stamped) {
|
|
64410
64530
|
await saveLocalAgentConfig(config);
|
|
64411
64531
|
}
|
|
@@ -64577,17 +64697,20 @@ async function initLocalAgentHttp(options2) {
|
|
|
64577
64697
|
throw new Error("HTTP endpoint is required.");
|
|
64578
64698
|
}
|
|
64579
64699
|
const existing2 = await loadLocalAgentConfig();
|
|
64580
|
-
if (existing2 && !options2.force) {
|
|
64581
|
-
throw new Error("HTTP local agent is
|
|
64700
|
+
if (existing2 && !options2.force && normalizeEndpoint(existing2.endpoint) !== endpoint) {
|
|
64701
|
+
throw new Error("HTTP local agent is initialized with another endpoint. Re-run with --force to overwrite.");
|
|
64582
64702
|
}
|
|
64583
64703
|
const config = {
|
|
64584
64704
|
endpoint,
|
|
64585
|
-
token: options2.token,
|
|
64705
|
+
token: options2.token ?? existing2?.token,
|
|
64586
64706
|
createdAt: existing2?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
64707
|
+
workspaceStateVersion: 1,
|
|
64587
64708
|
workspaceBindings: existing2?.workspaceBindings ?? {},
|
|
64588
64709
|
userGroupId: existing2?.userGroupId,
|
|
64589
64710
|
userGroupName: existing2?.userGroupName
|
|
64590
64711
|
};
|
|
64712
|
+
const workspacePath = await resolveWorkspacePath(options2.workspacePath ?? process.cwd());
|
|
64713
|
+
if (workspacePath) await enrollWorkspace(config, workspacePath);
|
|
64591
64714
|
await ensureDir(getLocalAgentHome());
|
|
64592
64715
|
await saveLocalAgentConfig(config);
|
|
64593
64716
|
if (options2.token) {
|
|
@@ -64615,7 +64738,7 @@ async function pullLocalAgentForCwd(context) {
|
|
|
64615
64738
|
async function describeLocalAgent(options2 = {}) {
|
|
64616
64739
|
const config = await loadLocalAgentConfig(options2);
|
|
64617
64740
|
if (!config) return null;
|
|
64618
|
-
const boundProjects = Object.entries(config.workspaceBindings).filter(([, b2]) => b2.projectId
|
|
64741
|
+
const boundProjects = Object.entries(config.workspaceBindings).filter(([, b2]) => (b2.projectId ?? 0) > 0).map(([workspacePath, b2]) => ({ path: workspacePath, projectName: b2.projectName, projectId: b2.projectId }));
|
|
64619
64742
|
const manifest = await loadManifest2();
|
|
64620
64743
|
const counts = { skills: 0, rules: 0, claudemd: 0 };
|
|
64621
64744
|
for (const scope of Object.values(manifest.scopes)) {
|
|
@@ -64829,7 +64952,18 @@ async function bindCurrentProject(options2) {
|
|
|
64829
64952
|
if (!config) {
|
|
64830
64953
|
throw new Error("Local agent not initialized. Run `teamai init --http` first.");
|
|
64831
64954
|
}
|
|
64832
|
-
|
|
64955
|
+
if (!isWorkspaceEnrolled(config, workspacePath)) {
|
|
64956
|
+
throw new Error(
|
|
64957
|
+
"Current workspace is not enrolled. Run `teamai init --http <ENDPOINT> --token <API_TOKEN>` here first."
|
|
64958
|
+
);
|
|
64959
|
+
}
|
|
64960
|
+
await persistWorkspaceBinding(
|
|
64961
|
+
config,
|
|
64962
|
+
options2?.cwd ?? process.cwd(),
|
|
64963
|
+
workspacePath,
|
|
64964
|
+
0,
|
|
64965
|
+
"__skipped__"
|
|
64966
|
+
);
|
|
64833
64967
|
log.info(`\u5DF2\u8DF3\u8FC7\u7ED1\u5B9A\uFF0C\u4EE5\u540E\u4E0D\u518D\u63D0\u793A\u6B64\u5DE5\u4F5C\u533A\u3002`);
|
|
64834
64968
|
return;
|
|
64835
64969
|
}
|
|
@@ -65995,7 +66129,13 @@ async function initHttp(url, options2) {
|
|
|
65995
66129
|
await reconcileHooksForInit(teamConfig, localConfig2, filterAgents2);
|
|
65996
66130
|
const { initLocalAgentHttp: initLocalAgentHttp2 } = await Promise.resolve().then(() => (init_local_agent(), local_agent_exports));
|
|
65997
66131
|
try {
|
|
65998
|
-
await initLocalAgentHttp2({
|
|
66132
|
+
await initLocalAgentHttp2({
|
|
66133
|
+
endpoint: url,
|
|
66134
|
+
token: options2.token,
|
|
66135
|
+
force: options2.force,
|
|
66136
|
+
filterAgents: filterAgents2,
|
|
66137
|
+
workspacePath: projectRoot ?? process.cwd()
|
|
66138
|
+
});
|
|
65999
66139
|
} catch (e) {
|
|
66000
66140
|
log.debug(`Local agent init: ${e.message}`);
|
|
66001
66141
|
}
|
|
@@ -106694,7 +106834,12 @@ async function sourceAddHttp(endpoint, options2) {
|
|
|
106694
106834
|
return;
|
|
106695
106835
|
}
|
|
106696
106836
|
const { initLocalAgentHttp: initLocalAgentHttp2 } = await Promise.resolve().then(() => (init_local_agent(), local_agent_exports));
|
|
106697
|
-
await initLocalAgentHttp2({
|
|
106837
|
+
await initLocalAgentHttp2({
|
|
106838
|
+
endpoint: trimmed2,
|
|
106839
|
+
token: options2.token,
|
|
106840
|
+
force: true,
|
|
106841
|
+
workspacePath: mainConfig?.projectRoot ?? process.cwd()
|
|
106842
|
+
});
|
|
106698
106843
|
log.success(`HTTP source added (${trimmed2}).`);
|
|
106699
106844
|
log.info("It will report/sync on the next AI session (via the hook-dispatch hook already installed).");
|
|
106700
106845
|
}
|