Show when each extension was last updated
MCP, skill and tool rows in Settings say "Updated 5m ago" beside how they're reached and who gets them. updated_at now means a change to an extension's settings (an edit, or any Access save): runs, connections and MCP syncs keep their own last_checked_at / last_synced_at and no longer touch it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -37,6 +37,7 @@ export default async function grabToolsOverview({ user_id }: Params): Promise<Cu
|
||||
status: tool.status,
|
||||
last_error: tool.last_error,
|
||||
last_checked_at: tool.last_checked_at,
|
||||
updated_at: tool.updated_at,
|
||||
access: { all_bots: tool.all_bots, ...access(tool.id) },
|
||||
...(targets.can_edit ? { parameters: tool.parameters, config: tool.config } : {}),
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@ export default function parseCustomToolRow({ row }: Params): CustomToolRecord {
|
||||
status: (row.status || "untested") as CustomToolStatus,
|
||||
last_error: row.last_error || "",
|
||||
last_checked_at: typeof row.last_checked_at == "number" ? row.last_checked_at : null,
|
||||
updated_at: typeof row.updated_at == "number" ? row.updated_at : null,
|
||||
kind: row.kind || "prompt",
|
||||
config: parseJsonColumn<Record<string, unknown>>({ text: row.config, fallback: {} }),
|
||||
} as CustomToolRecord;
|
||||
|
||||
@@ -29,5 +29,6 @@ export default function parseMcpServerRow({ row }: Params): McpServerRecord {
|
||||
status: (row.status || "untested") as McpServerStatus,
|
||||
last_error: row.last_error || "",
|
||||
last_synced_at: typeof row.last_synced_at == "number" ? row.last_synced_at : null,
|
||||
updated_at: typeof row.updated_at == "number" ? row.updated_at : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,5 +17,6 @@ export default function parseSkillRow({ row }: Params): SkillRecord {
|
||||
body: row.body || "",
|
||||
all_bots: row.all_bots == 1,
|
||||
enabled: row.enabled != 0,
|
||||
updated_at: typeof row.updated_at == "number" ? row.updated_at : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,13 +11,12 @@ type Params = {
|
||||
/**
|
||||
* Saves how a custom tool's run went (`status`, `last_error`,
|
||||
* `last_checked_at`), for its row in Settings, under Tools. Never throws:
|
||||
* a run doesn't fail over its bookkeeping.
|
||||
* a run doesn't fail over its bookkeeping. `updated_at` is left alone: it
|
||||
* says when the tool's settings last changed.
|
||||
*/
|
||||
export default async function recordCustomToolRun({ custom_tool_id, error }: Params) {
|
||||
const now = Date.now();
|
||||
|
||||
await BunSQLite.sql({
|
||||
sql: `UPDATE custom_tools SET status = ?, last_error = ?, last_checked_at = ?, updated_at = ? WHERE id = ?`,
|
||||
values: [error ? "error" : "ok", (error || "").slice(0, 4000), now, now, custom_tool_id],
|
||||
sql: `UPDATE custom_tools SET status = ?, last_error = ?, last_checked_at = ? WHERE id = ?`,
|
||||
values: [error ? "error" : "ok", (error || "").slice(0, 4000), Date.now(), custom_tool_id],
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
@@ -11,13 +11,12 @@ type Params = {
|
||||
/**
|
||||
* Saves whether a bot's run could connect to an MCP server, so its row in
|
||||
* Settings, under MCPs, shows a server that stopped answering (or came
|
||||
* back). Its tools listing is left as it was. Never throws.
|
||||
* back). Its tools listing and `updated_at` (when its settings last
|
||||
* changed) are left as they were. Never throws.
|
||||
*/
|
||||
export default async function recordMcpServerConnection({ mcp_server_id, error }: Params) {
|
||||
const now = Date.now();
|
||||
|
||||
await BunSQLite.sql({
|
||||
sql: `UPDATE mcp_servers SET status = ?, last_error = ?, last_synced_at = ?, updated_at = ? WHERE id = ?`,
|
||||
values: [error ? "error" : "ok", (error || "").slice(0, 4000), now, now, mcp_server_id],
|
||||
sql: `UPDATE mcp_servers SET status = ?, last_error = ?, last_synced_at = ? WHERE id = ?`,
|
||||
values: [error ? "error" : "ok", (error || "").slice(0, 4000), Date.now(), mcp_server_id],
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ type Params = {
|
||||
* super admins and admins. An admin never sees the coordinator, so its
|
||||
* attachment is kept as it is; only a super admin sets "every bot", which
|
||||
* when turned on gives it to every bot (`attachToAllBots`) and every new
|
||||
* one. Turning it off takes it from no one.
|
||||
* one. Turning it off takes it from no one. Either way it counts as a
|
||||
* change to the extension (`updated_at`).
|
||||
*/
|
||||
export default async function setExtensionAccess({ user_id, kind, id, bot_ids, workspace_ids, all_bots }: Params) {
|
||||
const role = await assertCrewManager({ user_id });
|
||||
@@ -63,5 +64,7 @@ export default async function setExtensionAccess({ user_id, kind, id, bot_ids, w
|
||||
});
|
||||
|
||||
if (all_bots && found.payload?.[0]?.all_bots != 1) await attachToAllBots({ kind, id });
|
||||
} else {
|
||||
await BunSQLite.sql({ sql: `UPDATE ${table} SET updated_at = ? WHERE id = ?`, values: [now, id] });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ export default async function syncMcpServer({ mcp_server_id, reinstall }: Params
|
||||
const tools = await listMcpTools({ client: await open.client() });
|
||||
|
||||
await BunSQLite.sql({
|
||||
sql: `UPDATE mcp_servers SET tools_cache = ?, status = 'ok', last_error = '', last_synced_at = ?, updated_at = ? WHERE id = ?`,
|
||||
values: [JSON.stringify(tools), now, now, server.id],
|
||||
sql: `UPDATE mcp_servers SET tools_cache = ?, status = 'ok', last_error = '', last_synced_at = ? WHERE id = ?`,
|
||||
values: [JSON.stringify(tools), now, server.id],
|
||||
});
|
||||
|
||||
return { ok: true as const, tools };
|
||||
@@ -49,8 +49,8 @@ export default async function syncMcpServer({ mcp_server_id, reinstall }: Params
|
||||
}).slice(0, 4000);
|
||||
|
||||
await BunSQLite.sql({
|
||||
sql: `UPDATE mcp_servers SET status = 'error', last_error = ?, last_synced_at = ?, updated_at = ? WHERE id = ?`,
|
||||
values: [message, now, now, server.id],
|
||||
sql: `UPDATE mcp_servers SET status = 'error', last_error = ?, last_synced_at = ? WHERE id = ?`,
|
||||
values: [message, now, server.id],
|
||||
});
|
||||
|
||||
return { ok: false as const, error: message };
|
||||
|
||||
@@ -39,6 +39,7 @@ export default async function testMcpDraft({
|
||||
status: "untested",
|
||||
last_error: "",
|
||||
last_synced_at: null,
|
||||
updated_at: null,
|
||||
},
|
||||
envs,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user