dsh-monkeyai-sessions 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Artenx
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,86 @@
1
- # Temporary Holding Version
1
+ # DSH MonkeyAI Sessions
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ English | [简体中文](README.zh.md)
4
+
5
+ Read and continue your MonkeyAI conversations inside DeepSeek Harness.
6
+
7
+ Browse the sessions on your MonkeyAI devices, open one to read its full conversation history, and send new instructions to carry on the work you started in the MonkeyAI client — no copy-pasting context, no restarting the task. Replies stream back live, and you can stop a running turn or switch models without leaving DSH.
8
+
9
+ Authorization uses the MonkeyAI OAuth authorization-code flow with PKCE; DSH stores the resulting grant in its credential store.
10
+
11
+ ## Development
12
+
13
+ The plugin targets DSH `v0.2.2-rc.1` and Node.js `>=24.9.0`.
14
+
15
+ ```sh
16
+ npm test
17
+ npm run build
18
+ ```
19
+
20
+ `npm test` builds the Client bundle before running tests. The build generates `client.js` and `lib/client-runtime.cjs`; both artifacts are distributed with the package.
21
+ Tests load the generated Client bundle, validate unary and duplex stream descriptors, check the `main` and `sidebar.panellist` registrations, verify stream and Remote cleanup on unload, and test PKCE state/challenge construction.
22
+ Host-service and Host-stream tests use credential-store, fetch, and WebSocket fakes to cover authorization exchange, device/session scoping, connection tickets, history and live frames, prompt delivery, connection loss, permission revocation, and read-only rejection.
23
+
24
+ The Host registers invocation descriptors through `ctx.typert`. The Client mounts the package's Remote contribution with `$mount()`. Shared Remote metadata uses the protocol package's `remote-info` entry, which has no Cordis runtime import.
25
+ The Client bundle inlines a spec-compatible copy of that factory (`src/shared/remote-info-lite.mjs`): DSH materializes only the modules listed in `dsh.client.inject`, and the protocol package's subpath entries are not seed words there.
26
+
27
+ ## Authorization
28
+
29
+ The panel uses DSH's light theme for a consistent, simple look. The layout is state-driven: an unconnected panel shows a single connect card (server origin plus one primary button, with the paste-callback mode collapsed), a connected panel shows a compact toolbar (account, device, one Refresh action that loads devices and sessions together, disconnect) above the session cards, and an open session focuses the conversation with a compact header (back button, title, model switcher), an approval card with plain option buttons instead of raw JSON, and an Enter-to-send composer. Secondary actions (adding a device by machine ID, creating a new session) stay collapsed in details sections.
30
+ The device list reads the account-wide endpoint directory (`GET /api/v1/endpoints`, no runtime-API header) so every registered device appears, marking `online` from the boolean field and skipping revoked entries. Selecting a device loads its sessions automatically. Headless runtime devices that register through the separate device-code grant may not appear in that directory; for those, add a device manually by machine ID ("Device missing?..." section in the panel) - the entry is kept in browser storage and merged into the device selector.
31
+
32
+ Three ways to connect, in order of convenience:
33
+
34
+ - **Sign in (default)**: enter the MonkeyAI server origin, account email, and password in the panel. The Host performs the whole OAuth exchange server-side — it logs in, opens an authorization request, approves it, and exchanges the returned code — so nothing has to come back from the browser. This is the only mode that works when the browser runs on a phone or any machine other than the DSH Host. The password is used for those requests only and is never stored; the panel clears the field on success.
35
+ - **Browser authorization (loopback)**: the Host listens on `127.0.0.1` with a random port and the MonkeyAI server redirects to `http://127.0.0.1:<port>/oauth/callback`. When the browser shares the Host's machine the callback page posts the code back to the panel and the grant completes with no copy-paste. A remote browser cannot reach that loopback address, so use sign-in instead.
36
+ - **Paste callback (scheme)**: the original `monkeyai-desktop://oauth/callback` redirect for environments where loopback is rejected.
37
+
38
+ All three request `device:connect`, `session:read`, and `session:control` through the registered `monkeyai-desktop` public client. OAuth state and the PKCE verifier stay in the DSH Host process.
39
+
40
+ ## Sessions
41
+
42
+ Full conversation history is loaded over the runtime's HTTP read channel (`POST {http_base}/read/session` with `_monkeyai/session/messages`, paginated by cursor) instead of the bounded ACP `session/load` replay, so long sessions show every turn including the latest replies. While a turn is running the composer shows a stop button that sends `session/cancel`; the model switcher uses `_monkeyai/session/model/set` on the live session connection. Assistant messages render lightweight markdown (code blocks, inline code, bold, headings, lists).
43
+
44
+ ## Installation
45
+
46
+ From npm, once published:
47
+
48
+ ```sh
49
+ dsh plugin --profile web add dsh-monkeyai-sessions
50
+ ```
51
+
52
+ From the plugin market index: enable **Custom plugin indexes** under Plugins → Experimental plugins, open **Discover**, and add this index source:
53
+
54
+ ```
55
+ https://artenx.github.io/dsh-monkeyai-sessions/index.json
56
+ ```
57
+
58
+ From a checkout:
59
+
60
+ ```sh
61
+ npm install
62
+ npm run build
63
+ npm pack
64
+ dsh plugin --profile web add ./dsh-monkeyai-sessions-0.1.1.tgz
65
+ ```
66
+
67
+ Verified against a real DSH `0.2.2-rc.1` web profile and a live MonkeyAI runtime: authorization, full history loading, prompt delivery, model switching, and turn cancellation all work end to end.
68
+
69
+ ## Publishing
70
+
71
+ The package declares a DSH bundle (`dsh.bundle.patch`), a web Client (`dsh.client`), and `engines.dsh`. Host-provided modules resolve through the running DSH installation, so the only peer dependency is `@deepseek-ai/cordis`.
72
+
73
+ ```sh
74
+ # Build the Client bundle and the market index
75
+ npm run build
76
+ npm run build:market
77
+
78
+ # Publish the package (requires an npm account with publish rights)
79
+ npm publish --access public
80
+ ```
81
+
82
+ `scripts/build-market-index.mjs` reads published versions and their publish times from the npm registry, falling back to the current `package.json` version before the first release. The resulting `market/index.json` follows plugin market index format 1 and is deployed to GitHub Pages by `.github/workflows/market-index.yml`. Set `MARKET_INDEX_URL` to override the printed index address.
83
+
84
+ ## License
85
+
86
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,96 @@
1
+ # DSH MonkeyAI 会话
2
+
3
+ [English](README.md) | 简体中文
4
+
5
+ 在 DeepSeek Harness 里读取并继续你的 MonkeyAI 对话。
6
+
7
+ 浏览 MonkeyAI 设备上的会话,打开任意一个查看完整对话历史,直接下发新指令接着做之前在 MonkeyAI 客户端上的工作——不用复制上下文,不用重新起任务。回复实时流式返回,还能在 DSH 里停止正在执行的回合、切换模型。
8
+
9
+ 授权走 MonkeyAI 的 OAuth 授权码 + PKCE 流程,拿到的凭证由 DSH 存进自己的凭证库。
10
+
11
+ ## 安装
12
+
13
+ 从 npm 安装:
14
+
15
+ ```sh
16
+ dsh plugin --profile web add dsh-monkeyai-sessions
17
+ ```
18
+
19
+ 从插件市场索引安装:在 **插件 → 实验性插件** 中打开 **自定义插件索引**,进入 **发现** 页添加索引源:
20
+
21
+ ```
22
+ https://artenx.github.io/dsh-monkeyai-sessions/index.json
23
+ ```
24
+
25
+ 从源码安装:
26
+
27
+ ```sh
28
+ npm install
29
+ npm run build
30
+ npm pack
31
+ dsh plugin --profile web add ./dsh-monkeyai-sessions-0.1.1.tgz
32
+ ```
33
+
34
+ 已在真实的 DSH `0.2.2-rc.1` web profile 与在线 MonkeyAI runtime 上端到端验证:授权、完整历史加载、指令下发、模型切换、回合取消均正常工作。
35
+
36
+ ## 连接账号
37
+
38
+ 三种方式,按便利程度排序:
39
+
40
+ - **账号登录(默认)**:在面板里填 MonkeyAI 服务器地址、账号邮箱和密码。整个 OAuth 流程由 Host 侧完成——登录、发起授权请求、批准、用返回的 code 换 token——浏览器不需要回传任何东西。**手机或任何非 Host 本机的浏览器只能用这种方式。** 密码仅用于这几次请求,不做任何存储,登录成功后面板立即清空输入框。
41
+ - **浏览器授权(loopback)**:Host 在 `127.0.0.1` 随机端口监听,MonkeyAI 服务器重定向到 `http://127.0.0.1:<port>/oauth/callback`。当浏览器与 Host 在同一台机器上时,回调页会把 code 通过 postMessage 发回面板,自动完成授权,无需粘贴。远程浏览器访问不到这个 loopback 地址,此时请改用账号登录。
42
+ - **粘贴回调(scheme)**:原始的 `monkeyai-desktop://oauth/callback` 重定向,用于 loopback 被拒绝的环境。
43
+
44
+ 三种方式都通过已注册的 `monkeyai-desktop` 公共客户端申请 `device:connect`、`session:read`、`session:control` 权限。OAuth state 与 PKCE verifier 始终留在 DSH Host 进程内。
45
+
46
+ ## 会话能力
47
+
48
+ 完整对话历史通过 runtime 的 HTTP 读取通道加载(`POST {http_base}/read/session`,方法 `_monkeyai/session/messages`,按游标翻页),而不是 ACP `session/load` 的有界回放,因此长会话能看到每一轮内容,包括最新回复。
49
+
50
+ 回合执行期间输入框旁会显示停止按钮,点击发送 `session/cancel`;模型切换在会话自己的连接上调用 `_monkeyai/session/model/set`。助手消息支持轻量 Markdown 渲染(代码块、行内代码、粗体、标题、列表)。
51
+
52
+ ## 界面说明
53
+
54
+ 面板采用 DSH 浅色主题,按状态切换布局:
55
+
56
+ - **未连接**:一张登录卡片(服务器地址 + 账号密码 + 主按钮),浏览器授权方式折叠收起
57
+ - **已连接**:会话卡片上方是紧凑工具栏(账号、设备、一个刷新按钮同时加载设备与会话、断开连接)
58
+ - **会话中**:紧凑会话头(返回、标题、模型切换)、审批卡片用普通选项按钮而非原始 JSON、回车发送的输入框
59
+
60
+ 次要操作(按 machine ID 手动添加设备、新建会话)都收在折叠区里。
61
+
62
+ 设备列表读取账号级的 endpoint 目录(`GET /api/v1/endpoints`),因此所有已注册设备都会出现,在线状态取自 `status` 字段,已撤销的条目会被跳过。选中设备后自动加载其会话。通过独立设备码授权注册的 headless runtime 可能不在该目录里,这类设备可在面板「找不到设备?」区域按 machine ID 手动添加,条目保存在浏览器本地存储并合并进设备选择器。
63
+
64
+ ## 开发
65
+
66
+ 插件面向 DSH `v0.2.2-rc.1` 与 Node.js `>=24.9.0`。
67
+
68
+ ```sh
69
+ npm test
70
+ npm run build
71
+ ```
72
+
73
+ `npm test` 会先构建 Client bundle 再跑测试。构建产出 `client.js` 与 `lib/client-runtime.cjs`,两者都随包分发。
74
+
75
+ 测试会加载生成的 Client bundle,校验一元与双向流描述符,检查 `main` 与 `sidebar.panellist` 注册,验证卸载时流与 Remote 的清理,并测试 PKCE state/challenge 构造。Host 服务与 Host 流测试用凭证库、fetch、WebSocket 的替身覆盖授权交换、设备/会话作用域、连接票据、历史与实时帧、指令投递、连接中断、权限撤销、只读拒绝等场景。
76
+
77
+ Host 通过 `ctx.typert` 注册调用描述符,Client 用 `$mount()` 挂载包的 Remote 贡献。共享的 Remote 元数据使用协议包的 `remote-info` 入口,它不引入 Cordis 运行时。Client bundle 内联了该工厂的规范兼容副本(`src/shared/remote-info-lite.mjs`):DSH 只实例化 `dsh.client.inject` 中列出的模块,协议包的子路径入口不在其种子词表内。
78
+
79
+ ## 发布
80
+
81
+ 包声明了 DSH bundle(`dsh.bundle.patch`)、web Client(`dsh.client`)与 `engines.dsh`。Host 提供的模块通过运行中的 DSH 安装解析,因此唯一的 peer 依赖是 `@deepseek-ai/cordis`。
82
+
83
+ ```sh
84
+ # 构建 Client bundle 与市场索引
85
+ npm run build
86
+ npm run build:market
87
+
88
+ # 发布(需要有发布权限的 npm 账号)
89
+ npm publish --access public
90
+ ```
91
+
92
+ `scripts/build-market-index.mjs` 从 npm registry 读取已发布版本及其发布时间,首次发布前回退到当前 `package.json` 版本。生成的 `market/index.json` 遵循插件市场索引 format 1,由 `.github/workflows/market-index.yml` 部署到 GitHub Pages。设置 `MARKET_INDEX_URL` 可覆盖打印出的索引地址。
93
+
94
+ ## 许可
95
+
96
+ MIT
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64">
2
+ <circle cx="7" cy="9.5" r="3.2" fill="#8b5e3c"/>
3
+ <circle cx="17" cy="9.5" r="3.2" fill="#8b5e3c"/>
4
+ <circle cx="7" cy="9.5" r="1.6" fill="#e8c9a8"/>
5
+ <circle cx="17" cy="9.5" r="1.6" fill="#e8c9a8"/>
6
+ <circle cx="12" cy="12" r="7.5" fill="#a06b42"/>
7
+ <path d="M6.8 12.2c0-2.6 2.3-4.4 5.2-4.4s5.2 1.8 5.2 4.4c0 3.2-2.3 5.6-5.2 5.6s-5.2-2.4-5.2-5.6z" fill="#f3ddc4"/>
8
+ <circle cx="9.7" cy="11.6" r="1.05" fill="#3d2b1c"/>
9
+ <circle cx="14.3" cy="11.6" r="1.05" fill="#3d2b1c"/>
10
+ <path d="M9.8 14.9c.6.7 1.4 1 2.2 1s1.6-.3 2.2-1" stroke="#3d2b1c" stroke-width="1.1" stroke-linecap="round" fill="none"/>
11
+ </svg>