Skip to content

Commit 244f3c8

Browse files
committed
refactor(workspaces): rename capability layer to operations
1 parent c2f0426 commit 244f3c8

24 files changed

Lines changed: 441 additions & 454 deletions

src/features/workspaces/ai/ai-thread-runtime.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { createAIThreadResearchTools } from "#/features/workspaces/ai/research-t
1919
import { createAIThreadTimeTools } from "#/features/workspaces/ai/time-tools";
2020
import { createAIThreadWebTools } from "#/features/workspaces/ai/web-tools";
2121
import { createAIThreadWorkspaceTools } from "#/features/workspaces/ai/workspace-tools";
22-
import { workspaceCapabilityToolDefinitions } from "#/features/workspaces/capabilities/workspace-capability-tools";
22+
import { workspaceToolDefinitions } from "#/features/workspaces/operations/workspace-tool-definitions";
2323
import { formatWorkspaceAiContextForPrompt } from "#/features/workspaces/model/workspace-ai-context";
2424

2525
const thinkPromptSectionDivider = "══════════════════════════════════════════════";
@@ -165,7 +165,7 @@ const AI_THREAD_TIME_TOOL_DESCRIPTORS: AIThreadToolDescriptor[] = [
165165
];
166166

167167
const AI_THREAD_WORKSPACE_TOOL_DESCRIPTORS: AIThreadToolDescriptor[] = [
168-
...workspaceCapabilityToolDefinitions.map(({ name, mutating }) => ({
168+
...workspaceToolDefinitions.map(({ name, mutating }) => ({
169169
name,
170170
codemode: true,
171171
mutating,

src/features/workspaces/ai/workspace-tools.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import { tool } from "ai";
33

44
import type { AIThreadContext } from "#/features/workspaces/ai/ai-thread-metadata";
55
import {
6-
workspaceCapabilityToolDefinitions,
7-
type WorkspaceCapabilityToolDefinition,
8-
} from "#/features/workspaces/capabilities/workspace-capability-tools";
6+
workspaceToolDefinitions,
7+
type WorkspaceToolDefinition,
8+
} from "#/features/workspaces/operations/workspace-tool-definitions";
99
import {
10-
createWorkspaceCapabilityContext,
11-
type WorkspaceCapabilityContext,
12-
type WorkspaceCapabilityScope,
13-
} from "#/features/workspaces/capabilities/workspace-capability-context";
10+
createWorkspaceAccessContext,
11+
type WorkspaceAccessContext,
12+
type WorkspaceAccessScope,
13+
} from "#/features/workspaces/operations/workspace-access-context";
1414

1515
type WorkspaceThreadToolConfig = {
16-
definition: WorkspaceCapabilityToolDefinition;
16+
definition: WorkspaceToolDefinition;
1717
getThreadContext: () => Promise<AIThreadContext | null>;
1818
};
1919

@@ -31,7 +31,7 @@ function createWorkspaceThreadTool(input: WorkspaceThreadToolConfig) {
3131

3232
return await definition.execute(
3333
args,
34-
createThreadWorkspaceCapabilityContext(thread, definition.scopes),
34+
createThreadWorkspaceAccessContext(thread, definition.scopes),
3535
);
3636
},
3737
});
@@ -41,7 +41,7 @@ export function createAIThreadWorkspaceTools(input: {
4141
getThreadContext: () => Promise<AIThreadContext | null>;
4242
}): ToolSet {
4343
return Object.fromEntries(
44-
workspaceCapabilityToolDefinitions.map((definition) => [
44+
workspaceToolDefinitions.map((definition) => [
4545
definition.name,
4646
createWorkspaceThreadTool({
4747
definition,
@@ -61,11 +61,11 @@ async function requireThreadContext(getThreadContext: () => Promise<AIThreadCont
6161
return thread;
6262
}
6363

64-
function createThreadWorkspaceCapabilityContext(
64+
function createThreadWorkspaceAccessContext(
6565
thread: AIThreadContext,
66-
scopes: readonly WorkspaceCapabilityScope[],
67-
): WorkspaceCapabilityContext {
68-
return createWorkspaceCapabilityContext({
66+
scopes: readonly WorkspaceAccessScope[],
67+
): WorkspaceAccessContext {
68+
return createWorkspaceAccessContext({
6969
scopes,
7070
userId: thread.userId,
7171
workspaceId: thread.workspaceId,

src/features/workspaces/capabilities/account-capability-context.ts

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/features/workspaces/capabilities/capability-context.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/features/workspaces/capabilities/list-items.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/features/workspaces/capabilities/read-pages.test.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/features/workspaces/capabilities/workspace-capability-context.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export interface AccessActor<TScope extends string> {
2+
scopes: ReadonlySet<TScope>;
3+
userId: string;
4+
}
5+
6+
export interface ScopedAccessContext<TScope extends string> {
7+
actor: AccessActor<TScope>;
8+
}
9+
10+
export class AccessScopeError<TScope extends string> extends Error {
11+
constructor(
12+
readonly domain: string,
13+
readonly scope: TScope,
14+
) {
15+
super(`Missing ${domain} access scope: ${scope}`);
16+
this.name = "AccessScopeError";
17+
}
18+
}
19+
20+
export function createAccessActor<TScope extends string>(input: {
21+
scopes: readonly TScope[];
22+
userId: string;
23+
}): AccessActor<TScope> {
24+
return {
25+
scopes: new Set(input.scopes),
26+
userId: input.userId,
27+
};
28+
}
29+
30+
export function assertAccessScope<TScope extends string>(
31+
context: ScopedAccessContext<TScope>,
32+
domain: string,
33+
scope: TScope,
34+
) {
35+
if (!context.actor.scopes.has(scope)) {
36+
throw new AccessScopeError(domain, scope);
37+
}
38+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {
2+
assertAccessScope,
3+
type AccessActor,
4+
createAccessActor,
5+
type ScopedAccessContext,
6+
} from "#/features/workspaces/operations/access-context";
7+
8+
export const accountAccessScopes = ["workspaces:read"] as const;
9+
10+
export type AccountAccessScope = (typeof accountAccessScopes)[number];
11+
12+
export type AccountAccessActor = AccessActor<AccountAccessScope>;
13+
14+
export type AccountAccessContext = ScopedAccessContext<AccountAccessScope>;
15+
16+
export function createAccountAccessContext(input: {
17+
scopes: readonly AccountAccessScope[];
18+
userId: string;
19+
}): AccountAccessContext {
20+
return {
21+
actor: createAccessActor(input),
22+
};
23+
}
24+
25+
export function assertAccountAccessScope(context: AccountAccessContext, scope: AccountAccessScope) {
26+
assertAccessScope(context, "account", scope);
27+
}

0 commit comments

Comments
 (0)