**背景**:这些改动原属本工作区另外几个会话(T01/T02 等),**那些会话已被用户删除** ⇒
工作树里的成果处于"无主"状态,一次错误 checkout / 覆盖即**永久丢失** ⇒ 代入库保全。
口径遵循本项目**先例**(`39a1f2e` / `b617cdb`:**别人的活,代入库并在提交信息里注明**)。
**内容**:档案 101「能力管理」改名 + 页内 tab 分页|档案 102 语言切换搬入「用户设置」|
`07-实例UI分区登记表.md`|`scripts/find-ui*.mjs`(UI 元素定位工具)|`poc/portal-entry/`(0.5.3)|
`src/web/locale-pref.ts` + `home-files.ts`(语言偏好持久化)|`test/locale-pref.test.mjs`|
`package.json`|`BRIEF.md` / `INDEX.md` / `docs-manifest.json` / `03-路线图与待办.md` / 档案 100 增量。
**已做最小健全性检查**(⚠️ **未跑完整构建 / 单测** —— 那是原会话的验收职责,本次只求"不丢"):
- JSON 合法:`package.json` / `poc/business-plugins/package.json` / `docs-manifest.json` ✓
- 4 个 TS 文件 `{}`/`()` 配平 ✓;新增文件均非空 ✓
- 规模:13 文件改动 +340/−210,新增 12 条
**未 push**(按 §4 提交边界:用户说"提交",未说"推送")。
102 lines
3.3 KiB
JavaScript
102 lines
3.3 KiB
JavaScript
// @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;
|