全部插件

DSH / BUNDLE / BUNDLES

@gausszhou/dsh-where-am-i

v0.1.0gausszhou / dsh-where-am-i262dd5032a

可安装组合包组合包与其他模块社区 · Topic 自动分析

概览

@gausszhou/dsh-where-am-i

Inject a neofetch-like device info block (host, OS, kernel, arch, CPU, memory, uptime, timezone, locale, shell, node) into each brand-new DeepSeek Harness session once; existing sessions are untouched.

README / ZH

插件文档

dsh-where-am-i

Neofetch for DeepSeek Harness.

English | 简体中文

DeepSeek Harness (dsh) 插件:把当前设备信息以 neofetch 风格注入每个新建会话——OS 发行版、内核、架构、主机名、CPU、内存、uptime、时区、locale、shell/terminal、Node 版本。只在全新会话的第一步注入一次,之后持久保留在该会话历史里;已有会话完全不受影响。

一句话行为

  • 全新会话(创建后第一次发送消息):注入一条设备信息 user 消息 → 模型在会话开头看到它;
  • 已有会话(重启前就存在的、恢复的、延续中的):系统提示词与会话历史都不变,一条也不加;
  • 同一个会话的后续步骤:永不重复注入(消息已持久化在历史里,直到 compaction 遮蔽);
  • 子代理会话(subagent/工作流工具派生的临时会话):默认跳过(避免每次 fan-out 都重复);includeSubagents: true 可放开。

使用方法

将插件加进 dsh profile(发布为 npm 包后按包名安装):

dsh plugin --profile web add "@gausszhou/dsh-where-am-i"

本地开发时用 link 依赖(与 dsh-opencode-session-id 相同的方式):在 ~/.dsh/profiles/web/package.jsondependencies"@gausszhou/dsh-where-am-i": "link:/home/gauss/Code/gausszhou/dsh-where-am-i",并把它加入 dsh.profile.bundles;插件自带的 cordis.patch.ymldsh.bundle.patch)会完成 insert。

装完后重启 dsh websystemctl --user restart dsh-web)让 bundle 生效。默认零配置即可用。

新会话里模型看到的内容(本机实测)

System info (the machine this dsh session runs on; sampled at session start):
host: gauss-KP
user: gauss
os: Ubuntu 26.04 LTS
kernel: 7.0.0-29-generic
arch: x86_64
cpu: 6 × Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
memory: 7.9 GiB used / 15.0 GiB total
uptime: 1d 4h 3m
timezone: Asia/Shanghai (GMT+08:00)
locale: zh_CN.UTF-8
shell: /bin/bash
term: dumb
node: v24.19.0

配置

默认零配置;全部可选项(均可省略,用默认值):

默认 说明
fields 全部 13 项 只输出指定的字段行,按默认顺序排列,例如 [os, arch, timezone];未知字段名被忽略;过滤后为空则回退到全部
includeSubagents false true 时也会往子代理会话注入(默认跳过,避免 fan-out 重复)
verbose false 注入时把快照打到 stdout(web 部署可 journalctl -u dsh-web 看到)

字段清单(emission 顺序):host user os kernel arch cpu memory uptime timezone locale shell term node。采样不到的字段(如无 SHELL 环境变量的 Windows)会自动省略该行。

# ~/.dsh/profiles/web/cordis.patch.yml
- id: where-am-i
  config:
    fields: [os, kernel, arch, cpu, memory, timezone]

设计说明:dsh 现有提示词里已有哪些信息

实现前对 dsh 现有提示词做了调研(dsh-system-prompt 的段注册与变量、dsh-agent-loop 的变量提供、各 runtime-context 包),已有内容如下,本插件只补缺口、不重复

已有事实 来源 位置
You are an AI agent powered by DeepSeek Harness. dsh-system-prompt 系统提示词段 harness:identity,order -100
DSH 源码 checkout 路径 dsh-app-boot / dsh-web-app harness:source,order -99
Web GUI URL dsh-web-app(仅 web profile) app:web-surface,order -98
部署 persona 配置 deployment:persona,order 0
工具跨调用引导(read/write/edit/bash/web_search…) dsh-tool-* tool:*,order 100–199
{{provider}} {{model}} {{cwd}}(会话工作目录,每次组装求值) dsh-agent-loop 提示词变量
文件沙箱策略、审批策略 dsh-sandbox-policy / dsh-user-approval runtime context(user 角色快照)
带时区时间戳 + 浏览器时区 + 经过时长 dsh-time-context(默认组合未启用) runtime context
tmux session/window/pane 位置 dsh-tmux-context(非 web 组合) runtime context
AGENTS.md / CLAUDE.md 工作区指令 dsh-agent-instructions 持久 user 消息

完全缺失(即本插件补的):OS/发行版名、内核 release、CPU 架构、主机名、CPU 型号与核心数、总/空闲内存、uptime、宿主 locale、shell/terminal、Node 版本、宿主进程时区。

刻意省略的字段

  • cwd{{cwd}} 变量已按会话实时提供,harness 也明确警告不要从 checkout 路径推断工作目录——不重复。
  • 日期/当前时间:冻结在历史里的墙钟会过期;实时时间戳由 dsh-time-context 按请求提供(启用时)。
  • ASCII logo / 桌面壁纸:纯 token 噪音,对模型无信息量。

为什么不是「系统提示词段」,而是「新会话一次性消息」

第一版实现用了 systemPrompt.section(),但那意味着:插件挂载后,每个会话的每一步都渲染同一段文本——既做不到「一次」,也会改写所有已有会话的系统提示词前缀(KV cache 从第一个变化的 token 起失效一次)。

现在的实现改为 dsh-time-context / dsh-tmux-context 同一条 seam:注册一个前置的 agent/pre-step waterfall 监听器,先 await next() 让下游先决策,仅当决策进入(enter)时,向该步批次追加一条持久、带来源的 user 消息。agent loop 会在 step/start 后把批次里的每条消息 session.append("user/message", …) 持久化,于是:

  • 注入的消息成为该会话自己的历史(模型开头可见,compaction 前一直保留);
  • 不注册任何系统提示词段 → 已有会话的系统提示词字节级不变,前缀与 KV cache 全部保留;
  • 后续步骤(本会话或其他任何会话)看到历史里已存在消息 → 永不再次注入(跨重启、跨插件热重载都成立——判定只看会话日志本身)。

「全新会话」的判定:pre-step 时 agent.session.events 里还没有任何 user/messageassistant/messagetool/result 事件(第一步的在途提示词要等步骤进入后才持久化,time-context 的 README 明示这一点)。任何恢复/延续/已注入的会话都至少有一个这类事件 → 永久跳过。空批次(纯 runtime context、调度轮次等,没有 user 来源消息)也不会被注入。

设备信息在注入时采样(即新会话第一步的时刻),uptime/内存尽可能新鲜;消息是按会话的历史,会话之间字节差异零成本。

对「已有会话前缀」的明确结论

  • 系统提示词:插件不注册段renderPrompt 对已有会话的输出与安装前一模一样(集成测试断言了这一点);
  • 会话历史:已有会话不会被追加任何消息;
  • 受影响面仅限新建会话:注入发生在它第一次请求之前,属于该会话自己的前缀,不存在旧缓存可供失效。

实现细节

  • 零子进程:不调 sw_vers / uname,全部来自 node:os、一次同步读 /etc/os-release(Linux/WSL 取 PRETTY_NAME,回退 ID VERSION_ID)与 Intl
  • 架构名按 neofetch 习惯映射:x64→x86_64arm64→aarch64ia32→i386arm→armv7l
  • macOS 从 Darwin release 反推营销版本(Darwin 24 ↔ macOS 15,19 ↔ 10.15,更老不猜)。
  • 时区是宿主进程时区(IANA 名 + 当前 UTC 偏移,DST 感知);与 dsh-time-context 的浏览器时区是两个概念。
  • 注入消息满足 harness 的消息契约(assertMessageEventShape:非空 idrole: "user"source.kindcontent 数组),source 形状与 time-context 的插件快照一致({ kind: 'plugin', plugin: 'where-am-i', form: 'snapshot', sections: [...] }),UI/轨迹归因一致。
  • 监听器 inject: ["agents"](与 time-context 相同),树里没有 agents 注册表时不加载。

验证

node test/verify.mjs          # 单测:os-release 解析/架构映射/macOS 命名/字节与时间格式化/时区偏移/配置归一化/渲染子集/决策门(user 来源、历史门、子代理门)/消息形状/不重复 cwd/date + 本机真实快照
node test/smoke-apply.mjs     # 接线:全新会话注入一次、已有会话零注入、同一会话永不重注入、无 user 来源不注入、reject/abort 透传、子代理门、fields 子集
node test/integration-real.mjs # 真实 cordis + dsh-system-prompt + dsh-session:系统提示词不被改动、注入消息被真实 Session 持久化并进入派生历史、同会话不再注入

说明与限制

  • 快照在新会话第一步采样:该会话期间 uptime/内存/负载会过期(这正是 neofetch-at-session-start 语义;消息是历史,不再刷新)。
  • /etc/os-release 缺失且非 Windows/macOS 时,os 行回退到 os.version()/os.type(),可能不如发行版名友好。
  • user 行不隐去:模型能看见运行 dsh 的本地用户名(与 neofetch 一致)。在意隐私可以 fields 里去掉 user/host
  • 注入的是宿主机信息;若 dsh 跑在容器/远程执行里,报告的是容器/远程内核,而非开发机(如 WSL 会显示 WSL 内核号)。
  • 消息会占用每条请求的 token(compaction 遮蔽前);这也是为什么已有会话不加、子代理默认不加——只付一次、只付给真正的新对话。

LIMITATIONS

已知限制

- The snapshot is sampled at each new session's **first step**: uptime/memory go stale during that session (neofetch-at-session-start semantics; the message is history and is not refreshed). - Without `/etc/os-release` on non-Windows/macOS systems, the `os` line falls back to `os.version()`/`os.type()` and may be less friendly than a distro name. - The `user` line is not redacted — the model can see the local username running dsh (like neofetch). Drop `user`/`host` via `fields` if you care about privacy. - Host-machine facts are reported; if dsh runs inside a container or remote execution, the kernel reported is the container's/remote one (e.g. WSL shows the WSL kernel). - The message costs tokens on every request until compaction hides it; this is why existing sessions and subagents are excluded by default — the cost is paid once, only by genuinely new conversations.