@skillsmith/mcp-server 0.4.10 → 0.4.12
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/CHANGELOG.md +8 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/__tests__/tool-dispatch.envelope.test.d.ts +12 -0
- package/dist/src/__tests__/tool-dispatch.envelope.test.d.ts.map +1 -0
- package/dist/src/__tests__/tool-dispatch.envelope.test.js +205 -0
- package/dist/src/__tests__/tool-dispatch.envelope.test.js.map +1 -0
- package/dist/src/index.js +10 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/middleware/license.d.ts +6 -6
- package/dist/src/middleware/license.d.ts.map +1 -1
- package/dist/src/middleware/license.js +11 -8
- package/dist/src/middleware/license.js.map +1 -1
- package/dist/src/tool-dispatch.d.ts.map +1 -1
- package/dist/src/tool-dispatch.js +58 -19
- package/dist/src/tool-dispatch.js.map +1 -1
- package/dist/src/tools/audit-tools.d.ts +6 -6
- package/dist/src/tools/install.d.ts +9 -3
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.js +52 -11
- package/dist/src/tools/install.js.map +1 -1
- package/dist/src/tools/install.test.d.ts +17 -0
- package/dist/src/tools/install.test.d.ts.map +1 -0
- package/dist/src/tools/install.test.js +237 -0
- package/dist/src/tools/install.test.js.map +1 -0
- package/dist/src/tools/integration-tools.d.ts +8 -8
- package/dist/src/tools/rbac-tools.d.ts +4 -4
- package/dist/src/tools/recommend.types.d.ts +3 -3
- package/dist/src/tools/registry-tools.d.ts +2 -2
- package/dist/src/tools/registry-tools.d.ts.map +1 -1
- package/dist/src/tools/registry-tools.js +42 -4
- package/dist/src/tools/registry-tools.js.map +1 -1
- package/dist/src/tools/skill-diff.d.ts +2 -2
- package/dist/src/tools/sso-tools.d.ts +2 -2
- package/dist/src/tools/suggest.d.ts +4 -4
- package/dist/src/tools/team-resolver.d.ts +29 -0
- package/dist/src/tools/team-resolver.d.ts.map +1 -0
- package/dist/src/tools/team-resolver.js +46 -0
- package/dist/src/tools/team-resolver.js.map +1 -0
- package/dist/src/tools/team-resolver.test.d.ts +6 -0
- package/dist/src/tools/team-resolver.test.d.ts.map +1 -0
- package/dist/src/tools/team-resolver.test.js +73 -0
- package/dist/src/tools/team-resolver.test.js.map +1 -0
- package/dist/src/tools/team-workspace.d.ts +18 -4
- package/dist/src/tools/team-workspace.d.ts.map +1 -1
- package/dist/src/tools/team-workspace.js +149 -75
- package/dist/src/tools/team-workspace.js.map +1 -1
- package/dist/src/tools/team-workspace.live.d.ts +34 -0
- package/dist/src/tools/team-workspace.live.d.ts.map +1 -0
- package/dist/src/tools/team-workspace.live.js +182 -0
- package/dist/src/tools/team-workspace.live.js.map +1 -0
- package/dist/src/tools/team-workspace.live.test.d.ts +10 -0
- package/dist/src/tools/team-workspace.live.test.d.ts.map +1 -0
- package/dist/src/tools/team-workspace.live.test.js +177 -0
- package/dist/src/tools/team-workspace.live.test.js.map +1 -0
- package/dist/src/tools/team-workspace.stub.d.ts.map +1 -1
- package/dist/src/tools/team-workspace.stub.js +3 -1
- package/dist/src/tools/team-workspace.stub.js.map +1 -1
- package/dist/src/tools/team-workspace.test.d.ts +1 -0
- package/dist/src/tools/team-workspace.test.d.ts.map +1 -1
- package/dist/src/tools/team-workspace.test.js +43 -1
- package/dist/src/tools/team-workspace.test.js.map +1 -1
- package/dist/src/tools/uninstall.d.ts +1 -1
- package/dist/src/validation.d.ts +64 -0
- package/dist/src/validation.d.ts.map +1 -0
- package/dist/src/validation.js +73 -0
- package/dist/src/validation.js.map +1 -0
- package/dist/src/validation.test.d.ts +6 -0
- package/dist/src/validation.test.d.ts.map +1 -0
- package/dist/src/validation.test.js +102 -0
- package/dist/src/validation.test.js.map +1 -0
- package/package.json +2 -2
- package/server.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-workspace.js","sourceRoot":"","sources":["../../../src/tools/team-workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"team-workspace.js","sourceRoot":"","sources":["../../../src/tools/team-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Live Supabase-backed TeamWorkspaceService
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/team-workspace.live
|
|
4
|
+
* @see SMI-4292: Wave 5A — drops stub fallback when Supabase is configured.
|
|
5
|
+
* @see SMI-4312: Use service-role client for CRUD post license-key resolution.
|
|
6
|
+
*
|
|
7
|
+
* Uses the Supabase service-role client for all CRUD against
|
|
8
|
+
* `team_workspaces` and `workspace_skills`. Rationale: migration 071 RLS
|
|
9
|
+
* gates tenant access on `authenticated` role + `auth.uid()`, which the
|
|
10
|
+
* MCP subprocess does not carry (no user JWT, no browser cookie). The
|
|
11
|
+
* anon client can't satisfy those policies; service-role bypasses them.
|
|
12
|
+
* Tenant isolation is enforced in-query via explicit `team_id` filters on
|
|
13
|
+
* every request, plus a team-scoped workspace-existence check before any
|
|
14
|
+
* `workspace_skills` operation. See ADR-116.
|
|
15
|
+
*
|
|
16
|
+
* License-key → team_id resolution still uses the anon client + RPC
|
|
17
|
+
* (`resolve_team_from_license` is SECURITY DEFINER — see team-resolver.ts).
|
|
18
|
+
*
|
|
19
|
+
* All rows are returned in camelCase (Workspace shape); Supabase snake_case
|
|
20
|
+
* columns are mapped at the boundary so handlers stay schema-agnostic.
|
|
21
|
+
*/
|
|
22
|
+
import type { TeamWorkspaceService } from './team-workspace.js';
|
|
23
|
+
/**
|
|
24
|
+
* Create a live Supabase-backed TeamWorkspaceService.
|
|
25
|
+
* Call signals and teamId arguments from the handler are honoured; the
|
|
26
|
+
* service does NOT re-resolve team_id internally.
|
|
27
|
+
*
|
|
28
|
+
* Every DB call explicitly filters by `team_id = <resolved>` (for
|
|
29
|
+
* `team_workspaces`) or asserts workspace membership (for
|
|
30
|
+
* `workspace_skills`). Service-role bypasses RLS — tenant isolation
|
|
31
|
+
* lives here, not in the database.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createLiveService(): TeamWorkspaceService;
|
|
34
|
+
//# sourceMappingURL=team-workspace.live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-workspace.live.d.ts","sourceRoot":"","sources":["../../../src/tools/team-workspace.live.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,qBAAqB,CAAA;AA8G5B;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,IAAI,oBAAoB,CAgGxD"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Live Supabase-backed TeamWorkspaceService
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/team-workspace.live
|
|
4
|
+
* @see SMI-4292: Wave 5A — drops stub fallback when Supabase is configured.
|
|
5
|
+
* @see SMI-4312: Use service-role client for CRUD post license-key resolution.
|
|
6
|
+
*
|
|
7
|
+
* Uses the Supabase service-role client for all CRUD against
|
|
8
|
+
* `team_workspaces` and `workspace_skills`. Rationale: migration 071 RLS
|
|
9
|
+
* gates tenant access on `authenticated` role + `auth.uid()`, which the
|
|
10
|
+
* MCP subprocess does not carry (no user JWT, no browser cookie). The
|
|
11
|
+
* anon client can't satisfy those policies; service-role bypasses them.
|
|
12
|
+
* Tenant isolation is enforced in-query via explicit `team_id` filters on
|
|
13
|
+
* every request, plus a team-scoped workspace-existence check before any
|
|
14
|
+
* `workspace_skills` operation. See ADR-116.
|
|
15
|
+
*
|
|
16
|
+
* License-key → team_id resolution still uses the anon client + RPC
|
|
17
|
+
* (`resolve_team_from_license` is SECURITY DEFINER — see team-resolver.ts).
|
|
18
|
+
*
|
|
19
|
+
* All rows are returned in camelCase (Workspace shape); Supabase snake_case
|
|
20
|
+
* columns are mapped at the boundary so handlers stay schema-agnostic.
|
|
21
|
+
*/
|
|
22
|
+
import { getSupabaseAdminClient } from '../supabase-client.js';
|
|
23
|
+
import { resolveLicenseTeamId } from './team-resolver.js';
|
|
24
|
+
function mapWorkspace(row) {
|
|
25
|
+
return {
|
|
26
|
+
id: row.id,
|
|
27
|
+
name: row.name,
|
|
28
|
+
description: row.description,
|
|
29
|
+
teamId: row.team_id,
|
|
30
|
+
settings: row.settings ?? {},
|
|
31
|
+
createdAt: row.created_at,
|
|
32
|
+
updatedAt: row.updated_at,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function mapSharedSkill(row) {
|
|
36
|
+
return {
|
|
37
|
+
skillId: row.skill_id,
|
|
38
|
+
addedBy: row.added_by ?? 'unknown',
|
|
39
|
+
addedAt: row.added_at,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get the Supabase service-role client. Throws a typed error if
|
|
44
|
+
* `SUPABASE_SERVICE_ROLE_KEY` is not configured on the MCP host —
|
|
45
|
+
* handlers surface this to the caller instead of leaking a 42501.
|
|
46
|
+
*/
|
|
47
|
+
async function getClient() {
|
|
48
|
+
try {
|
|
49
|
+
return (await getSupabaseAdminClient());
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
const message = err instanceof Error ? err.message : 'unknown error';
|
|
53
|
+
throw new Error(`Team workspace operations require SUPABASE_SERVICE_ROLE_KEY on the MCP host: ${message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Fetch a workspace by (teamId, workspaceId) and verify tenant scope.
|
|
58
|
+
* Returns null on miss or if the workspace belongs to a different team.
|
|
59
|
+
* Shared helper so sibling methods don't depend on a correctly-bound `this`.
|
|
60
|
+
*/
|
|
61
|
+
async function fetchTeamScopedWorkspace(client, teamId, workspaceId) {
|
|
62
|
+
const resp = await client
|
|
63
|
+
.from('team_workspaces')
|
|
64
|
+
.select()
|
|
65
|
+
.eq('id', workspaceId)
|
|
66
|
+
.eq('team_id', teamId)
|
|
67
|
+
.single();
|
|
68
|
+
if (resp.error || !resp.data)
|
|
69
|
+
return null;
|
|
70
|
+
return mapWorkspace(resp.data);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Assert the workspace exists AND belongs to the resolved `teamId`.
|
|
74
|
+
* Required before every `workspace_skills` CRUD because service-role
|
|
75
|
+
* bypasses RLS — the DB no longer cross-checks membership for us.
|
|
76
|
+
*/
|
|
77
|
+
async function assertWorkspaceInTeam(client, teamId, workspaceId) {
|
|
78
|
+
const workspace = await fetchTeamScopedWorkspace(client, teamId, workspaceId);
|
|
79
|
+
if (!workspace) {
|
|
80
|
+
throw new Error(`Workspace ${workspaceId} not found in team ${teamId}.`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a live Supabase-backed TeamWorkspaceService.
|
|
85
|
+
* Call signals and teamId arguments from the handler are honoured; the
|
|
86
|
+
* service does NOT re-resolve team_id internally.
|
|
87
|
+
*
|
|
88
|
+
* Every DB call explicitly filters by `team_id = <resolved>` (for
|
|
89
|
+
* `team_workspaces`) or asserts workspace membership (for
|
|
90
|
+
* `workspace_skills`). Service-role bypasses RLS — tenant isolation
|
|
91
|
+
* lives here, not in the database.
|
|
92
|
+
*/
|
|
93
|
+
export function createLiveService() {
|
|
94
|
+
return {
|
|
95
|
+
async resolveTeamId(licenseKey) {
|
|
96
|
+
const teamId = await resolveLicenseTeamId(licenseKey);
|
|
97
|
+
if (!teamId) {
|
|
98
|
+
throw new Error('Unable to resolve team from license key. Ensure SKILLSMITH_LICENSE_KEY is set and corresponds to an active Team-tier subscription.');
|
|
99
|
+
}
|
|
100
|
+
return teamId;
|
|
101
|
+
},
|
|
102
|
+
async createWorkspace(teamId, name, description) {
|
|
103
|
+
const client = await getClient();
|
|
104
|
+
const resp = await client
|
|
105
|
+
.from('team_workspaces')
|
|
106
|
+
.insert({ team_id: teamId, name, description: description ?? null })
|
|
107
|
+
.select()
|
|
108
|
+
.single();
|
|
109
|
+
if (resp.error || !resp.data) {
|
|
110
|
+
throw new Error(`Failed to create workspace: ${resp.error?.message ?? 'unknown error'}`);
|
|
111
|
+
}
|
|
112
|
+
return mapWorkspace(resp.data);
|
|
113
|
+
},
|
|
114
|
+
async listWorkspaces(teamId) {
|
|
115
|
+
const client = await getClient();
|
|
116
|
+
const resp = await client.from('team_workspaces').select().eq('team_id', teamId);
|
|
117
|
+
if (resp.error) {
|
|
118
|
+
throw new Error(`Failed to list workspaces: ${resp.error.message ?? 'unknown error'}`);
|
|
119
|
+
}
|
|
120
|
+
return (resp.data ?? []).map(mapWorkspace);
|
|
121
|
+
},
|
|
122
|
+
async getWorkspace(teamId, workspaceId) {
|
|
123
|
+
const client = await getClient();
|
|
124
|
+
return fetchTeamScopedWorkspace(client, teamId, workspaceId);
|
|
125
|
+
},
|
|
126
|
+
async deleteWorkspace(teamId, workspaceId) {
|
|
127
|
+
const client = await getClient();
|
|
128
|
+
const resp = await client
|
|
129
|
+
.from('team_workspaces')
|
|
130
|
+
.delete()
|
|
131
|
+
.eq('id', workspaceId)
|
|
132
|
+
.eq('team_id', teamId);
|
|
133
|
+
if (resp.error)
|
|
134
|
+
return false;
|
|
135
|
+
// PostgREST returns affected rows in `data` when `returning=representation` (default)
|
|
136
|
+
return Array.isArray(resp.data) ? resp.data.length > 0 : true;
|
|
137
|
+
},
|
|
138
|
+
async addSkill(teamId, workspaceId, skillId) {
|
|
139
|
+
const client = await getClient();
|
|
140
|
+
await assertWorkspaceInTeam(client, teamId, workspaceId);
|
|
141
|
+
const resp = await client
|
|
142
|
+
.from('workspace_skills')
|
|
143
|
+
.insert({ workspace_id: workspaceId, skill_id: skillId })
|
|
144
|
+
.select()
|
|
145
|
+
.single();
|
|
146
|
+
if (resp.error || !resp.data) {
|
|
147
|
+
throw new Error(`Failed to add skill: ${resp.error?.message ?? 'unknown error'}`);
|
|
148
|
+
}
|
|
149
|
+
return mapSharedSkill(resp.data);
|
|
150
|
+
},
|
|
151
|
+
async removeSkill(teamId, workspaceId, skillId) {
|
|
152
|
+
const client = await getClient();
|
|
153
|
+
await assertWorkspaceInTeam(client, teamId, workspaceId);
|
|
154
|
+
const resp = await client
|
|
155
|
+
.from('workspace_skills')
|
|
156
|
+
.delete()
|
|
157
|
+
.eq('workspace_id', workspaceId)
|
|
158
|
+
.eq('skill_id', skillId);
|
|
159
|
+
if (resp.error)
|
|
160
|
+
return false;
|
|
161
|
+
return Array.isArray(resp.data) ? resp.data.length > 0 : true;
|
|
162
|
+
},
|
|
163
|
+
async listSkills(teamId, workspaceId) {
|
|
164
|
+
const client = await getClient();
|
|
165
|
+
await assertWorkspaceInTeam(client, teamId, workspaceId);
|
|
166
|
+
const resp = await client
|
|
167
|
+
.from('workspace_skills')
|
|
168
|
+
.select()
|
|
169
|
+
.eq('workspace_id', workspaceId);
|
|
170
|
+
if (resp.error) {
|
|
171
|
+
throw new Error(`Failed to list skills: ${resp.error.message ?? 'unknown error'}`);
|
|
172
|
+
}
|
|
173
|
+
return (resp.data ?? []).map(mapSharedSkill);
|
|
174
|
+
},
|
|
175
|
+
async getWorkspaceSettings(teamId, workspaceId) {
|
|
176
|
+
const client = await getClient();
|
|
177
|
+
const ws = await fetchTeamScopedWorkspace(client, teamId, workspaceId);
|
|
178
|
+
return ws?.settings ?? {};
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=team-workspace.live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-workspace.live.js","sourceRoot":"","sources":["../../../src/tools/team-workspace.live.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AA4CzD,SAAS,YAAY,CAAC,GAAiB;IACrC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAA;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAsB;IAC5C,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,OAAO,EAAE,GAAG,CAAC,QAAQ,IAAI,SAAS;QAClC,OAAO,EAAE,GAAG,CAAC,QAAQ;KACtB,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAA0B,CAAA;IAClE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAA;QACpE,MAAM,IAAI,KAAK,CACb,gFAAgF,OAAO,EAAE,CAC1F,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,wBAAwB,CACrC,MAA6B,EAC7B,MAAc,EACd,WAAmB;IAEnB,MAAM,IAAI,GAAG,MAAM,MAAM;SACtB,IAAI,CAAe,iBAAiB,CAAC;SACrC,MAAM,EAAE;SACR,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC;SACrB,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;SACrB,MAAM,EAAE,CAAA;IACX,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,qBAAqB,CAClC,MAA6B,EAC7B,MAAc,EACd,WAAmB;IAEnB,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;IAC7E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,aAAa,WAAW,sBAAsB,MAAM,GAAG,CAAC,CAAA;IAC1E,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,UAAkB;YACpC,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAA;YACrD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,oIAAoI,CACrI,CAAA;YACH,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW;YAC7C,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,IAAI,GAAG,MAAM,MAAM;iBACtB,IAAI,CAAe,iBAAiB,CAAC;iBACrC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC;iBACnE,MAAM,EAAE;iBACR,MAAM,EAAE,CAAA;YACX,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAA;YAC1F,CAAC;YACD,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChC,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,MAAM;YACzB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAe,iBAAiB,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YAC9F,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAA;YACxF,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAC5C,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW;YACpC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,OAAO,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;QAC9D,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,WAAW;YACvC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,IAAI,GAAG,MAAM,MAAM;iBACtB,IAAI,CAAe,iBAAiB,CAAC;iBACrC,MAAM,EAAE;iBACR,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC;iBACrB,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YACxB,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAA;YAC5B,sFAAsF;YACtF,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC/D,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO;YACzC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;YACxD,MAAM,IAAI,GAAG,MAAM,MAAM;iBACtB,IAAI,CAAoB,kBAAkB,CAAC;iBAC3C,MAAM,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBACxD,MAAM,EAAE;iBACR,MAAM,EAAE,CAAA;YACX,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAA;YACnF,CAAC;YACD,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO;YAC5C,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;YACxD,MAAM,IAAI,GAAG,MAAM,MAAM;iBACtB,IAAI,CAAoB,kBAAkB,CAAC;iBAC3C,MAAM,EAAE;iBACR,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC;iBAC/B,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YAC1B,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAA;YAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC/D,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW;YAClC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;YACxD,MAAM,IAAI,GAAG,MAAM,MAAM;iBACtB,IAAI,CAAoB,kBAAkB,CAAC;iBAC3C,MAAM,EAAE;iBACR,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;YAClC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAA;YACpF,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAC9C,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,MAAM,EAAE,WAAW;YAC5C,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,EAAE,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;YACtE,OAAO,EAAE,EAAE,QAAQ,IAAI,EAAE,CAAA;QAC3B,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Live-mode tests for team_workspace + share_skill MCP tools
|
|
3
|
+
* @see SMI-4312: service-role client post-resolution + cross-team hardening
|
|
4
|
+
*
|
|
5
|
+
* Kept in a sidecar so team-workspace.test.ts stays under the 500-line CI limit.
|
|
6
|
+
* Exercises the live Supabase-backed service by mocking `getSupabaseAdminClient`
|
|
7
|
+
* with a recording fake client.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=team-workspace.live.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-workspace.live.test.d.ts","sourceRoot":"","sources":["../../../src/tools/team-workspace.live.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Live-mode tests for team_workspace + share_skill MCP tools
|
|
3
|
+
* @see SMI-4312: service-role client post-resolution + cross-team hardening
|
|
4
|
+
*
|
|
5
|
+
* Kept in a sidecar so team-workspace.test.ts stays under the 500-line CI limit.
|
|
6
|
+
* Exercises the live Supabase-backed service by mocking `getSupabaseAdminClient`
|
|
7
|
+
* with a recording fake client.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
10
|
+
// Live service and handlers: imported AFTER the vi.mock block below so that
|
|
11
|
+
// the module under test sees the mocked supabase-client exports.
|
|
12
|
+
import { executeTeamWorkspace, executeShareSkill, setTeamWorkspaceService, createStubService, } from './team-workspace.js';
|
|
13
|
+
import { createLiveService } from './team-workspace.live.js';
|
|
14
|
+
vi.mock('../supabase-client.js', () => ({
|
|
15
|
+
isSupabaseConfigured: vi.fn(() => true),
|
|
16
|
+
getSupabaseClient: vi.fn(),
|
|
17
|
+
getSupabaseAdminClient: vi.fn(),
|
|
18
|
+
resetSupabaseClients: vi.fn(),
|
|
19
|
+
}));
|
|
20
|
+
vi.mock('./team-resolver.js', () => ({
|
|
21
|
+
readLicenseKey: vi.fn(() => 'sk_test_fake_license'),
|
|
22
|
+
resolveLicenseTeamId: vi.fn(async () => 'team-alpha'),
|
|
23
|
+
}));
|
|
24
|
+
function createFakeClient(opts = {}) {
|
|
25
|
+
const calls = [];
|
|
26
|
+
function makeQuery(table, op) {
|
|
27
|
+
const record = { table, op, filters: [] };
|
|
28
|
+
calls.push(record);
|
|
29
|
+
const chain = {
|
|
30
|
+
select: () => chain,
|
|
31
|
+
eq: (column, value) => {
|
|
32
|
+
record.filters.push({ column, value });
|
|
33
|
+
return chain;
|
|
34
|
+
},
|
|
35
|
+
insert: (row) => {
|
|
36
|
+
record.op = 'insert';
|
|
37
|
+
record.payload = row;
|
|
38
|
+
return chain;
|
|
39
|
+
},
|
|
40
|
+
delete: () => {
|
|
41
|
+
record.op = 'delete';
|
|
42
|
+
return chain;
|
|
43
|
+
},
|
|
44
|
+
single: async () => {
|
|
45
|
+
return (opts.singleResponder?.() ?? {
|
|
46
|
+
data: null,
|
|
47
|
+
error: null,
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
then: (onFulfilled) => {
|
|
51
|
+
const resp = opts.thenResponder?.() ?? { data: [], error: null };
|
|
52
|
+
return Promise.resolve(onFulfilled(resp));
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
return chain;
|
|
56
|
+
}
|
|
57
|
+
const client = {
|
|
58
|
+
from: (table) => makeQuery(table, 'select'),
|
|
59
|
+
};
|
|
60
|
+
return { client, calls };
|
|
61
|
+
}
|
|
62
|
+
function makeContext() {
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Shared setup
|
|
67
|
+
// ============================================================================
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
// Install the live service so handlers hit the mocked admin client.
|
|
70
|
+
setTeamWorkspaceService(createLiveService());
|
|
71
|
+
});
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
// Restore stub so unrelated tests start clean if the file grows.
|
|
74
|
+
setTeamWorkspaceService(createStubService());
|
|
75
|
+
vi.clearAllMocks();
|
|
76
|
+
});
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Tests — admin client is used post license resolution
|
|
79
|
+
// ============================================================================
|
|
80
|
+
describe('team-workspace live mode — SMI-4312', () => {
|
|
81
|
+
it('listWorkspaces calls the admin (service-role) client with team_id filter', async () => {
|
|
82
|
+
const { client, calls } = createFakeClient({
|
|
83
|
+
thenResponder: () => ({ data: [], error: null }),
|
|
84
|
+
});
|
|
85
|
+
const { getSupabaseAdminClient, getSupabaseClient } = await import('../supabase-client.js');
|
|
86
|
+
vi.mocked(getSupabaseAdminClient).mockResolvedValue(client);
|
|
87
|
+
const result = await executeTeamWorkspace({ action: 'list' }, makeContext());
|
|
88
|
+
expect(result.success).toBe(true);
|
|
89
|
+
expect(result.dataSource).toBe('live');
|
|
90
|
+
expect(getSupabaseAdminClient).toHaveBeenCalled();
|
|
91
|
+
// The anon-key client must NOT be used for CRUD in live mode.
|
|
92
|
+
expect(getSupabaseClient).not.toHaveBeenCalled();
|
|
93
|
+
// team_id filter must be applied on the query.
|
|
94
|
+
const q = calls.find((c) => c.table === 'team_workspaces');
|
|
95
|
+
expect(q).toBeDefined();
|
|
96
|
+
expect(q.filters.some((f) => f.column === 'team_id' && f.value === 'team-alpha')).toBe(true);
|
|
97
|
+
});
|
|
98
|
+
it('createWorkspace inserts with team_id from the resolved license', async () => {
|
|
99
|
+
const { client, calls } = createFakeClient({
|
|
100
|
+
singleResponder: () => ({
|
|
101
|
+
data: {
|
|
102
|
+
id: 'ws-new',
|
|
103
|
+
team_id: 'team-alpha',
|
|
104
|
+
name: 'New WS',
|
|
105
|
+
description: null,
|
|
106
|
+
settings: null,
|
|
107
|
+
created_by: null,
|
|
108
|
+
created_at: '2026-04-19T00:00:00Z',
|
|
109
|
+
updated_at: '2026-04-19T00:00:00Z',
|
|
110
|
+
},
|
|
111
|
+
error: null,
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
const { getSupabaseAdminClient } = await import('../supabase-client.js');
|
|
115
|
+
vi.mocked(getSupabaseAdminClient).mockResolvedValue(client);
|
|
116
|
+
const result = await executeTeamWorkspace({ action: 'create', name: 'New WS' }, makeContext());
|
|
117
|
+
expect(result.success).toBe(true);
|
|
118
|
+
expect(result.workspace?.teamId).toBe('team-alpha');
|
|
119
|
+
const insertCall = calls.find((c) => c.op === 'insert');
|
|
120
|
+
expect(insertCall).toBeDefined();
|
|
121
|
+
expect(insertCall.payload?.team_id).toBe('team-alpha');
|
|
122
|
+
});
|
|
123
|
+
it('surfaces a typed error when SUPABASE_SERVICE_ROLE_KEY is not configured', async () => {
|
|
124
|
+
const { getSupabaseAdminClient } = await import('../supabase-client.js');
|
|
125
|
+
vi.mocked(getSupabaseAdminClient).mockRejectedValueOnce(new Error('Supabase admin not configured: SUPABASE_SERVICE_ROLE_KEY required'));
|
|
126
|
+
const result = await executeTeamWorkspace({ action: 'list' }, makeContext());
|
|
127
|
+
expect(result.success).toBe(false);
|
|
128
|
+
expect(result.dataSource).toBe('live');
|
|
129
|
+
expect(result.error).toMatch(/SUPABASE_SERVICE_ROLE_KEY/);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
// ============================================================================
|
|
133
|
+
// Tests — cross-team workspace access hardening
|
|
134
|
+
// ============================================================================
|
|
135
|
+
describe('share_skill live mode — cross-team hardening — SMI-4312', () => {
|
|
136
|
+
const foreignWorkspaceId = '00000000-0000-0000-0000-0000000000ff';
|
|
137
|
+
/**
|
|
138
|
+
* Fake that returns "no row" whenever the team_workspaces SELECT is
|
|
139
|
+
* team-scoped — i.e. the caller tried to access a workspace owned by
|
|
140
|
+
* a different team. This is the cross-team attack shape.
|
|
141
|
+
*/
|
|
142
|
+
function foreignWorkspaceFake() {
|
|
143
|
+
return createFakeClient({
|
|
144
|
+
singleResponder: () => ({
|
|
145
|
+
data: null,
|
|
146
|
+
error: { message: 'No rows found' },
|
|
147
|
+
}),
|
|
148
|
+
thenResponder: () => ({ data: [], error: null }),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
it('share_skill add rejects a workspaceId that does not belong to the resolved team', async () => {
|
|
152
|
+
const { client } = foreignWorkspaceFake();
|
|
153
|
+
const { getSupabaseAdminClient } = await import('../supabase-client.js');
|
|
154
|
+
vi.mocked(getSupabaseAdminClient).mockResolvedValue(client);
|
|
155
|
+
const result = await executeShareSkill({ action: 'add', workspaceId: foreignWorkspaceId, skillId: 'author/name' }, makeContext());
|
|
156
|
+
expect(result.success).toBe(false);
|
|
157
|
+
expect(result.dataSource).toBe('live');
|
|
158
|
+
expect(result.error).toMatch(/not found in team/i);
|
|
159
|
+
});
|
|
160
|
+
it('share_skill list rejects a cross-team workspaceId', async () => {
|
|
161
|
+
const { client } = foreignWorkspaceFake();
|
|
162
|
+
const { getSupabaseAdminClient } = await import('../supabase-client.js');
|
|
163
|
+
vi.mocked(getSupabaseAdminClient).mockResolvedValue(client);
|
|
164
|
+
const result = await executeShareSkill({ action: 'list', workspaceId: foreignWorkspaceId }, makeContext());
|
|
165
|
+
expect(result.success).toBe(false);
|
|
166
|
+
expect(result.error).toMatch(/not found in team/i);
|
|
167
|
+
});
|
|
168
|
+
it('share_skill remove rejects a cross-team workspaceId', async () => {
|
|
169
|
+
const { client } = foreignWorkspaceFake();
|
|
170
|
+
const { getSupabaseAdminClient } = await import('../supabase-client.js');
|
|
171
|
+
vi.mocked(getSupabaseAdminClient).mockResolvedValue(client);
|
|
172
|
+
const result = await executeShareSkill({ action: 'remove', workspaceId: foreignWorkspaceId, skillId: 'author/name' }, makeContext());
|
|
173
|
+
expect(result.success).toBe(false);
|
|
174
|
+
expect(result.error).toMatch(/not found in team/i);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
//# sourceMappingURL=team-workspace.live.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-workspace.live.test.js","sourceRoot":"","sources":["../../../src/tools/team-workspace.live.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGxE,4EAA4E;AAC5E,iEAAiE;AACjE,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5D,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,oBAAoB,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;IACvC,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC1B,sBAAsB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC/B,oBAAoB,EAAE,EAAE,CAAC,EAAE,EAAE;CAC9B,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC;IACnD,oBAAoB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC;CACtD,CAAC,CAAC,CAAA;AAqBH,SAAS,gBAAgB,CAAC,OAA0B,EAAE;IAIpD,MAAM,KAAK,GAAe,EAAE,CAAA;IAE5B,SAAS,SAAS,CAAC,KAAa,EAAE,EAAkC;QAClE,MAAM,MAAM,GAAa,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QACnD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClB,MAAM,KAAK,GAA4B;YACrC,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK;YACnB,EAAE,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE;gBACrC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;gBACtC,OAAO,KAAK,CAAA;YACd,CAAC;YACD,MAAM,EAAE,CAAC,GAA4B,EAAE,EAAE;gBACvC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAA;gBACpB,MAAM,CAAC,OAAO,GAAG,GAAG,CAAA;gBACpB,OAAO,KAAK,CAAA;YACd,CAAC;YACD,MAAM,EAAE,GAAG,EAAE;gBACX,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAA;gBACpB,OAAO,KAAK,CAAA;YACd,CAAC;YACD,MAAM,EAAE,KAAK,IAAI,EAAE;gBACjB,OAAO,CACL,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI;oBAC1B,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE,IAAI;iBACZ,CACF,CAAA;YACH,CAAC;YACD,IAAI,EAAE,CAAC,WAAuE,EAAE,EAAE;gBAChF,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;gBAChE,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;YAC3C,CAAC;SACF,CAAA;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC;KACpD,CAAA;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAC1B,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,EAA4B,CAAA;AACrC,CAAC;AAED,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E,UAAU,CAAC,GAAG,EAAE;IACd,oEAAoE;IACpE,uBAAuB,CAAC,iBAAiB,EAAE,CAAC,CAAA;AAC9C,CAAC,CAAC,CAAA;AAEF,SAAS,CAAC,GAAG,EAAE;IACb,iEAAiE;IACjE,uBAAuB,CAAC,iBAAiB,EAAE,CAAC,CAAA;IAC5C,EAAE,CAAC,aAAa,EAAE,CAAA;AACpB,CAAC,CAAC,CAAA;AAEF,+EAA+E;AAC/E,uDAAuD;AACvD,+EAA+E;AAE/E,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC;YACzC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SACjD,CAAC,CAAA;QACF,MAAM,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QAC3F,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;QAE5E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,CAAC,sBAAsB,CAAC,CAAC,gBAAgB,EAAE,CAAA;QACjD,8DAA8D;QAC9D,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAA;QAEhD,+CAA+C;QAC/C,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,iBAAiB,CAAC,CAAA;QAC1D,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACvB,MAAM,CAAC,CAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/F,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC;YACzC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtB,IAAI,EAAE;oBACJ,EAAE,EAAE,QAAQ;oBACZ,OAAO,EAAE,YAAY;oBACrB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,IAAI;oBACjB,QAAQ,EAAE,IAAI;oBACd,UAAU,EAAE,IAAI;oBAChB,UAAU,EAAE,sBAAsB;oBAClC,UAAU,EAAE,sBAAsB;iBACnC;gBACD,KAAK,EAAE,IAAI;aACZ,CAAC;SACH,CAAC,CAAA;QACF,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QACxE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;QAE9F,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAA;QACvD,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAA;QAChC,MAAM,CAAC,UAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QACxE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,qBAAqB,CACrD,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAC/E,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;QAE5E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,+EAA+E;AAC/E,gDAAgD;AAChD,+EAA+E;AAE/E,QAAQ,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACvE,MAAM,kBAAkB,GAAG,sCAAsC,CAAA;IAEjE;;;;OAIG;IACH,SAAS,oBAAoB;QAC3B,OAAO,gBAAgB,CAAC;YACtB,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtB,IAAI,EAAE,IAAI;gBACV,KAAK,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE;aACpC,CAAC;YACF,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SACjD,CAAC,CAAA;IACJ,CAAC;IAED,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAA;QACzC,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QACxE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,aAAa,EAAE,EAC1E,WAAW,EAAE,CACd,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAA;QACzC,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QACxE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,EACnD,WAAW,EAAE,CACd,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAA;QACzC,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QACxE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,aAAa,EAAE,EAC7E,WAAW,EAAE,CACd,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-workspace.stub.d.ts","sourceRoot":"","sources":["../../../src/tools/team-workspace.stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,qBAAqB,CAAA;AAM5B,qCAAqC;AACrC,wBAAgB,iBAAiB,IAAI,oBAAoB,
|
|
1
|
+
{"version":3,"file":"team-workspace.stub.d.ts","sourceRoot":"","sources":["../../../src/tools/team-workspace.stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,qBAAqB,CAAA;AAM5B,qCAAqC;AACrC,wBAAgB,iBAAiB,IAAI,oBAAoB,CAwExD"}
|
|
@@ -17,7 +17,9 @@ export function createStubService() {
|
|
|
17
17
|
const skills = new Map();
|
|
18
18
|
return {
|
|
19
19
|
async resolveTeamId(_licenseKey) {
|
|
20
|
-
//
|
|
20
|
+
// SMI-4292: Live resolution lives in team-workspace.live.ts via
|
|
21
|
+
// resolve_team_from_license RPC (migration 071). This stub returns a
|
|
22
|
+
// static team id for unit tests and unauthenticated environments.
|
|
21
23
|
return 'team_stub_00000000-0000-0000-0000-000000000000';
|
|
22
24
|
},
|
|
23
25
|
async createWorkspace(teamId, name, description) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-workspace.stub.js","sourceRoot":"","sources":["../../../src/tools/team-workspace.stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,qCAAqC;AACrC,MAAM,UAAU,iBAAiB;IAC/B,gCAAgC;IAChC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAA;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAA;IAE/C,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,WAAmB;YACrC,
|
|
1
|
+
{"version":3,"file":"team-workspace.stub.js","sourceRoot":"","sources":["../../../src/tools/team-workspace.stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,qCAAqC;AACrC,MAAM,UAAU,iBAAiB;IAC/B,gCAAgC;IAChC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAA;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAA;IAE/C,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,WAAmB;YACrC,gEAAgE;YAChE,qEAAqE;YACrE,kEAAkE;YAClE,OAAO,gDAAgD,CAAA;QACzD,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAc,EAAE,IAAY,EAAE,WAAoB;YACtE,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;YAC9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YACpC,MAAM,EAAE,GAAc;gBACpB,EAAE;gBACF,IAAI;gBACJ,WAAW,EAAE,WAAW,IAAI,IAAI;gBAChC,MAAM;gBACN,QAAQ,EAAE,EAAE;gBACZ,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,GAAG;aACf,CAAA;YACD,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YACtB,OAAO,EAAE,CAAA;QACX,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,MAAc;YACjC,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;QACtE,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,OAAe,EAAE,WAAmB;YACrD,OAAO,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAA;QAC5C,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,OAAe,EAAE,WAAmB;YACxD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YAC3C,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAC9B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAC1B,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,OAAe,EAAE,WAAmB,EAAE,OAAe;YAClE,MAAM,KAAK,GAAgB;gBACzB,OAAO;gBACP,OAAO,EAAE,cAAc;gBACvB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAClC,CAAA;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;YAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAChB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;YAC7B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,WAAmB,EAAE,OAAe;YACrE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAA;YAC1D,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;YACjC,OAAO,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACtC,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,WAAmB;YACnD,OAAO,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;QACtC,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,OAAe,EAAE,WAAmB;YAC7D,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACtC,OAAO,EAAE,EAAE,QAAQ,IAAI,EAAE,CAAA;QAC3B,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @fileoverview Unit tests for team_workspace and share_skill MCP tools
|
|
3
3
|
* @see SMI-3895: Team Workspace + Share Skill MCP Tools
|
|
4
4
|
* @see SMI-3898: Skill Sharing Controls
|
|
5
|
+
* @see SMI-4292: Wave 5A — live Supabase integration + typed error paths
|
|
5
6
|
*/
|
|
6
7
|
export {};
|
|
7
8
|
//# sourceMappingURL=team-workspace.test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-workspace.test.d.ts","sourceRoot":"","sources":["../../../src/tools/team-workspace.test.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"team-workspace.test.d.ts","sourceRoot":"","sources":["../../../src/tools/team-workspace.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
* @fileoverview Unit tests for team_workspace and share_skill MCP tools
|
|
3
3
|
* @see SMI-3895: Team Workspace + Share Skill MCP Tools
|
|
4
4
|
* @see SMI-3898: Skill Sharing Controls
|
|
5
|
+
* @see SMI-4292: Wave 5A — live Supabase integration + typed error paths
|
|
5
6
|
*/
|
|
6
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
7
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
7
8
|
import { teamWorkspaceInputSchema, shareSkillInputSchema, executeTeamWorkspace, executeShareSkill, createStubService, setTeamWorkspaceService, matchesPattern, checkSharingPolicy, } from './team-workspace.js';
|
|
9
|
+
// Mock isSupabaseConfigured so we can flip between 'stub' and 'live' modes
|
|
10
|
+
vi.mock('../supabase-client.js', () => ({
|
|
11
|
+
isSupabaseConfigured: vi.fn(() => false),
|
|
12
|
+
getSupabaseClient: vi.fn(),
|
|
13
|
+
getSupabaseAdminClient: vi.fn(),
|
|
14
|
+
resetSupabaseClients: vi.fn(),
|
|
15
|
+
}));
|
|
8
16
|
// ============================================================================
|
|
9
17
|
// Helpers
|
|
10
18
|
// ============================================================================
|
|
@@ -199,6 +207,23 @@ describe('executeTeamWorkspace', () => {
|
|
|
199
207
|
const result = await executeTeamWorkspace({ action: 'delete', workspaceId: '00000000-0000-0000-0000-000000000099' }, makeContext());
|
|
200
208
|
expect(result.success).toBe(false);
|
|
201
209
|
});
|
|
210
|
+
// SMI-4292: Typed error when Supabase live but license key missing
|
|
211
|
+
it('returns typed error in live mode when SKILLSMITH_LICENSE_KEY is missing', async () => {
|
|
212
|
+
const { isSupabaseConfigured } = await import('../supabase-client.js');
|
|
213
|
+
vi.mocked(isSupabaseConfigured).mockReturnValueOnce(true);
|
|
214
|
+
const orig = process.env.SKILLSMITH_LICENSE_KEY;
|
|
215
|
+
delete process.env.SKILLSMITH_LICENSE_KEY;
|
|
216
|
+
try {
|
|
217
|
+
const result = await executeTeamWorkspace({ action: 'list' }, makeContext());
|
|
218
|
+
expect(result.success).toBe(false);
|
|
219
|
+
expect(result.dataSource).toBe('live');
|
|
220
|
+
expect(result.error).toContain('SKILLSMITH_LICENSE_KEY');
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
if (orig !== undefined)
|
|
224
|
+
process.env.SKILLSMITH_LICENSE_KEY = orig;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
202
227
|
});
|
|
203
228
|
// ============================================================================
|
|
204
229
|
// executeShareSkill
|
|
@@ -240,6 +265,23 @@ describe('executeShareSkill', () => {
|
|
|
240
265
|
expect(result.success).toBe(false);
|
|
241
266
|
expect(result.error).toContain('not found');
|
|
242
267
|
});
|
|
268
|
+
// SMI-4292: Typed error when Supabase live but license key missing
|
|
269
|
+
it('returns typed error in live mode when SKILLSMITH_LICENSE_KEY is missing', async () => {
|
|
270
|
+
const { isSupabaseConfigured } = await import('../supabase-client.js');
|
|
271
|
+
vi.mocked(isSupabaseConfigured).mockReturnValueOnce(true);
|
|
272
|
+
const orig = process.env.SKILLSMITH_LICENSE_KEY;
|
|
273
|
+
delete process.env.SKILLSMITH_LICENSE_KEY;
|
|
274
|
+
try {
|
|
275
|
+
const result = await executeShareSkill({ action: 'list', workspaceId: wsId }, makeContext());
|
|
276
|
+
expect(result.success).toBe(false);
|
|
277
|
+
expect(result.dataSource).toBe('live');
|
|
278
|
+
expect(result.error).toContain('SKILLSMITH_LICENSE_KEY');
|
|
279
|
+
}
|
|
280
|
+
finally {
|
|
281
|
+
if (orig !== undefined)
|
|
282
|
+
process.env.SKILLSMITH_LICENSE_KEY = orig;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
243
285
|
// SMI-3898: Deny list enforcement
|
|
244
286
|
it('rejects skill matching deny list pattern', async () => {
|
|
245
287
|
// Create a service with deny list
|