Skip to content

Commit e04a9d8

Browse files
committed
cleanup tools
1 parent 2a32d4c commit e04a9d8

11 files changed

Lines changed: 155 additions & 351 deletions

File tree

api/lib/admin.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,54 @@ export function getConfig(ctx?: AppContext) {
4141
apiKey,
4242
};
4343
}
44+
45+
// ─── JWT / env helpers ────────────────────────────────────────────────────────
46+
47+
export function decodeJwtPayload(
48+
token: string,
49+
): Record<string, unknown> | null {
50+
try {
51+
const payloadB64 = token.split(".")[1];
52+
if (!payloadB64) return null;
53+
const json = atob(payloadB64.replace(/-/g, "+").replace(/_/g, "/"));
54+
return JSON.parse(json) as Record<string, unknown>;
55+
} catch {
56+
return null;
57+
}
58+
}
59+
60+
export async function getUserEnvName(apiKey: string): Promise<string> {
61+
const payload = decodeJwtPayload(apiKey);
62+
const userId =
63+
(payload?.user as Record<string, unknown> | undefined)?.id ??
64+
payload?.sub ??
65+
apiKey;
66+
const encoder = new TextEncoder();
67+
const data = encoder.encode(String(userId));
68+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
69+
const hashArray = Array.from(new Uint8Array(hashBuffer));
70+
const hashHex = hashArray
71+
.map((b) => b.toString(16).padStart(2, "0"))
72+
.join("");
73+
return `${hashHex.slice(0, 9)}`;
74+
}
75+
76+
// Mirror ENVIRONMENTS.consistentHash from admin/sdk/environments.ts
77+
export function consistentHash(input: string): string {
78+
let hash = 0;
79+
for (let i = 0; i < input.length; i++) {
80+
hash = (hash << 5) - hash + input.charCodeAt(i);
81+
hash = hash & hash;
82+
}
83+
return Math.abs(hash).toString(36);
84+
}
85+
86+
export function buildEnvUrl(site: string, env: string): string {
87+
return `https://envs-${site}--${consistentHash(env)}.decocdn.com`;
88+
}
89+
90+
export async function resolveEnv(ctx?: AppContext): Promise<string> {
91+
const env = getEnv(ctx);
92+
const token = env.MESH_REQUEST_CONTEXT?.token;
93+
return getUserEnvName(token);
94+
}

api/tools/assets.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ export const deleteAssetTool = createTool({
256256
"Permanently delete a media asset by its ID from the configured deco.cx site. This is irreversible — the file is removed from storage and the database index.",
257257
inputSchema: deleteAssetInputSchema,
258258
outputSchema: deleteAssetOutputSchema,
259+
_meta: { ui: { visibility: ["app"] } },
259260
annotations: {
260261
readOnlyHint: false,
261262
destructiveHint: true,

api/tools/commit-summary.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createTool } from "@decocms/runtime/tools";
22
import { z } from "zod";
3-
import { callAdmin, getConfig } from "../lib/admin.ts";
3+
import { callAdmin, getConfig, resolveEnv } from "../lib/admin.ts";
44
import type { GitStatus } from "./git.ts";
55

66
const daemonDiffSchema = z.object({
@@ -10,9 +10,7 @@ const daemonDiffSchema = z.object({
1010

1111
// ─── schemas ──────────────────────────────────────────────────────────────────
1212

13-
export const suggestCommitMessageInputSchema = z.object({
14-
env: z.string().describe("Environment name to generate suggestions for"),
15-
});
13+
export const suggestCommitMessageInputSchema = z.object({});
1614
export type SuggestCommitMessageInput = z.infer<
1715
typeof suggestCommitMessageInputSchema
1816
>;
@@ -235,12 +233,13 @@ export const suggestCommitMessageTool = createTool({
235233
idempotentHint: false,
236234
openWorldHint: false,
237235
},
238-
execute: async ({ context }, ctx) => {
236+
execute: async (_input, ctx) => {
239237
const { site, apiKey } = getConfig(ctx);
238+
const env = await resolveEnv(ctx);
240239

241240
const status = (await callAdmin(
242241
"deco-sites/admin/loaders/releases/git/status.ts",
243-
{ site, env: context.env },
242+
{ site, env },
244243
apiKey,
245244
)) as GitStatus;
246245

@@ -265,12 +264,7 @@ export const suggestCommitMessageTool = createTool({
265264
}
266265

267266
// Fetch actual diff content for richer AI context
268-
const diffSummary = await fetchDiffSummary(
269-
site,
270-
context.env,
271-
apiKey,
272-
changedFiles,
273-
);
267+
const diffSummary = await fetchDiffSummary(site, env, apiKey, changedFiles);
274268

275269
const filesSummary = [
276270
...status.modified.map((f) => `Modified: ${f}`),

api/tools/environments.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const listEnvironmentsTool = createTool({
4242
"List all sandbox environments (platform=sandbox) for the configured deco.cx site. Returns each environment's name, URL, branch/commit, and metadata.",
4343
inputSchema: listEnvironmentsInputSchema,
4444
outputSchema: listEnvironmentsOutputSchema,
45+
_meta: { ui: { visibility: ["app"] } },
4546
annotations: {
4647
readOnlyHint: true,
4748
destructiveHint: false,
@@ -154,6 +155,7 @@ export const createEnvironmentTool = createTool({
154155
"Create a new environment for the configured deco.cx site. Provisions a Kubernetes deployment and returns the environment URL once ready (takes 1–3 minutes for deco platform).",
155156
inputSchema: createEnvironmentInputSchema,
156157
outputSchema: createEnvironmentOutputSchema,
158+
_meta: { ui: { visibility: ["app"] } },
157159
annotations: {
158160
readOnlyHint: false,
159161
destructiveHint: false,
@@ -211,6 +213,7 @@ export const deleteEnvironmentTool = createTool({
211213
"Permanently delete a sandbox environment by name. This is irreversible — the environment and all associated resources will be removed.",
212214
inputSchema: deleteEnvironmentInputSchema,
213215
outputSchema: deleteEnvironmentOutputSchema,
216+
_meta: { ui: { visibility: ["app"] } },
214217
annotations: {
215218
readOnlyHint: false,
216219
destructiveHint: true,
@@ -273,6 +276,7 @@ export const previewEnvironmentTool = createTool({
273276
"Get a live preview URL for a specific path in an environment. Includes a cache-busting parameter so the latest version is always served.",
274277
inputSchema: previewEnvironmentInputSchema,
275278
outputSchema: previewEnvironmentOutputSchema,
279+
_meta: { ui: { visibility: ["app"] } },
276280
annotations: {
277281
readOnlyHint: true,
278282
destructiveHint: false,

0 commit comments

Comments
 (0)