// @dsh-local/portal-entry — PoC host plugin for the dsh web profile. // // Goal: prove the official profile-plugin mechanism on dsh 0.1.2-rc.1 // (install -> load -> persist across restart -> remove), with zero risk to // the running profile: every side effect is guarded, nothing can throw out // of apply(). // // v1 evidence channel: an append-only marker file // $DSH_HOME/.dsh-poc-portal-entry.log // written when the row is instantiated. Tool registration (defineTool from // @deepseek-ai/dsh-tools) is attempted defensively; failure is logged, never // fatal. import { appendFileSync } from "node:fs"; import { join } from "node:path"; const MARKER = ".dsh-poc-portal-entry.log"; const PORTAL_ROOT = process.env.DSH_SERVER_LOGIN_URL ?? "http://127.0.0.1:3080"; /** Append one line to the marker file. Never throws. */ function log(line) { try { const home = process.env.DSH_HOME || process.env.HOME || "."; appendFileSync(join(home, MARKER), `${new Date().toISOString()} ${line}\n`); } catch { // marker writes must never take the profile down } } /** Build the portal_ping tool definition (lazy import of defineTool). */ async function portalPingDefinition() { const { defineTool } = await import("@deepseek-ai/dsh-tools"); return defineTool({ name: "portal_ping", description: "PoC tool: probe the dsh-server-login portal reachable from this instance. Returns HTTP status and body size of the portal root.", parameters: {}, output: { schema: { type: "object", additionalProperties: false, properties: { ok: { type: "boolean", required: true }, status: { type: "number" }, bytes: { type: "number" }, note: { type: "string" } } } }, isConcurrencySafe: () => true, async execute() { try { const res = await fetch(PORTAL_ROOT, { redirect: "manual" }); const body = await res.arrayBuffer(); return { ok: true, status: res.status, bytes: body.byteLength, note: `portal root reachable from instance (${PORTAL_ROOT})` }; } catch (err) { return { ok: false, note: `portal unreachable: ${String(err?.message ?? err)}` }; } } }); } /** Cordis-style plugin apply. Row declares inject:[tools], so ctx.tools is * available; every failure is still contained and logged. */ export function apply(ctx) { log(`apply pid=${process.pid} dshHome=${process.env.DSH_HOME ?? ""} home=${process.env.HOME ?? ""}`); const register = () => { try { if (!ctx.tools || typeof ctx.tools.register !== "function") { log("tools service unavailable at apply time"); return; } portalPingDefinition() .then((def) => { try { ctx.tools.register(def); log("tool portal_ping registered"); } catch (err) { log(`tool register threw: ${String(err?.message ?? err)}`); } }) .catch((err) => log(`tool build failed: ${String(err?.message ?? err)}`)); } catch (err) { log(`tools access failed: ${String(err?.message ?? err)}`); } }; try { register(); } catch (err) { log(`register wrapper failed: ${String(err?.message ?? err)}`); } } export default apply;