@overaihq/cli 0.14.15 → 0.15.1
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/index.js +1099 -8
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -38129,6 +38129,13 @@ var agentVersionConfigSchema = external_exports.object({
|
|
|
38129
38129
|
model: external_exports.string(),
|
|
38130
38130
|
temperature: external_exports.number(),
|
|
38131
38131
|
maxTokens: external_exports.number(),
|
|
38132
|
+
/**
|
|
38133
|
+
* Model calls the agent may make in one turn. The last one runs without
|
|
38134
|
+
* tools: a turn that hits the limit mid-investigation would otherwise end on
|
|
38135
|
+
* an unanswered tool call — no reply in chat, and no object at all from
|
|
38136
|
+
* `generate/object`. Defaulted so configs saved before the field still parse.
|
|
38137
|
+
*/
|
|
38138
|
+
maxSteps: external_exports.number().int().min(1).max(200).default(20),
|
|
38132
38139
|
rateLimitRequestsPerMinute: external_exports.number(),
|
|
38133
38140
|
rateLimitTokensPerMinute: external_exports.number()
|
|
38134
38141
|
});
|
|
@@ -38137,6 +38144,7 @@ var defaultAgentVersionConfig = {
|
|
|
38137
38144
|
model: "claude-sonnet-4-6",
|
|
38138
38145
|
temperature: 0.7,
|
|
38139
38146
|
maxTokens: 4096,
|
|
38147
|
+
maxSteps: 20,
|
|
38140
38148
|
rateLimitRequestsPerMinute: 20,
|
|
38141
38149
|
rateLimitTokensPerMinute: 2e5
|
|
38142
38150
|
};
|
|
@@ -43967,6 +43975,10 @@ var consoleLogsPayloadSchema = external_exports.object({
|
|
|
43967
43975
|
var runtimeErrorPayloadSchema = external_exports.object({
|
|
43968
43976
|
error: external_exports.string().nullable()
|
|
43969
43977
|
});
|
|
43978
|
+
var hostShortcutPayloadSchema = external_exports.enum([
|
|
43979
|
+
"commandPalette",
|
|
43980
|
+
"architect"
|
|
43981
|
+
]);
|
|
43970
43982
|
var pageInteractionPayloadSchema = external_exports.object({
|
|
43971
43983
|
clicks: external_exports.number().int().min(0),
|
|
43972
43984
|
keypresses: external_exports.number().int().min(0)
|
|
@@ -59728,6 +59740,7 @@ var agentFiles = (v) => ({
|
|
|
59728
59740
|
model: v.model,
|
|
59729
59741
|
temperature: v.temperature,
|
|
59730
59742
|
maxTokens: v.maxTokens,
|
|
59743
|
+
maxSteps: v.maxSteps,
|
|
59731
59744
|
rateLimitRequestsPerMinute: v.rateLimitRequestsPerMinute,
|
|
59732
59745
|
rateLimitTokensPerMinute: v.rateLimitTokensPerMinute,
|
|
59733
59746
|
functionIds: v.functionIds,
|
|
@@ -60187,7 +60200,7 @@ ${findings2.map((f) => ` ${f}`).join("\n")}`
|
|
|
60187
60200
|
}
|
|
60188
60201
|
});
|
|
60189
60202
|
var agentVersionFields = `
|
|
60190
|
-
versionNumber systemPrompt model temperature maxTokens
|
|
60203
|
+
versionNumber systemPrompt model temperature maxTokens maxSteps
|
|
60191
60204
|
rateLimitRequestsPerMinute rateLimitTokensPerMinute
|
|
60192
60205
|
agentVersionFunctionsByAgentIdAndVersionNumber(orderBy: [FUNCTION_ID_ASC]) {
|
|
60193
60206
|
nodes { functionId }
|
|
@@ -60211,6 +60224,7 @@ var flattenAgentVersion = (node2) => ({
|
|
|
60211
60224
|
model: node2.model,
|
|
60212
60225
|
temperature: node2.temperature,
|
|
60213
60226
|
maxTokens: node2.maxTokens,
|
|
60227
|
+
maxSteps: node2.maxSteps,
|
|
60214
60228
|
rateLimitRequestsPerMinute: node2.rateLimitRequestsPerMinute,
|
|
60215
60229
|
rateLimitTokensPerMinute: node2.rateLimitTokensPerMinute,
|
|
60216
60230
|
functionIds: node2.agentVersionFunctionsByAgentIdAndVersionNumber.nodes.map(
|
|
@@ -60305,7 +60319,7 @@ var agentSource = (client) => ({
|
|
|
60305
60319
|
const data = await client.graphql(
|
|
60306
60320
|
`mutation SdkCreateAgentVersion($expectedLatestVersion: Int,
|
|
60307
60321
|
$agentId: String!, $message: String!, $systemPrompt: String!,
|
|
60308
|
-
$model: String!, $temperature: Float!, $maxTokens: Int!,
|
|
60322
|
+
$model: String!, $temperature: Float!, $maxTokens: Int!, $maxSteps: Int,
|
|
60309
60323
|
$rateLimitRequestsPerMinute: Int!, $rateLimitTokensPerMinute: Int!,
|
|
60310
60324
|
$functionIds: [String], $tableSpaceBindings: JSON, $agentIds: [String],
|
|
60311
60325
|
$knowledgeBaseIds: [String], $builtinToolSets: [String]
|
|
@@ -60313,6 +60327,7 @@ var agentSource = (client) => ({
|
|
|
60313
60327
|
createAgentVersionWithAttachments(input: { expectedLatestVersion: $expectedLatestVersion,
|
|
60314
60328
|
agentId: $agentId, message: $message, systemPrompt: $systemPrompt,
|
|
60315
60329
|
model: $model, temperature: $temperature, maxTokens: $maxTokens,
|
|
60330
|
+
maxSteps: $maxSteps,
|
|
60316
60331
|
rateLimitRequestsPerMinute: $rateLimitRequestsPerMinute,
|
|
60317
60332
|
rateLimitTokensPerMinute: $rateLimitTokensPerMinute,
|
|
60318
60333
|
functionIds: $functionIds, tableSpaceBindings: $tableSpaceBindings,
|
|
@@ -60329,6 +60344,8 @@ var agentSource = (client) => ({
|
|
|
60329
60344
|
knowledgeBaseIds: input2.knowledgeBaseIds ?? [],
|
|
60330
60345
|
// Null keeps the current sets; an empty array clears them.
|
|
60331
60346
|
builtinToolSets: input2.builtinToolSets ?? null,
|
|
60347
|
+
// Null keeps the latest version's limit.
|
|
60348
|
+
maxSteps: input2.maxSteps ?? null,
|
|
60332
60349
|
expectedLatestVersion: options.expectedLatestVersion
|
|
60333
60350
|
}
|
|
60334
60351
|
);
|
|
@@ -60691,6 +60708,58 @@ var printablePageRender = (client, id) => ({
|
|
|
60691
60708
|
}
|
|
60692
60709
|
});
|
|
60693
60710
|
|
|
60711
|
+
// ../sdk/src/references.ts
|
|
60712
|
+
var referencesSchema = external_exports.object({
|
|
60713
|
+
inbound: external_exports.array(
|
|
60714
|
+
external_exports.object({
|
|
60715
|
+
resourceId: external_exports.string(),
|
|
60716
|
+
referencerId: external_exports.string(),
|
|
60717
|
+
referencerKind: external_exports.string(),
|
|
60718
|
+
referencerName: external_exports.string(),
|
|
60719
|
+
referencerWorkspaceId: external_exports.string()
|
|
60720
|
+
})
|
|
60721
|
+
),
|
|
60722
|
+
outbound: external_exports.array(
|
|
60723
|
+
external_exports.object({
|
|
60724
|
+
resourceId: external_exports.string(),
|
|
60725
|
+
targetId: external_exports.string(),
|
|
60726
|
+
targetKind: external_exports.string(),
|
|
60727
|
+
targetName: external_exports.string(),
|
|
60728
|
+
targetWorkspaceId: external_exports.string()
|
|
60729
|
+
})
|
|
60730
|
+
)
|
|
60731
|
+
});
|
|
60732
|
+
var resourceReferences = async (client, resourceIds, options) => resourceIds.length === 0 ? { inbound: [], outbound: [] } : referencesSchema.parse(
|
|
60733
|
+
await client.trpc("getResourceReferences", {
|
|
60734
|
+
resourceIds,
|
|
60735
|
+
referencerWorkspaceIds: options?.referencerWorkspaceIds
|
|
60736
|
+
})
|
|
60737
|
+
);
|
|
60738
|
+
var agentToolReachSchema = external_exports.array(
|
|
60739
|
+
external_exports.object({
|
|
60740
|
+
agentId: external_exports.string(),
|
|
60741
|
+
agentName: external_exports.string(),
|
|
60742
|
+
agentWorkspaceId: external_exports.string(),
|
|
60743
|
+
tools: external_exports.array(
|
|
60744
|
+
external_exports.object({
|
|
60745
|
+
kind: external_exports.string(),
|
|
60746
|
+
id: external_exports.string(),
|
|
60747
|
+
name: external_exports.string(),
|
|
60748
|
+
accessMode: external_exports.string().nullable(),
|
|
60749
|
+
isReachable: external_exports.boolean(),
|
|
60750
|
+
isReachableFromTarget: external_exports.boolean().nullable()
|
|
60751
|
+
})
|
|
60752
|
+
),
|
|
60753
|
+
hiddenCount: external_exports.number(),
|
|
60754
|
+
hiddenUnreachableCount: external_exports.number(),
|
|
60755
|
+
hiddenLostAtTargetCount: external_exports.number(),
|
|
60756
|
+
canShareIntoTarget: external_exports.boolean()
|
|
60757
|
+
})
|
|
60758
|
+
);
|
|
60759
|
+
var agentToolReach = async (client, agentIds, targetWorkspaceId) => agentToolReachSchema.parse(
|
|
60760
|
+
await client.trpc("getAgentToolReach", { agentIds, targetWorkspaceId })
|
|
60761
|
+
);
|
|
60762
|
+
|
|
60694
60763
|
// ../sdk/src/report.ts
|
|
60695
60764
|
var report = async (client, kind, details, options) => {
|
|
60696
60765
|
await client.trpc("architectIssues.report", {
|
|
@@ -60855,6 +60924,153 @@ var idTableByPrefix = (id) => {
|
|
|
60855
60924
|
return best?.table ?? null;
|
|
60856
60925
|
};
|
|
60857
60926
|
|
|
60927
|
+
// ../sdk/src/resourceGroups.ts
|
|
60928
|
+
var memberKind = (table) => table.replace(/_(\w)/g, (_, letter) => letter.toUpperCase());
|
|
60929
|
+
var resolveMember = async (client, resourceId) => {
|
|
60930
|
+
const row = await client.resource(resourceId).show();
|
|
60931
|
+
const table = idTableByPrefix(row.id);
|
|
60932
|
+
if (table == null) throw new Error(`Unsupported resource id: ${resourceId}`);
|
|
60933
|
+
return {
|
|
60934
|
+
member: { resourceKind: memberKind(table), resourceId: row.id },
|
|
60935
|
+
workspaceId: row.workspaceId
|
|
60936
|
+
};
|
|
60937
|
+
};
|
|
60938
|
+
var membershipOf = async (client, member) => {
|
|
60939
|
+
const data = await client.graphql(
|
|
60940
|
+
`query SdkResourceGroupMembership($resourceKind: String!, $resourceId: String!) {
|
|
60941
|
+
resourceGroupMembers(condition: { resourceKind: $resourceKind, resourceId: $resourceId }) {
|
|
60942
|
+
nodes { groupId group { name } }
|
|
60943
|
+
}
|
|
60944
|
+
}`,
|
|
60945
|
+
{ ...member }
|
|
60946
|
+
);
|
|
60947
|
+
const row = data.resourceGroupMembers?.nodes[0];
|
|
60948
|
+
return row == null ? null : { ...member, groupId: row.groupId, groupName: row.group?.name ?? null };
|
|
60949
|
+
};
|
|
60950
|
+
var removeMembership = async (client, member) => {
|
|
60951
|
+
const membership = await membershipOf(client, member);
|
|
60952
|
+
if (membership == null) return null;
|
|
60953
|
+
await client.graphql(
|
|
60954
|
+
`mutation SdkRemoveResourceGroupMember($resourceKind: String!, $resourceId: String!) {
|
|
60955
|
+
deleteResourceGroupMember(input: { resourceKind: $resourceKind, resourceId: $resourceId }) {
|
|
60956
|
+
deletedResourceGroupMemberNodeId
|
|
60957
|
+
}
|
|
60958
|
+
}`,
|
|
60959
|
+
{ ...member }
|
|
60960
|
+
);
|
|
60961
|
+
return membership;
|
|
60962
|
+
};
|
|
60963
|
+
var removeResourceFromGroup = async (client, storedId) => {
|
|
60964
|
+
const table = idTableByPrefix(storedId);
|
|
60965
|
+
return table == null ? null : removeMembership(client, {
|
|
60966
|
+
resourceKind: memberKind(table),
|
|
60967
|
+
resourceId: storedId
|
|
60968
|
+
});
|
|
60969
|
+
};
|
|
60970
|
+
var resourceGroupCollection = (client) => ({
|
|
60971
|
+
list: async (options) => {
|
|
60972
|
+
const data = await client.graphql(
|
|
60973
|
+
`query SdkResourceGroups($condition: ResourceGroupCondition) {
|
|
60974
|
+
resourceGroups(condition: $condition) {
|
|
60975
|
+
nodes {
|
|
60976
|
+
id name workspaceId
|
|
60977
|
+
resourceGroupMembersByGroupId { nodes { resourceKind resourceId } }
|
|
60978
|
+
}
|
|
60979
|
+
}
|
|
60980
|
+
}`,
|
|
60981
|
+
{
|
|
60982
|
+
condition: options?.workspaceId == null ? null : { workspaceId: options.workspaceId }
|
|
60983
|
+
}
|
|
60984
|
+
);
|
|
60985
|
+
return (data.resourceGroups?.nodes ?? []).map((group) => ({
|
|
60986
|
+
id: group.id,
|
|
60987
|
+
name: group.name,
|
|
60988
|
+
workspaceId: group.workspaceId,
|
|
60989
|
+
members: group.resourceGroupMembersByGroupId.nodes
|
|
60990
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
60991
|
+
},
|
|
60992
|
+
create: async (input2) => {
|
|
60993
|
+
const data = await client.graphql(
|
|
60994
|
+
`mutation SdkCreateResourceGroup($workspaceId: String!, $name: String!) {
|
|
60995
|
+
createResourceGroup(input: { resourceGroup: { workspaceId: $workspaceId, name: $name } }) {
|
|
60996
|
+
resourceGroup { id }
|
|
60997
|
+
}
|
|
60998
|
+
}`,
|
|
60999
|
+
input2
|
|
61000
|
+
);
|
|
61001
|
+
const id = data.createResourceGroup?.resourceGroup?.id;
|
|
61002
|
+
if (id == null) throw new Error("createResourceGroup returned no group.");
|
|
61003
|
+
return { id };
|
|
61004
|
+
},
|
|
61005
|
+
membershipOf: async (resourceId) => membershipOf(client, (await resolveMember(client, resourceId)).member),
|
|
61006
|
+
removeMember: async (resourceId) => removeMembership(client, (await resolveMember(client, resourceId)).member)
|
|
61007
|
+
});
|
|
61008
|
+
var resourceGroupResource = (client, id) => ({
|
|
61009
|
+
id,
|
|
61010
|
+
rename: async (name2) => {
|
|
61011
|
+
const data = await client.graphql(
|
|
61012
|
+
`mutation SdkRenameResourceGroup($id: String!, $name: String!) {
|
|
61013
|
+
updateResourceGroup(input: { id: $id, patch: { name: $name } }) { resourceGroup { id } }
|
|
61014
|
+
}`,
|
|
61015
|
+
{ id, name: name2 }
|
|
61016
|
+
);
|
|
61017
|
+
if (data.updateResourceGroup?.resourceGroup == null) {
|
|
61018
|
+
throw new Error(`Resource group ${id} was not renamed.`);
|
|
61019
|
+
}
|
|
61020
|
+
},
|
|
61021
|
+
delete: async () => {
|
|
61022
|
+
await client.graphql(
|
|
61023
|
+
`mutation SdkDeleteResourceGroup($id: String!) {
|
|
61024
|
+
deleteResourceGroup(input: { id: $id }) { deletedResourceGroupNodeId }
|
|
61025
|
+
}`,
|
|
61026
|
+
{ id }
|
|
61027
|
+
);
|
|
61028
|
+
},
|
|
61029
|
+
add: async (resourceIds) => {
|
|
61030
|
+
const data = await client.graphql(
|
|
61031
|
+
`query SdkResourceGroupWorkspace($id: String!) {
|
|
61032
|
+
resourceGroup(id: $id) { workspaceId }
|
|
61033
|
+
}`,
|
|
61034
|
+
{ id }
|
|
61035
|
+
);
|
|
61036
|
+
const groupWorkspaceId = data.resourceGroup?.workspaceId;
|
|
61037
|
+
if (groupWorkspaceId == null) {
|
|
61038
|
+
throw new Error(
|
|
61039
|
+
`Resource group ${id} not found (or not editable by you).`
|
|
61040
|
+
);
|
|
61041
|
+
}
|
|
61042
|
+
const resolved = await Promise.all(
|
|
61043
|
+
resourceIds.map(async (resourceId) => ({
|
|
61044
|
+
resourceId,
|
|
61045
|
+
...await resolveMember(client, resourceId)
|
|
61046
|
+
}))
|
|
61047
|
+
);
|
|
61048
|
+
const misplaced = resolved.filter(
|
|
61049
|
+
(entry) => entry.workspaceId !== groupWorkspaceId
|
|
61050
|
+
);
|
|
61051
|
+
if (misplaced.length > 0) {
|
|
61052
|
+
throw new Error(
|
|
61053
|
+
`${misplaced.map(
|
|
61054
|
+
(entry) => `${entry.resourceId} is in workspace ${String(entry.workspaceId)}`
|
|
61055
|
+
).join("; ")}, but group ${id} is in ${groupWorkspaceId}. Move ${misplaced.length === 1 ? "it" : "them"} to that workspace first.`
|
|
61056
|
+
);
|
|
61057
|
+
}
|
|
61058
|
+
const previous = [];
|
|
61059
|
+
for (const { member } of resolved) {
|
|
61060
|
+
previous.push(await removeMembership(client, member));
|
|
61061
|
+
await client.graphql(
|
|
61062
|
+
`mutation SdkAddResourceGroupMember($member: ResourceGroupMemberInput!) {
|
|
61063
|
+
createResourceGroupMember(input: { resourceGroupMember: $member }) {
|
|
61064
|
+
resourceGroupMember { groupId }
|
|
61065
|
+
}
|
|
61066
|
+
}`,
|
|
61067
|
+
{ member: { groupId: id, ...member } }
|
|
61068
|
+
);
|
|
61069
|
+
}
|
|
61070
|
+
return previous;
|
|
61071
|
+
}
|
|
61072
|
+
});
|
|
61073
|
+
|
|
60858
61074
|
// ../sdk/src/resourceShow.ts
|
|
60859
61075
|
var resourceTables = {
|
|
60860
61076
|
workspace: {
|
|
@@ -61018,7 +61234,33 @@ var genericResource = (client, id) => {
|
|
|
61018
61234
|
throw new Error(`No supported changes supplied for ${id}.`);
|
|
61019
61235
|
}
|
|
61020
61236
|
return show(current.id);
|
|
61021
|
-
}
|
|
61237
|
+
},
|
|
61238
|
+
move: async (workspaceId) => {
|
|
61239
|
+
const resource = resourceTableFor(id);
|
|
61240
|
+
if (resource === resourceTables.workspace) {
|
|
61241
|
+
throw new Error(
|
|
61242
|
+
`${id} is a workspace; reparent it instead of moving it.`
|
|
61243
|
+
);
|
|
61244
|
+
}
|
|
61245
|
+
const current = await show(id);
|
|
61246
|
+
const result = await client.graphql(
|
|
61247
|
+
`mutation SdkMoveResource($id: String!, $workspaceId: String!) {
|
|
61248
|
+
${resource.mutation}(input: { id: $id, patch: { workspaceId: $workspaceId } }) {
|
|
61249
|
+
updated: ${resource.result} { id workspaceId }
|
|
61250
|
+
}
|
|
61251
|
+
}`,
|
|
61252
|
+
{ id: current.id, workspaceId }
|
|
61253
|
+
);
|
|
61254
|
+
const updated = result[resource.mutation]?.updated;
|
|
61255
|
+
if (updated == null) {
|
|
61256
|
+
throw new Error(
|
|
61257
|
+
`Resource ${id} was not moved; check that you can edit both workspaces.`
|
|
61258
|
+
);
|
|
61259
|
+
}
|
|
61260
|
+
const leftGroup = await removeResourceFromGroup(client, current.id);
|
|
61261
|
+
return { ...updated, leftGroup };
|
|
61262
|
+
},
|
|
61263
|
+
references: () => resourceReferences(client, [id])
|
|
61022
61264
|
};
|
|
61023
61265
|
};
|
|
61024
61266
|
|
|
@@ -61321,9 +61563,137 @@ var tableSpaceCredentialResource = (client, credentialId) => {
|
|
|
61321
61563
|
var exchangeSchema = external_exports.object({ token: external_exports.string(), expiresIn: external_exports.number() });
|
|
61322
61564
|
var staticToken = (jwt2) => () => jwt2;
|
|
61323
61565
|
|
|
61566
|
+
// ../sdk/src/paginate.ts
|
|
61567
|
+
var paginate = async (client, query, field, variables = {}) => {
|
|
61568
|
+
const nodes = [];
|
|
61569
|
+
let after = null;
|
|
61570
|
+
do {
|
|
61571
|
+
const data = await client.graphql(
|
|
61572
|
+
query,
|
|
61573
|
+
{ ...variables, after }
|
|
61574
|
+
);
|
|
61575
|
+
const connection = data[field];
|
|
61576
|
+
if (connection == null) return nodes;
|
|
61577
|
+
nodes.push(...connection.nodes);
|
|
61578
|
+
const page = connection.pageInfo;
|
|
61579
|
+
if (page.hasNextPage && (page.endCursor == null || page.endCursor === after))
|
|
61580
|
+
throw new Error(`${field} pagination did not advance.`);
|
|
61581
|
+
after = page.hasNextPage ? page.endCursor : null;
|
|
61582
|
+
} while (after != null);
|
|
61583
|
+
return nodes;
|
|
61584
|
+
};
|
|
61585
|
+
|
|
61324
61586
|
// ../sdk/src/workspaces.ts
|
|
61587
|
+
var SHARE_KINDS = [
|
|
61588
|
+
"table_space",
|
|
61589
|
+
"function",
|
|
61590
|
+
"agent",
|
|
61591
|
+
"integration",
|
|
61592
|
+
"action_runner"
|
|
61593
|
+
];
|
|
61594
|
+
var SHARE_FIELDS = "id fromWorkspaceId toWorkspaceId resourceKind resourceId fromWorkspace { name } toWorkspace { name }";
|
|
61595
|
+
var shareFromRow = (row) => ({
|
|
61596
|
+
id: row.id,
|
|
61597
|
+
fromWorkspaceId: row.fromWorkspaceId,
|
|
61598
|
+
fromWorkspaceName: row.fromWorkspace?.name ?? null,
|
|
61599
|
+
toWorkspaceId: row.toWorkspaceId,
|
|
61600
|
+
toWorkspaceName: row.toWorkspace?.name ?? null,
|
|
61601
|
+
resourceKind: row.resourceKind,
|
|
61602
|
+
resourceId: row.resourceId
|
|
61603
|
+
});
|
|
61604
|
+
var storedShareEnds = async (client, from, to) => {
|
|
61605
|
+
const data = await client.graphql(
|
|
61606
|
+
`query SdkShareWorkspaceIds($from: String!, $to: String!) {
|
|
61607
|
+
from: workspaces(condition: { idIgnoringCase: $from }, includeArchived: YES, first: 1) { nodes { id } }
|
|
61608
|
+
to: workspaces(condition: { idIgnoringCase: $to }, includeArchived: YES, first: 1) { nodes { id } }
|
|
61609
|
+
}`,
|
|
61610
|
+
{ from, to }
|
|
61611
|
+
);
|
|
61612
|
+
const stored = {
|
|
61613
|
+
from: data.from?.nodes[0]?.id,
|
|
61614
|
+
to: data.to?.nodes[0]?.id
|
|
61615
|
+
};
|
|
61616
|
+
if (stored.from == null) {
|
|
61617
|
+
throw new Error(`Workspace ${from} not found (or not visible to you).`);
|
|
61618
|
+
}
|
|
61619
|
+
if (stored.to == null) {
|
|
61620
|
+
throw new Error(`Workspace ${to} not found (or not visible to you).`);
|
|
61621
|
+
}
|
|
61622
|
+
return { from: stored.from, to: stored.to };
|
|
61623
|
+
};
|
|
61624
|
+
var workspaceTree = async (client, includeArchived) => {
|
|
61625
|
+
const [workspaces, edges, roles] = await Promise.all([
|
|
61626
|
+
paginate(
|
|
61627
|
+
client,
|
|
61628
|
+
`query SdkWorkspaceTreeNodes($after: Cursor, $includeArchived: IncludeArchivedOption!) {
|
|
61629
|
+
workspaces(first: 100, after: $after, includeArchived: $includeArchived) {
|
|
61630
|
+
nodes { id name isArchived }
|
|
61631
|
+
pageInfo { hasNextPage endCursor }
|
|
61632
|
+
}
|
|
61633
|
+
}`,
|
|
61634
|
+
"workspaces",
|
|
61635
|
+
{ includeArchived: includeArchived ? "YES" : "NO" }
|
|
61636
|
+
),
|
|
61637
|
+
paginate(
|
|
61638
|
+
client,
|
|
61639
|
+
`query SdkWorkspaceTreeEdges($after: Cursor) {
|
|
61640
|
+
workspaceWorkspaces(first: 100, after: $after) {
|
|
61641
|
+
nodes { workspaceId parentWorkspaceId }
|
|
61642
|
+
pageInfo { hasNextPage endCursor }
|
|
61643
|
+
}
|
|
61644
|
+
}`,
|
|
61645
|
+
"workspaceWorkspaces"
|
|
61646
|
+
),
|
|
61647
|
+
client.graphql(
|
|
61648
|
+
`query SdkWorkspaceTreeRoles { myWorkspaceRoles { nodes { workspaceId role } } }`
|
|
61649
|
+
)
|
|
61650
|
+
]);
|
|
61651
|
+
const role = new Map(
|
|
61652
|
+
roles.myWorkspaceRoles.nodes.map((r) => [r.workspaceId, r.role])
|
|
61653
|
+
);
|
|
61654
|
+
const parentOf = new Map(
|
|
61655
|
+
edges.map((e) => [e.workspaceId, e.parentWorkspaceId])
|
|
61656
|
+
);
|
|
61657
|
+
const nodes = new Map(
|
|
61658
|
+
workspaces.map((w) => [
|
|
61659
|
+
w.id,
|
|
61660
|
+
{
|
|
61661
|
+
id: w.id,
|
|
61662
|
+
name: w.name,
|
|
61663
|
+
isArchived: w.isArchived,
|
|
61664
|
+
role: role.get(w.id) ?? null,
|
|
61665
|
+
parentWorkspaceId: null,
|
|
61666
|
+
children: []
|
|
61667
|
+
}
|
|
61668
|
+
])
|
|
61669
|
+
);
|
|
61670
|
+
const roots = [...nodes.values()].filter((node2) => {
|
|
61671
|
+
const parent = nodes.get(parentOf.get(node2.id) ?? "");
|
|
61672
|
+
if (parent == null) return true;
|
|
61673
|
+
node2.parentWorkspaceId = parent.id;
|
|
61674
|
+
parent.children.push(node2);
|
|
61675
|
+
return false;
|
|
61676
|
+
});
|
|
61677
|
+
const sort2 = (list) => {
|
|
61678
|
+
list.sort((a, b) => a.name.localeCompare(b.name));
|
|
61679
|
+
list.forEach((node2) => sort2(node2.children));
|
|
61680
|
+
return list;
|
|
61681
|
+
};
|
|
61682
|
+
return sort2(roots);
|
|
61683
|
+
};
|
|
61325
61684
|
var workspaceCollection = (client) => ({
|
|
61326
61685
|
create: (input2) => createWorkspace(client, input2),
|
|
61686
|
+
tree: (options) => workspaceTree(client, options?.includeArchived === true),
|
|
61687
|
+
shares: async () => (await paginate(
|
|
61688
|
+
client,
|
|
61689
|
+
`query SdkAllWorkspaceShares($after: Cursor) {
|
|
61690
|
+
workspaceResourceShares(first: 100, after: $after) {
|
|
61691
|
+
nodes { ${SHARE_FIELDS} }
|
|
61692
|
+
pageInfo { hasNextPage endCursor }
|
|
61693
|
+
}
|
|
61694
|
+
}`,
|
|
61695
|
+
"workspaceResourceShares"
|
|
61696
|
+
)).map(shareFromRow),
|
|
61327
61697
|
list: async (options) => {
|
|
61328
61698
|
const data = await client.graphql(
|
|
61329
61699
|
`query SdkWorkspaceList($first: Int!, $includeArchived: IncludeArchivedOption!) {
|
|
@@ -61397,6 +61767,109 @@ var workspaceResource = (client, id) => ({
|
|
|
61397
61767
|
}
|
|
61398
61768
|
]
|
|
61399
61769
|
);
|
|
61770
|
+
},
|
|
61771
|
+
tree: async (options) => {
|
|
61772
|
+
const find2 = (list) => list.map(
|
|
61773
|
+
(node3) => node3.id.toLowerCase() === id.toLowerCase() ? node3 : find2(node3.children)
|
|
61774
|
+
).find((node3) => node3 != null);
|
|
61775
|
+
const node2 = find2(
|
|
61776
|
+
await workspaceTree(client, options?.includeArchived === true)
|
|
61777
|
+
);
|
|
61778
|
+
if (node2 == null) {
|
|
61779
|
+
throw new Error(`Workspace ${id} not found (or not visible to you).`);
|
|
61780
|
+
}
|
|
61781
|
+
return node2;
|
|
61782
|
+
},
|
|
61783
|
+
setParent: async (parentWorkspaceId) => {
|
|
61784
|
+
const data = await client.graphql(
|
|
61785
|
+
`mutation SdkSetWorkspaceParent($workspaceId: String!, $parentWorkspaceId: String!) {
|
|
61786
|
+
setWorkspaceParent(input: { workspaceId: $workspaceId, parentWorkspaceId: $parentWorkspaceId }) {
|
|
61787
|
+
workspaceWorkspace { workspaceId }
|
|
61788
|
+
}
|
|
61789
|
+
}`,
|
|
61790
|
+
{ workspaceId: id, parentWorkspaceId }
|
|
61791
|
+
);
|
|
61792
|
+
if (data.setWorkspaceParent?.workspaceWorkspace == null) {
|
|
61793
|
+
throw new Error(
|
|
61794
|
+
`Workspace ${id} was not moved; check that you manage both workspaces.`
|
|
61795
|
+
);
|
|
61796
|
+
}
|
|
61797
|
+
},
|
|
61798
|
+
moveToRoot: async () => {
|
|
61799
|
+
const data = await client.graphql(
|
|
61800
|
+
`mutation SdkMoveWorkspaceToRoot($workspaceId: String!) {
|
|
61801
|
+
deleteWorkspaceWorkspaceByWorkspaceId(input: { workspaceId: $workspaceId }) {
|
|
61802
|
+
workspaceWorkspace { workspaceId }
|
|
61803
|
+
}
|
|
61804
|
+
}`,
|
|
61805
|
+
{ workspaceId: id }
|
|
61806
|
+
);
|
|
61807
|
+
return data.deleteWorkspaceWorkspaceByWorkspaceId?.workspaceWorkspace != null;
|
|
61808
|
+
},
|
|
61809
|
+
shares: async () => {
|
|
61810
|
+
const data = await client.graphql(
|
|
61811
|
+
`query SdkWorkspaceShares($id: String!) {
|
|
61812
|
+
from: workspaceResourceShares(condition: { fromWorkspaceId: $id }) { nodes { ${SHARE_FIELDS} } }
|
|
61813
|
+
to: workspaceResourceShares(condition: { toWorkspaceId: $id }) { nodes { ${SHARE_FIELDS} } }
|
|
61814
|
+
}`,
|
|
61815
|
+
{ id }
|
|
61816
|
+
);
|
|
61817
|
+
return [...data.from?.nodes ?? [], ...data.to?.nodes ?? []].map(
|
|
61818
|
+
shareFromRow
|
|
61819
|
+
);
|
|
61820
|
+
},
|
|
61821
|
+
share: async (input2) => {
|
|
61822
|
+
if (!SHARE_KINDS.includes(input2.kind)) {
|
|
61823
|
+
throw new Error(
|
|
61824
|
+
`Unknown share kind "${input2.kind}". Use one of: ${SHARE_KINDS.join(", ")}.`
|
|
61825
|
+
);
|
|
61826
|
+
}
|
|
61827
|
+
const ends = await storedShareEnds(client, id, input2.toWorkspaceId);
|
|
61828
|
+
const data = await client.graphql(
|
|
61829
|
+
`mutation SdkCreateWorkspaceShare($share: WorkspaceResourceShareInput!) {
|
|
61830
|
+
createWorkspaceResourceShare(input: { workspaceResourceShare: $share }) {
|
|
61831
|
+
workspaceResourceShare { id }
|
|
61832
|
+
}
|
|
61833
|
+
}`,
|
|
61834
|
+
{
|
|
61835
|
+
share: {
|
|
61836
|
+
fromWorkspaceId: ends.from,
|
|
61837
|
+
toWorkspaceId: ends.to,
|
|
61838
|
+
resourceKind: input2.kind,
|
|
61839
|
+
resourceId: input2.resourceId ?? null
|
|
61840
|
+
}
|
|
61841
|
+
}
|
|
61842
|
+
);
|
|
61843
|
+
const shareId = data.createWorkspaceResourceShare?.workspaceResourceShare?.id;
|
|
61844
|
+
if (shareId == null)
|
|
61845
|
+
throw new Error("createWorkspaceResourceShare returned no share.");
|
|
61846
|
+
return { id: shareId };
|
|
61847
|
+
},
|
|
61848
|
+
unshare: async (input2) => {
|
|
61849
|
+
const ends = await storedShareEnds(client, id, input2.toWorkspaceId);
|
|
61850
|
+
const data = await client.graphql(
|
|
61851
|
+
`query SdkFindWorkspaceShare($from: String!, $to: String!, $kind: String!) {
|
|
61852
|
+
workspaceResourceShares(condition: { fromWorkspaceId: $from, toWorkspaceId: $to, resourceKind: $kind }) {
|
|
61853
|
+
nodes { ${SHARE_FIELDS} }
|
|
61854
|
+
}
|
|
61855
|
+
}`,
|
|
61856
|
+
{ from: ends.from, to: ends.to, kind: input2.kind }
|
|
61857
|
+
);
|
|
61858
|
+
const resourceId = input2.resourceId?.toLowerCase() ?? null;
|
|
61859
|
+
const row = data.workspaceResourceShares?.nodes.find(
|
|
61860
|
+
(share) => (share.resourceId?.toLowerCase() ?? null) === resourceId
|
|
61861
|
+
);
|
|
61862
|
+
if (row == null) {
|
|
61863
|
+
throw new Error(
|
|
61864
|
+
`No ${input2.resourceId == null ? `whole-kind ${input2.kind}` : `${input2.kind} ${input2.resourceId}`} share from ${ends.from} to ${ends.to}.`
|
|
61865
|
+
);
|
|
61866
|
+
}
|
|
61867
|
+
await client.graphql(
|
|
61868
|
+
`mutation SdkDeleteWorkspaceShare($id: String!) {
|
|
61869
|
+
deleteWorkspaceResourceShare(input: { id: $id }) { deletedWorkspaceResourceShareNodeId }
|
|
61870
|
+
}`,
|
|
61871
|
+
{ id: row.id }
|
|
61872
|
+
);
|
|
61400
61873
|
}
|
|
61401
61874
|
});
|
|
61402
61875
|
|
|
@@ -61515,6 +61988,7 @@ var OverAIClient = class {
|
|
|
61515
61988
|
};
|
|
61516
61989
|
workspaces = workspaceCollection(this);
|
|
61517
61990
|
runners = runnerCollection(this);
|
|
61991
|
+
resourceGroups = resourceGroupCollection(this);
|
|
61518
61992
|
storage = storageApi(this);
|
|
61519
61993
|
/** Its `deploy` checks deployed callers first; see `FunctionResource`. */
|
|
61520
61994
|
fn(id) {
|
|
@@ -61584,6 +62058,20 @@ var OverAIClient = class {
|
|
|
61584
62058
|
resource(id) {
|
|
61585
62059
|
return genericResource(this, id);
|
|
61586
62060
|
}
|
|
62061
|
+
resourceGroup(id) {
|
|
62062
|
+
return resourceGroupResource(this, id);
|
|
62063
|
+
}
|
|
62064
|
+
/**
|
|
62065
|
+
* References to and from many resources at once (at most 200 ids).
|
|
62066
|
+
* `referencerWorkspaceIds` limits inbound referencers to those workspaces.
|
|
62067
|
+
*/
|
|
62068
|
+
resourceReferences(resourceIds, options) {
|
|
62069
|
+
return resourceReferences(this, resourceIds, options);
|
|
62070
|
+
}
|
|
62071
|
+
/** Whether each agent's deployed tools resolve from its workspace and from `targetWorkspaceId`. */
|
|
62072
|
+
agentToolReach(agentIds, targetWorkspaceId) {
|
|
62073
|
+
return agentToolReach(this, agentIds, targetWorkspaceId);
|
|
62074
|
+
}
|
|
61587
62075
|
/** Claims of the JWT most recently obtained from the token source, or null before any request. Display only. */
|
|
61588
62076
|
claims() {
|
|
61589
62077
|
return this.#claims;
|
|
@@ -61902,6 +62390,9 @@ var unknownFlags = (args, known, valueFlags = []) => {
|
|
|
61902
62390
|
}
|
|
61903
62391
|
return out;
|
|
61904
62392
|
};
|
|
62393
|
+
var positionals = (args, valueFlags) => args.filter(
|
|
62394
|
+
(arg, index) => !arg.startsWith("-") && !valueFlags.includes(args[index - 1] ?? "")
|
|
62395
|
+
);
|
|
61905
62396
|
var flagValue = (args, ...names) => {
|
|
61906
62397
|
for (const name2 of names) {
|
|
61907
62398
|
const i = args.indexOf(name2);
|
|
@@ -63206,7 +63697,7 @@ ${lines.join("\n")}
|
|
|
63206
63697
|
var runRestore = (args) => {
|
|
63207
63698
|
const { root, manifest } = openClone();
|
|
63208
63699
|
const all = args.includes("--all");
|
|
63209
|
-
const filter2 =
|
|
63700
|
+
const filter2 = positionals2(args)[0];
|
|
63210
63701
|
if (filter2 == null && !all) {
|
|
63211
63702
|
throw new Error(
|
|
63212
63703
|
"Usage: overai restore <filter> (resource id, name, or path substring), or --all to discard every local edit."
|
|
@@ -63309,7 +63800,7 @@ var runPull = async (clone2) => {
|
|
|
63309
63800
|
var resourcesMatching = (manifest, filter2) => Object.entries(manifest.resources).filter(
|
|
63310
63801
|
([id, resource]) => filter2 == null || id === filter2 || resource.name.toLowerCase().includes(filter2.toLowerCase()) || resource.files.some((f) => f.includes(filter2))
|
|
63311
63802
|
);
|
|
63312
|
-
var
|
|
63803
|
+
var positionals2 = (args) => {
|
|
63313
63804
|
const valueFlags = /* @__PURE__ */ new Set(["-m", "--message", "-o", "--output"]);
|
|
63314
63805
|
const out = [];
|
|
63315
63806
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -63351,7 +63842,7 @@ var runPush = async (args, clone2) => {
|
|
|
63351
63842
|
const deploy = args.includes("--deploy");
|
|
63352
63843
|
const force = args.includes("--force");
|
|
63353
63844
|
const allowBreaking = args.includes("--allow-breaking");
|
|
63354
|
-
const pathFilter =
|
|
63845
|
+
const pathFilter = positionals2(args)[0];
|
|
63355
63846
|
let pushed = 0;
|
|
63356
63847
|
for (const [id, resource] of resourcesMatching(manifest, pathFilter)) {
|
|
63357
63848
|
const { state, changedFiles } = localState(root, resource);
|
|
@@ -63434,7 +63925,7 @@ var runPush = async (args, clone2) => {
|
|
|
63434
63925
|
};
|
|
63435
63926
|
var runDeploy = async (args) => {
|
|
63436
63927
|
const { root, manifest } = openClone();
|
|
63437
|
-
const pathFilter =
|
|
63928
|
+
const pathFilter = positionals2(args)[0];
|
|
63438
63929
|
const allowBreaking = args.includes("--allow-breaking");
|
|
63439
63930
|
const pending = resourcesMatching(manifest, pathFilter).filter(
|
|
63440
63931
|
([, r]) => r.deployedVersion !== r.baseVersion
|
|
@@ -64700,12 +65191,478 @@ var runReport = async (args) => {
|
|
|
64700
65191
|
);
|
|
64701
65192
|
};
|
|
64702
65193
|
|
|
65194
|
+
// src/commands/move.ts
|
|
65195
|
+
var printReport = (args, report2) => {
|
|
65196
|
+
if (flagValue(args, "-o", "--output") === "json") {
|
|
65197
|
+
printResult(report2, "json");
|
|
65198
|
+
return;
|
|
65199
|
+
}
|
|
65200
|
+
process.stdout.write(
|
|
65201
|
+
[
|
|
65202
|
+
...report2.plan,
|
|
65203
|
+
"",
|
|
65204
|
+
...report2.warnings.length === 0 ? ["No warnings."] : report2.warnings.map(
|
|
65205
|
+
(line, index) => index === 0 ? line : ` ${line}`
|
|
65206
|
+
),
|
|
65207
|
+
"",
|
|
65208
|
+
report2.dryRun ? "Dry run: nothing changed." : ""
|
|
65209
|
+
].join("\n").trimEnd() + "\n"
|
|
65210
|
+
);
|
|
65211
|
+
};
|
|
65212
|
+
var workspacesById = (forest) => {
|
|
65213
|
+
const byId = /* @__PURE__ */ new Map();
|
|
65214
|
+
const visit2 = (node2) => {
|
|
65215
|
+
byId.set(node2.id.toLowerCase(), node2);
|
|
65216
|
+
node2.children.forEach(visit2);
|
|
65217
|
+
};
|
|
65218
|
+
forest.forEach(visit2);
|
|
65219
|
+
return byId;
|
|
65220
|
+
};
|
|
65221
|
+
var subtreeIds = (node2) => [
|
|
65222
|
+
node2.id,
|
|
65223
|
+
...node2.children.flatMap(subtreeIds)
|
|
65224
|
+
];
|
|
65225
|
+
var userLabel = (user) => user.email ?? user.name ?? user.id;
|
|
65226
|
+
var ROLE_ORDER = ["manager", "editor", "viewer", "end_user"];
|
|
65227
|
+
var roleRank = (role) => {
|
|
65228
|
+
const rank = role == null ? -1 : ROLE_ORDER.indexOf(role);
|
|
65229
|
+
return rank === -1 ? ROLE_ORDER.length : rank;
|
|
65230
|
+
};
|
|
65231
|
+
var strongerRole = (a, b) => roleRank(a) <= roleRank(b) ? a : b;
|
|
65232
|
+
var reaches = (shares, from, to, kind, resourceId) => {
|
|
65233
|
+
const target = to.toLowerCase();
|
|
65234
|
+
const seen = /* @__PURE__ */ new Set([from.toLowerCase()]);
|
|
65235
|
+
const queue = [from.toLowerCase()];
|
|
65236
|
+
for (let at = queue.shift(); at != null; at = queue.shift()) {
|
|
65237
|
+
if (at === target) return true;
|
|
65238
|
+
shares.filter(
|
|
65239
|
+
(share) => share.fromWorkspaceId.toLowerCase() === at && share.resourceKind === kind && (share.resourceId == null || share.resourceId.toLowerCase() === resourceId.toLowerCase())
|
|
65240
|
+
).forEach((share) => {
|
|
65241
|
+
const next = share.toWorkspaceId.toLowerCase();
|
|
65242
|
+
if (!seen.has(next)) {
|
|
65243
|
+
seen.add(next);
|
|
65244
|
+
queue.push(next);
|
|
65245
|
+
}
|
|
65246
|
+
});
|
|
65247
|
+
}
|
|
65248
|
+
return false;
|
|
65249
|
+
};
|
|
65250
|
+
var rowName = (row) => {
|
|
65251
|
+
if (typeof row.name === "string") return row.name;
|
|
65252
|
+
const identity = row.identity;
|
|
65253
|
+
return typeof identity?.name === "string" ? identity.name : row.id;
|
|
65254
|
+
};
|
|
65255
|
+
var accessibleViews = {
|
|
65256
|
+
function: {
|
|
65257
|
+
collection: "workspaceAccessibleFunctions",
|
|
65258
|
+
idField: "functionId",
|
|
65259
|
+
relation: "function"
|
|
65260
|
+
},
|
|
65261
|
+
table_space: {
|
|
65262
|
+
collection: "workspaceAccessibleTableSpaces",
|
|
65263
|
+
idField: "tableSpaceId",
|
|
65264
|
+
relation: "tableSpace"
|
|
65265
|
+
},
|
|
65266
|
+
agent: {
|
|
65267
|
+
collection: "workspaceAccessibleAgents",
|
|
65268
|
+
idField: "agentId",
|
|
65269
|
+
relation: "agent"
|
|
65270
|
+
},
|
|
65271
|
+
integration: {
|
|
65272
|
+
collection: "workspaceAccessibleIntegrations",
|
|
65273
|
+
idField: "integrationId",
|
|
65274
|
+
relation: "integration"
|
|
65275
|
+
},
|
|
65276
|
+
action_runner: {
|
|
65277
|
+
collection: "workspaceAccessibleActionRunners",
|
|
65278
|
+
idField: "actionRunnerId",
|
|
65279
|
+
relation: "actionRunner"
|
|
65280
|
+
}
|
|
65281
|
+
};
|
|
65282
|
+
var SHARED_RESOURCE_CAP = 200;
|
|
65283
|
+
var sharedResources = async (client, share) => {
|
|
65284
|
+
if (share.resourceId != null) {
|
|
65285
|
+
const row = await client.resource(share.resourceId).show().catch(() => null);
|
|
65286
|
+
return {
|
|
65287
|
+
resources: [
|
|
65288
|
+
{
|
|
65289
|
+
id: share.resourceId,
|
|
65290
|
+
name: row == null ? share.resourceId : rowName(row)
|
|
65291
|
+
}
|
|
65292
|
+
],
|
|
65293
|
+
total: 1
|
|
65294
|
+
};
|
|
65295
|
+
}
|
|
65296
|
+
const kind = SHARE_KINDS.find((known) => known === share.resourceKind);
|
|
65297
|
+
if (kind == null) return { resources: [], total: 0 };
|
|
65298
|
+
const view = accessibleViews[kind];
|
|
65299
|
+
const data = await client.graphql(
|
|
65300
|
+
`query CliSharedKindResources($workspaceId: String!, $first: Int!) {
|
|
65301
|
+
${view.collection}(condition: { workspaceId: $workspaceId }, first: $first) {
|
|
65302
|
+
totalCount
|
|
65303
|
+
nodes { ${view.idField} ${view.relation} { ${resourceTables[kind].fields} } }
|
|
65304
|
+
}
|
|
65305
|
+
}`,
|
|
65306
|
+
{ workspaceId: share.fromWorkspaceId, first: SHARED_RESOURCE_CAP }
|
|
65307
|
+
);
|
|
65308
|
+
const connection = data[view.collection];
|
|
65309
|
+
return {
|
|
65310
|
+
resources: (connection?.nodes ?? []).map((node2) => {
|
|
65311
|
+
const id = String(node2[view.idField]);
|
|
65312
|
+
const row = node2[view.relation];
|
|
65313
|
+
return { id, name: row == null ? id : rowName(row) };
|
|
65314
|
+
}),
|
|
65315
|
+
total: connection?.totalCount ?? 0
|
|
65316
|
+
};
|
|
65317
|
+
};
|
|
65318
|
+
var moveWorkspace = async (args) => {
|
|
65319
|
+
const [workspaceId] = positionals(args, ["--to", "-o", "--output"]);
|
|
65320
|
+
const to = flagValue(args, "--to");
|
|
65321
|
+
if (workspaceId == null || to == null) {
|
|
65322
|
+
throw new Error(
|
|
65323
|
+
"Usage: overai workspace move <workspaceId> --to <parentWorkspaceId|root> [--dry-run]"
|
|
65324
|
+
);
|
|
65325
|
+
}
|
|
65326
|
+
const dryRun = args.includes("--dry-run");
|
|
65327
|
+
const client = cliClient();
|
|
65328
|
+
const [forest, allShares] = await Promise.all([
|
|
65329
|
+
client.workspaces.tree({ includeArchived: true }),
|
|
65330
|
+
client.workspaces.shares()
|
|
65331
|
+
]);
|
|
65332
|
+
const byId = workspacesById(forest);
|
|
65333
|
+
const label = (id) => {
|
|
65334
|
+
if (id == null) return "the top level";
|
|
65335
|
+
const node2 = byId.get(id.toLowerCase());
|
|
65336
|
+
return node2 == null ? id : `"${node2.name}" (${node2.id})`;
|
|
65337
|
+
};
|
|
65338
|
+
const moved = byId.get(workspaceId.toLowerCase());
|
|
65339
|
+
if (moved == null) {
|
|
65340
|
+
throw new Error(
|
|
65341
|
+
`Workspace ${workspaceId} not found (or not visible to you).`
|
|
65342
|
+
);
|
|
65343
|
+
}
|
|
65344
|
+
const newParent = to === "root" ? null : byId.get(to.toLowerCase());
|
|
65345
|
+
if (newParent === void 0) {
|
|
65346
|
+
throw new Error(`Workspace ${to} not found (or not visible to you).`);
|
|
65347
|
+
}
|
|
65348
|
+
const oldParentId = moved.parentWorkspaceId;
|
|
65349
|
+
if (oldParentId != null && oldParentId.toLowerCase() === newParent?.id.toLowerCase()) {
|
|
65350
|
+
(flagValue(args, "-o", "--output") === "json" ? process.stderr : process.stdout).write(
|
|
65351
|
+
`${label(moved.id)} is already under ${label(oldParentId)}; nothing to move.
|
|
65352
|
+
`
|
|
65353
|
+
);
|
|
65354
|
+
return;
|
|
65355
|
+
}
|
|
65356
|
+
const subtreeStoredIds = subtreeIds(moved);
|
|
65357
|
+
const subtree = new Set(subtreeStoredIds.map((id) => id.toLowerCase()));
|
|
65358
|
+
const deletedShares = oldParentId == null ? [] : allShares.filter(
|
|
65359
|
+
(share) => share.fromWorkspaceId.toLowerCase() === oldParentId.toLowerCase() && share.toWorkspaceId.toLowerCase() === moved.id.toLowerCase()
|
|
65360
|
+
);
|
|
65361
|
+
const [movedUsers, parentUsers, shared] = await Promise.all([
|
|
65362
|
+
client.workspace(moved.id).users(),
|
|
65363
|
+
newParent == null ? [] : client.workspace(newParent.id).users(),
|
|
65364
|
+
Promise.all(
|
|
65365
|
+
deletedShares.map(async (share) => ({
|
|
65366
|
+
share,
|
|
65367
|
+
...await sharedResources(client, share)
|
|
65368
|
+
}))
|
|
65369
|
+
)
|
|
65370
|
+
]);
|
|
65371
|
+
const plan = [
|
|
65372
|
+
`Moving workspace ${label(moved.id)} from ${oldParentId == null ? "the top level (or a parent you cannot see)" : label(oldParentId)} to ${label(newParent?.id ?? null)}.`,
|
|
65373
|
+
oldParentId == null ? "Shares from a parent you cannot see cannot be listed; the database deletes them with the move." : deletedShares.length === 0 ? `No shares from ${label(oldParentId)} into it to delete.` : `Will delete ${String(deletedShares.length)} share${deletedShares.length === 1 ? "" : "s"} from ${label(oldParentId)} into it: ${shared.map(
|
|
65374
|
+
({ share, resources }) => share.resourceId == null ? `all ${share.resourceKind}` : `${share.resourceKind} "${resources[0]?.name ?? share.resourceId}" (${share.resourceId})`
|
|
65375
|
+
).join("; ")}.`
|
|
65376
|
+
];
|
|
65377
|
+
const warnings = [];
|
|
65378
|
+
if (newParent != null && subtree.has(newParent.id.toLowerCase())) {
|
|
65379
|
+
warnings.push(
|
|
65380
|
+
`${label(newParent.id)} is inside ${label(moved.id)}; the database will refuse this move.`
|
|
65381
|
+
);
|
|
65382
|
+
}
|
|
65383
|
+
const movedById = new Map(movedUsers.map((user) => [user.id, user]));
|
|
65384
|
+
const parentById = new Map(parentUsers.map((user) => [user.id, user]));
|
|
65385
|
+
const access = [
|
|
65386
|
+
...movedUsers,
|
|
65387
|
+
...parentUsers.filter((user) => !movedById.has(user.id))
|
|
65388
|
+
].flatMap((user) => {
|
|
65389
|
+
const before = movedById.get(user.id)?.role ?? null;
|
|
65390
|
+
const after = strongerRole(
|
|
65391
|
+
movedById.get(user.id)?.directRole ?? null,
|
|
65392
|
+
parentById.get(user.id)?.role ?? null
|
|
65393
|
+
);
|
|
65394
|
+
if (before === after) return [];
|
|
65395
|
+
if (after == null)
|
|
65396
|
+
return [`${userLabel(user)} loses ${before ?? "access"}`];
|
|
65397
|
+
if (before == null) return [`${userLabel(user)} gains ${after}`];
|
|
65398
|
+
return roleRank(after) > roleRank(before) ? [`${userLabel(user)} drops to ${after} from ${before}`] : [`${userLabel(user)} rises to ${after} from ${before}`];
|
|
65399
|
+
});
|
|
65400
|
+
if (access.length > 0) {
|
|
65401
|
+
warnings.push(
|
|
65402
|
+
`Access on ${label(moved.id)} (from its direct and inherited roles; descendants with their own grants may differ):`,
|
|
65403
|
+
...access.map((line) => ` ${line}`)
|
|
65404
|
+
);
|
|
65405
|
+
}
|
|
65406
|
+
const sharedIds = shared.flatMap(
|
|
65407
|
+
({ share, resources }) => resources.map((resource) => ({ ...resource, kind: share.resourceKind }))
|
|
65408
|
+
);
|
|
65409
|
+
const sharedTotal = shared.reduce((sum2, { total }) => sum2 + total, 0);
|
|
65410
|
+
const references = await client.resourceReferences(
|
|
65411
|
+
sharedIds.slice(0, SHARED_RESOURCE_CAP).map((resource) => resource.id),
|
|
65412
|
+
{ referencerWorkspaceIds: subtreeStoredIds.slice(0, 500) }
|
|
65413
|
+
).catch((error62) => {
|
|
65414
|
+
warnings.push(
|
|
65415
|
+
`Could not check references: ${error62 instanceof Error ? error62.message : String(error62)}`
|
|
65416
|
+
);
|
|
65417
|
+
return null;
|
|
65418
|
+
});
|
|
65419
|
+
const sharedById = new Map(
|
|
65420
|
+
sharedIds.map((resource) => [resource.id.toLowerCase(), resource])
|
|
65421
|
+
);
|
|
65422
|
+
const brokenReferences = (references?.inbound ?? []).flatMap((ref) => {
|
|
65423
|
+
const resource = sharedById.get(ref.resourceId.toLowerCase());
|
|
65424
|
+
return resource != null && subtree.has(ref.referencerWorkspaceId.toLowerCase()) ? [
|
|
65425
|
+
`${ref.referencerKind} "${ref.referencerName}" (${ref.referencerId}) in ${label(ref.referencerWorkspaceId)} references ${resource.kind} "${resource.name}" (${resource.id}), shared by a share this move deletes`
|
|
65426
|
+
] : [];
|
|
65427
|
+
});
|
|
65428
|
+
if (brokenReferences.length > 0) {
|
|
65429
|
+
warnings.push(
|
|
65430
|
+
"May stop resolving (deployed content found by id; another share path may still reach it):",
|
|
65431
|
+
...brokenReferences.map((line) => ` ${line}`)
|
|
65432
|
+
);
|
|
65433
|
+
}
|
|
65434
|
+
if (sharedTotal > SHARED_RESOURCE_CAP) {
|
|
65435
|
+
warnings.push(
|
|
65436
|
+
`Checked references for the first ${String(SHARED_RESOURCE_CAP)} of ${String(sharedTotal)} shared resources.`
|
|
65437
|
+
);
|
|
65438
|
+
}
|
|
65439
|
+
printReport(args, {
|
|
65440
|
+
plan,
|
|
65441
|
+
warnings: warnings.length === 0 ? [] : ["WARN", ...warnings],
|
|
65442
|
+
dryRun
|
|
65443
|
+
});
|
|
65444
|
+
if (dryRun) return;
|
|
65445
|
+
const didMove = newParent == null ? await client.workspace(moved.id).moveToRoot() : await client.workspace(moved.id).setParent(newParent.id).then(() => true);
|
|
65446
|
+
(flagValue(args, "-o", "--output") === "json" ? process.stderr : process.stdout).write(
|
|
65447
|
+
didMove ? `Moved ${label(moved.id)}.
|
|
65448
|
+
` : `${label(moved.id)} was already at the top level, or its parent is not visible to you; nothing changed.
|
|
65449
|
+
`
|
|
65450
|
+
);
|
|
65451
|
+
};
|
|
65452
|
+
var moveResource = async (args) => {
|
|
65453
|
+
const [id] = positionals(args, ["--to", "-o", "--output"]);
|
|
65454
|
+
const to = flagValue(args, "--to");
|
|
65455
|
+
if (id == null || to == null) {
|
|
65456
|
+
throw new Error(
|
|
65457
|
+
"Usage: overai resource move <id> --to <workspaceId> [--dry-run]"
|
|
65458
|
+
);
|
|
65459
|
+
}
|
|
65460
|
+
const dryRun = args.includes("--dry-run");
|
|
65461
|
+
const client = cliClient();
|
|
65462
|
+
const row = await client.resource(id).show();
|
|
65463
|
+
const kind = idTableByPrefix(row.id);
|
|
65464
|
+
const fromId = typeof row.workspaceId === "string" ? row.workspaceId : null;
|
|
65465
|
+
if (kind == null || kind === "workspace" || fromId == null) {
|
|
65466
|
+
throw new Error(
|
|
65467
|
+
`${id} cannot be moved; use overai workspace move for a workspace.`
|
|
65468
|
+
);
|
|
65469
|
+
}
|
|
65470
|
+
const [forest, allShares, membership] = await Promise.all([
|
|
65471
|
+
client.workspaces.tree({ includeArchived: true }),
|
|
65472
|
+
client.workspaces.shares(),
|
|
65473
|
+
client.resourceGroups.membershipOf(row.id)
|
|
65474
|
+
]);
|
|
65475
|
+
const byId = workspacesById(forest);
|
|
65476
|
+
const label = (workspaceId) => {
|
|
65477
|
+
const node2 = byId.get(workspaceId.toLowerCase());
|
|
65478
|
+
return node2 == null ? workspaceId : `"${node2.name}" (${node2.id})`;
|
|
65479
|
+
};
|
|
65480
|
+
const destination = byId.get(to.toLowerCase());
|
|
65481
|
+
if (destination == null) {
|
|
65482
|
+
throw new Error(`Workspace ${to} not found (or not visible to you).`);
|
|
65483
|
+
}
|
|
65484
|
+
const subject = `${kind} "${rowName(row)}" (${row.id})`;
|
|
65485
|
+
if (destination.id.toLowerCase() === fromId.toLowerCase()) {
|
|
65486
|
+
(flagValue(args, "-o", "--output") === "json" ? process.stderr : process.stdout).write(`${subject} is already in ${label(fromId)}; nothing to move.
|
|
65487
|
+
`);
|
|
65488
|
+
return;
|
|
65489
|
+
}
|
|
65490
|
+
const ownShares = allShares.filter(
|
|
65491
|
+
(share) => share.resourceKind === kind && share.resourceId?.toLowerCase() === row.id.toLowerCase()
|
|
65492
|
+
);
|
|
65493
|
+
const plan = [
|
|
65494
|
+
`Moving ${subject} from ${label(fromId)} to ${label(destination.id)}.`,
|
|
65495
|
+
membership == null ? "It is in no resource group." : `Will remove it from group "${membership.groupName ?? membership.groupId}" (${membership.groupId}); a group holds only its own workspace's resources.`,
|
|
65496
|
+
ownShares.length === 0 ? "No shares name it." : `Will delete ${String(ownShares.length)} share${ownShares.length === 1 ? "" : "s"} naming it: ${ownShares.map(
|
|
65497
|
+
(share) => `${label(share.fromWorkspaceId)} \u2192 ${label(share.toWorkspaceId)}`
|
|
65498
|
+
).join("; ")}.`
|
|
65499
|
+
];
|
|
65500
|
+
const warnings = [];
|
|
65501
|
+
const failed = (what) => (error62) => {
|
|
65502
|
+
warnings.push(
|
|
65503
|
+
`Could not check ${what}: ${error62 instanceof Error ? error62.message : String(error62)}`
|
|
65504
|
+
);
|
|
65505
|
+
return null;
|
|
65506
|
+
};
|
|
65507
|
+
const [references, reach] = await Promise.all([
|
|
65508
|
+
client.resource(row.id).references().catch(failed("references")),
|
|
65509
|
+
kind === "agent" ? client.agentToolReach([row.id], destination.id).catch(failed("agent tool reach")) : null
|
|
65510
|
+
]);
|
|
65511
|
+
const sharesAfter = allShares.filter((share) => !ownShares.includes(share));
|
|
65512
|
+
const lostReach = [
|
|
65513
|
+
...(references?.inbound ?? []).flatMap(
|
|
65514
|
+
(ref) => reaches(allShares, fromId, ref.referencerWorkspaceId, kind, row.id) && !reaches(
|
|
65515
|
+
sharesAfter,
|
|
65516
|
+
destination.id,
|
|
65517
|
+
ref.referencerWorkspaceId,
|
|
65518
|
+
kind,
|
|
65519
|
+
row.id
|
|
65520
|
+
) ? [
|
|
65521
|
+
`${ref.referencerKind} "${ref.referencerName}" (${ref.referencerId}) in ${label(ref.referencerWorkspaceId)} will no longer reach ${subject}`
|
|
65522
|
+
] : []
|
|
65523
|
+
),
|
|
65524
|
+
...(references?.outbound ?? []).flatMap(
|
|
65525
|
+
(ref) => reaches(
|
|
65526
|
+
allShares,
|
|
65527
|
+
ref.targetWorkspaceId,
|
|
65528
|
+
fromId,
|
|
65529
|
+
ref.targetKind,
|
|
65530
|
+
ref.targetId
|
|
65531
|
+
) && !reaches(
|
|
65532
|
+
allShares,
|
|
65533
|
+
ref.targetWorkspaceId,
|
|
65534
|
+
destination.id,
|
|
65535
|
+
ref.targetKind,
|
|
65536
|
+
ref.targetId
|
|
65537
|
+
) ? [
|
|
65538
|
+
`${subject} will no longer reach ${ref.targetKind} "${ref.targetName}" (${ref.targetId}) in ${label(ref.targetWorkspaceId)}`
|
|
65539
|
+
] : []
|
|
65540
|
+
)
|
|
65541
|
+
];
|
|
65542
|
+
if (lostReach.length > 0) {
|
|
65543
|
+
warnings.push(
|
|
65544
|
+
"References by id in deployed content (heuristic: same workspace, or a chain of shares of that kind):",
|
|
65545
|
+
...lostReach.map((line) => ` ${line}`)
|
|
65546
|
+
);
|
|
65547
|
+
}
|
|
65548
|
+
const tools2 = (reach ?? []).flatMap((agent) => [
|
|
65549
|
+
...agent.tools.filter(
|
|
65550
|
+
(tool) => tool.isReachable && tool.isReachableFromTarget === false
|
|
65551
|
+
).map(
|
|
65552
|
+
(tool) => `${subject} will lose tool ${tool.kind} "${tool.name}" (${tool.id})`
|
|
65553
|
+
),
|
|
65554
|
+
...agent.hiddenLostAtTargetCount > 0 ? [
|
|
65555
|
+
`${subject} will lose ${String(agent.hiddenLostAtTargetCount)} tool${agent.hiddenLostAtTargetCount === 1 ? "" : "s"} you cannot see`
|
|
65556
|
+
] : []
|
|
65557
|
+
]);
|
|
65558
|
+
if (tools2.length > 0) {
|
|
65559
|
+
warnings.push(
|
|
65560
|
+
"Agent tools (from the server):",
|
|
65561
|
+
...tools2.map((line) => ` ${line}`)
|
|
65562
|
+
);
|
|
65563
|
+
}
|
|
65564
|
+
printReport(args, {
|
|
65565
|
+
plan,
|
|
65566
|
+
warnings: warnings.length === 0 ? [] : ["WARN", ...warnings],
|
|
65567
|
+
dryRun
|
|
65568
|
+
});
|
|
65569
|
+
if (dryRun) return;
|
|
65570
|
+
const result = await client.resource(row.id).move(destination.id);
|
|
65571
|
+
(flagValue(args, "-o", "--output") === "json" ? process.stderr : process.stdout).write(
|
|
65572
|
+
`Moved ${subject} to ${label(result.workspaceId)}${result.leftGroup == null ? "" : `; it left group "${result.leftGroup.groupName ?? result.leftGroup.groupId}"`}.
|
|
65573
|
+
`
|
|
65574
|
+
);
|
|
65575
|
+
};
|
|
65576
|
+
|
|
64703
65577
|
// src/commands/resource.ts
|
|
65578
|
+
var GROUP_USAGE = `Usage:
|
|
65579
|
+
overai resource group list [--workspace <id>]
|
|
65580
|
+
overai resource group create --workspace <id> --name <name>
|
|
65581
|
+
overai resource group rename <groupId> --name <name>
|
|
65582
|
+
overai resource group delete <groupId>
|
|
65583
|
+
overai resource group add <groupId> <resourceId>...
|
|
65584
|
+
overai resource group remove <resourceId>...
|
|
65585
|
+
`;
|
|
65586
|
+
var runGroup = async (args) => {
|
|
65587
|
+
const [operation, ...rest] = args;
|
|
65588
|
+
const ids = positionals(rest, ["--workspace", "--name", "-o", "--output"]);
|
|
65589
|
+
const name2 = flagValue(rest, "--name");
|
|
65590
|
+
const client = cliClient();
|
|
65591
|
+
if (operation === "list") {
|
|
65592
|
+
const workspaceId = flagValue(rest, "--workspace");
|
|
65593
|
+
printResult(
|
|
65594
|
+
(await client.resourceGroups.list({ workspaceId })).map((group) => ({
|
|
65595
|
+
id: group.id,
|
|
65596
|
+
name: group.name,
|
|
65597
|
+
workspaceId: group.workspaceId,
|
|
65598
|
+
resources: group.members.map((member) => member.resourceId).join(" ")
|
|
65599
|
+
})),
|
|
65600
|
+
resolveFormat(flagValue(rest, "-o", "--output"))
|
|
65601
|
+
);
|
|
65602
|
+
return;
|
|
65603
|
+
}
|
|
65604
|
+
if (operation === "create" && name2 != null) {
|
|
65605
|
+
const workspaceId = flagValue(rest, "--workspace") ?? openClone().manifest.workspaceId;
|
|
65606
|
+
const { id } = await client.resourceGroups.create({ workspaceId, name: name2 });
|
|
65607
|
+
process.stdout.write(
|
|
65608
|
+
`Created group "${name2}" (${id}) in ${workspaceId}.
|
|
65609
|
+
`
|
|
65610
|
+
);
|
|
65611
|
+
return;
|
|
65612
|
+
}
|
|
65613
|
+
const [groupId, ...resourceIds] = ids;
|
|
65614
|
+
if (operation === "rename" && groupId != null && name2 != null) {
|
|
65615
|
+
await client.resourceGroup(groupId).rename(name2);
|
|
65616
|
+
process.stdout.write(`Renamed group ${groupId} to "${name2}".
|
|
65617
|
+
`);
|
|
65618
|
+
return;
|
|
65619
|
+
}
|
|
65620
|
+
if (operation === "delete" && groupId != null) {
|
|
65621
|
+
await client.resourceGroup(groupId).delete();
|
|
65622
|
+
process.stdout.write(
|
|
65623
|
+
`Deleted group ${groupId}; its resources stay in the workspace.
|
|
65624
|
+
`
|
|
65625
|
+
);
|
|
65626
|
+
return;
|
|
65627
|
+
}
|
|
65628
|
+
if (operation === "add" && groupId != null && resourceIds.length > 0) {
|
|
65629
|
+
const previous = await client.resourceGroup(groupId).add(resourceIds);
|
|
65630
|
+
resourceIds.forEach((resourceId, index) => {
|
|
65631
|
+
const from = previous[index];
|
|
65632
|
+
process.stdout.write(
|
|
65633
|
+
`Added ${resourceId} to group ${groupId}${from == null || from.groupId === groupId ? "" : ` (left group "${from.groupName ?? from.groupId}")`}.
|
|
65634
|
+
`
|
|
65635
|
+
);
|
|
65636
|
+
});
|
|
65637
|
+
return;
|
|
65638
|
+
}
|
|
65639
|
+
if (operation === "remove" && ids.length > 0) {
|
|
65640
|
+
for (const resourceId of ids) {
|
|
65641
|
+
const membership = await client.resourceGroups.removeMember(resourceId);
|
|
65642
|
+
process.stdout.write(
|
|
65643
|
+
membership == null ? `${resourceId} is in no group.
|
|
65644
|
+
` : `Removed ${resourceId} from group "${membership.groupName ?? membership.groupId}".
|
|
65645
|
+
`
|
|
65646
|
+
);
|
|
65647
|
+
}
|
|
65648
|
+
return;
|
|
65649
|
+
}
|
|
65650
|
+
throw new Error(GROUP_USAGE.trimEnd());
|
|
65651
|
+
};
|
|
64704
65652
|
var runResource = async (args) => {
|
|
64705
65653
|
const [operation, id] = args;
|
|
65654
|
+
if (operation === "move") {
|
|
65655
|
+
await moveResource(args.slice(1));
|
|
65656
|
+
return;
|
|
65657
|
+
}
|
|
65658
|
+
if (operation === "group") {
|
|
65659
|
+
await runGroup(args.slice(1));
|
|
65660
|
+
return;
|
|
65661
|
+
}
|
|
64706
65662
|
if (operation !== "show" && operation !== "update" || id == null) {
|
|
64707
65663
|
throw new Error(
|
|
64708
|
-
|
|
65664
|
+
`Usage: overai resource show <id> | resource update <id> [--name <name>] [--description <text>] [--archive|--restore] [--enable|--disable] [--active|--inactive] | resource move <id> --to <workspaceId> [--dry-run]
|
|
65665
|
+
${GROUP_USAGE}`
|
|
64709
65666
|
);
|
|
64710
65667
|
}
|
|
64711
65668
|
const resource = resourceTableFor(id);
|
|
@@ -66377,6 +67334,10 @@ var webPagesDoc = {
|
|
|
66377
67334
|
body: `
|
|
66378
67335
|
Saves reject a stale editing base without discarding your draft. Incorporate the latest saved changes before retrying; never retry with a newer base unless those changes have been reconciled. A save conflict does not deploy anything.
|
|
66379
67336
|
|
|
67337
|
+
## Platform shortcuts
|
|
67338
|
+
|
|
67339
|
+
In React pages (v1 and v2), Cmd/Ctrl+K toggles the command palette and Cmd/Ctrl+I toggles the Architect when the host provides them, including while typing in inputs. These combinations are reserved for OverAI; use other keys for page actions. Other keys stay inside the page. Pressing inside a page dismisses outside host dropdowns without cancelling the page interaction. Nested third-party iframes do not forward these events.
|
|
67340
|
+
|
|
66380
67341
|
## Available Global Variables and Hooks
|
|
66381
67342
|
|
|
66382
67343
|
\`\`\`typescript
|
|
@@ -66798,6 +67759,8 @@ Resources (functions, tablespaces, integrations, agents, action runners, librari
|
|
|
66798
67759
|
|
|
66799
67760
|
To share a resource, go to the Workspace Overview page, and then click "Resource sharing" (Managers only) in the top bar.
|
|
66800
67761
|
|
|
67762
|
+
Moves clear sharing. Reparenting a workspace deletes the shares its old parent made into it, and moving a resource to another workspace deletes the shares that name it specifically and takes it out of its resource group. Re-share what the new location needs.
|
|
67763
|
+
|
|
66801
67764
|
Resources shared into a workspace appear in its Workspace Overview resource table alongside its own, each marked "Shared from <parent workspace>" ("Shared from another workspace" when the viewer can't see the parent), and the "Shared" filter chip narrows the table to them. They are read-only there: no action menu, no activity stats. A shared resource's name links to its page only when the viewer holds a builder role in the workspace that owns it; otherwise the row is listed but not clickable. A shared library is the exception: it always opens, read-only, viewed from the child workspace. To change or unshare it, a manager of the parent workspace uses "Resource sharing" there.
|
|
66802
67765
|
|
|
66803
67766
|
An agent's tools (functions, tablespaces, sub-agents, knowledge bases) resolve from the agent's own workspace, never the caller's. Sharing an agent therefore lets the recipient use its tools through it without those tools being shared. A library's own imports work the same way: sharing a library brings what it imports along. Moving an agent to a workspace that can't reach a tool silently drops that tool at runtime; the agent page header shows "N tools unavailable" when this has happened. Fix it by sharing the tool into the agent's workspace or moving the tool, not by detaching it.
|
|
@@ -67445,10 +68408,99 @@ var listWorkspaceUsers = async (args) => {
|
|
|
67445
68408
|
resolveFormat(flagValue(args, "-o", "--output"))
|
|
67446
68409
|
);
|
|
67447
68410
|
};
|
|
68411
|
+
var printTree = async (args) => {
|
|
68412
|
+
const [workspaceId] = positionals(args, ["-o", "--output"]);
|
|
68413
|
+
const includeArchived = args.includes("--archived");
|
|
68414
|
+
const client = cliClient();
|
|
68415
|
+
const roots = workspaceId == null ? await client.workspaces.tree({ includeArchived }) : [await client.workspace(workspaceId).tree({ includeArchived })];
|
|
68416
|
+
if (resolveFormat(flagValue(args, "-o", "--output")) !== "table") {
|
|
68417
|
+
printResult(roots, "json");
|
|
68418
|
+
return;
|
|
68419
|
+
}
|
|
68420
|
+
const lines = (node2, depth) => [
|
|
68421
|
+
`${" ".repeat(depth)}${node2.name} ${node2.id}${node2.role == null ? "" : ` ${node2.role}`}${node2.isArchived ? " archived" : ""}`,
|
|
68422
|
+
...node2.children.flatMap((child) => lines(child, depth + 1))
|
|
68423
|
+
];
|
|
68424
|
+
process.stdout.write(
|
|
68425
|
+
`${roots.flatMap((root) => lines(root, 0)).join("\n") || "(no workspaces)"}
|
|
68426
|
+
`
|
|
68427
|
+
);
|
|
68428
|
+
};
|
|
68429
|
+
var listShares = async (args) => {
|
|
68430
|
+
const workspaceId = workspaceIdFrom(args);
|
|
68431
|
+
const client = cliClient();
|
|
68432
|
+
const shares = await client.workspace(workspaceId).shares();
|
|
68433
|
+
const names = new Map(
|
|
68434
|
+
await Promise.all(
|
|
68435
|
+
shares.flatMap(
|
|
68436
|
+
(share) => share.resourceId == null ? [] : [
|
|
68437
|
+
client.resource(share.resourceId).show().then(
|
|
68438
|
+
(row) => [
|
|
68439
|
+
share.resourceId,
|
|
68440
|
+
typeof row.name === "string" ? row.name : ""
|
|
68441
|
+
],
|
|
68442
|
+
() => [share.resourceId, ""]
|
|
68443
|
+
)
|
|
68444
|
+
]
|
|
68445
|
+
)
|
|
68446
|
+
)
|
|
68447
|
+
);
|
|
68448
|
+
printResult(
|
|
68449
|
+
shares.map((share) => ({
|
|
68450
|
+
from: `${share.fromWorkspaceName ?? ""} (${share.fromWorkspaceId})`,
|
|
68451
|
+
to: `${share.toWorkspaceName ?? ""} (${share.toWorkspaceId})`,
|
|
68452
|
+
kind: share.resourceKind,
|
|
68453
|
+
resource: share.resourceId == null ? `all ${share.resourceKind}` : `${names.get(share.resourceId) ?? ""} (${share.resourceId})`
|
|
68454
|
+
})),
|
|
68455
|
+
resolveFormat(flagValue(args, "-o", "--output"))
|
|
68456
|
+
);
|
|
68457
|
+
};
|
|
68458
|
+
var shareResource = async (args) => {
|
|
68459
|
+
const [fromId] = positionals(args, [
|
|
68460
|
+
"--to",
|
|
68461
|
+
"--kind",
|
|
68462
|
+
"--resource",
|
|
68463
|
+
"-o",
|
|
68464
|
+
"--output"
|
|
68465
|
+
]);
|
|
68466
|
+
const to = flagValue(args, "--to");
|
|
68467
|
+
const kind = flagValue(args, "--kind");
|
|
68468
|
+
if (fromId == null || to == null || kind == null) {
|
|
68469
|
+
throw new Error(
|
|
68470
|
+
"Usage: overai workspace share <fromWorkspaceId> --to <childWorkspaceId> --kind <kind> [--resource <id>] [--remove]"
|
|
68471
|
+
);
|
|
68472
|
+
}
|
|
68473
|
+
const shareKind = SHARE_KINDS.find((known) => known === kind);
|
|
68474
|
+
if (shareKind == null) {
|
|
68475
|
+
throw new Error(
|
|
68476
|
+
`Unknown share kind "${kind}". Use one of: ${SHARE_KINDS.join(", ")}.`
|
|
68477
|
+
);
|
|
68478
|
+
}
|
|
68479
|
+
const client = cliClient();
|
|
68480
|
+
const typedResourceId = flagValue(args, "--resource");
|
|
68481
|
+
const resourceId = typedResourceId == null ? null : (await client.resource(typedResourceId).show()).id;
|
|
68482
|
+
const what = resourceId == null ? `all ${shareKind}` : `${shareKind} ${resourceId}`;
|
|
68483
|
+
const input2 = { toWorkspaceId: to, kind: shareKind, resourceId };
|
|
68484
|
+
if (args.includes("--remove")) {
|
|
68485
|
+
await client.workspace(fromId).unshare(input2);
|
|
68486
|
+
process.stdout.write(
|
|
68487
|
+
`Stopped sharing ${what} from ${fromId} into ${to}.
|
|
68488
|
+
`
|
|
68489
|
+
);
|
|
68490
|
+
return;
|
|
68491
|
+
}
|
|
68492
|
+
await client.workspace(fromId).share(input2);
|
|
68493
|
+
process.stdout.write(`Shared ${what} from ${fromId} into ${to}.
|
|
68494
|
+
`);
|
|
68495
|
+
};
|
|
67448
68496
|
var USAGE5 = `Usage:
|
|
67449
68497
|
overai workspace list [--archived] [--limit <n>]
|
|
67450
68498
|
overai workspace show [workspaceId]
|
|
67451
68499
|
overai workspace users [workspaceId]
|
|
68500
|
+
overai workspace tree [workspaceId] [--archived]
|
|
68501
|
+
overai workspace move <workspaceId> --to <parentWorkspaceId|root> [--dry-run]
|
|
68502
|
+
overai workspace shares [workspaceId]
|
|
68503
|
+
overai workspace share <fromWorkspaceId> --to <childWorkspaceId> --kind <${SHARE_KINDS.join("|")}> [--resource <id>] [--remove]
|
|
67452
68504
|
`;
|
|
67453
68505
|
var runWorkspace = async (args) => {
|
|
67454
68506
|
if (args[0] === "list") {
|
|
@@ -67463,6 +68515,22 @@ var runWorkspace = async (args) => {
|
|
|
67463
68515
|
await listWorkspaceUsers(args.slice(1));
|
|
67464
68516
|
return;
|
|
67465
68517
|
}
|
|
68518
|
+
if (args[0] === "tree") {
|
|
68519
|
+
await printTree(args.slice(1));
|
|
68520
|
+
return;
|
|
68521
|
+
}
|
|
68522
|
+
if (args[0] === "move") {
|
|
68523
|
+
await moveWorkspace(args.slice(1));
|
|
68524
|
+
return;
|
|
68525
|
+
}
|
|
68526
|
+
if (args[0] === "shares") {
|
|
68527
|
+
await listShares(args.slice(1));
|
|
68528
|
+
return;
|
|
68529
|
+
}
|
|
68530
|
+
if (args[0] === "share") {
|
|
68531
|
+
await shareResource(args.slice(1));
|
|
68532
|
+
return;
|
|
68533
|
+
}
|
|
67466
68534
|
process.stderr.write(USAGE5);
|
|
67467
68535
|
process.exitCode = 1;
|
|
67468
68536
|
};
|
|
@@ -67566,10 +68634,33 @@ Usage:
|
|
|
67566
68634
|
overai workspace show [workspaceId] Show a workspace's name and overview
|
|
67567
68635
|
overai workspace users [workspaceId] List users and effective/direct roles
|
|
67568
68636
|
(workspaceId defaults from a clone)
|
|
68637
|
+
overai workspace tree [workspaceId] [--archived]
|
|
68638
|
+
Print the workspace hierarchy; no id
|
|
68639
|
+
prints every top-level workspace
|
|
68640
|
+
overai workspace move <workspaceId> --to <parentId|root> [--dry-run]
|
|
68641
|
+
Reparent a workspace; prints the shares
|
|
68642
|
+
it loses and who gains or loses access
|
|
68643
|
+
overai workspace shares [workspaceId] List shares from and into a workspace
|
|
68644
|
+
overai workspace share <fromWorkspaceId> --to <childWorkspaceId> --kind <kind> [--resource <id>] [--remove]
|
|
68645
|
+
Share a kind (table_space, function,
|
|
68646
|
+
agent, integration, action_runner), or
|
|
68647
|
+
one resource, into a direct child
|
|
67569
68648
|
overai create <type> [--workspace <id>] [--name <name>]
|
|
67570
68649
|
Create a complete, usable resource
|
|
67571
68650
|
overai resource show <id> Show metadata for any resource
|
|
67572
68651
|
overai resource update <id> [...] Edit metadata, state, or archive status
|
|
68652
|
+
overai resource move <id> --to <workspaceId> [--dry-run]
|
|
68653
|
+
Move a resource to another workspace;
|
|
68654
|
+
prints the group and shares it loses and
|
|
68655
|
+
references that may stop resolving
|
|
68656
|
+
overai resource group list [--workspace <id>]
|
|
68657
|
+
overai resource group create --workspace <id> --name <name>
|
|
68658
|
+
overai resource group rename <groupId> --name <name>
|
|
68659
|
+
overai resource group delete <groupId>
|
|
68660
|
+
overai resource group add <groupId> <resourceId>...
|
|
68661
|
+
overai resource group remove <resourceId>...
|
|
68662
|
+
Side-navigation groups: flat, one per
|
|
68663
|
+
resource, same workspace
|
|
67573
68664
|
overai graphql -q '<query>' | -f <file> [--variables <json>] [--v1]
|
|
67574
68665
|
Run a GraphQL operation (/v2; --v1 = legacy Hasura)
|
|
67575
68666
|
overai fn <functionId> [--method GET] [--path /features/123] [--input k=v ... | -]
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@overaihq/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Create, edit, deploy, and run OverAI workspace resources from the command line",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://overai.com",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=24.22.
|
|
8
|
+
"node": ">=24.22.1"
|
|
9
9
|
},
|
|
10
10
|
"bin": {
|
|
11
11
|
"overai": "./dist/index.js"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"access": "public"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@overaihq/sdk": "0.
|
|
23
|
+
"@overaihq/sdk": "0.5.1",
|
|
24
24
|
"@perygee/common": "0.0.0",
|
|
25
25
|
"@types/node": "^24.19.2",
|
|
26
26
|
"@types/proper-lockfile": "^4.1.4",
|