@vicfei/dsh-super-agent 0.6.1 → 0.8.0
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/README.md +13 -2
- package/README.zh-CN.md +13 -2
- package/dist/cli.js +62 -9
- package/dist/cli.js.map +1 -1
- package/dist/domain.d.ts +9 -2
- package/dist/domain.js +1 -0
- package/dist/domain.js.map +1 -1
- package/dist/engine.d.ts +17 -6
- package/dist/engine.js +72 -19
- package/dist/engine.js.map +1 -1
- package/dist/feishu.d.ts +66 -0
- package/dist/feishu.js +112 -0
- package/dist/feishu.js.map +1 -0
- package/dist/github/client.d.ts +6 -0
- package/dist/github/client.js +9 -0
- package/dist/github/client.js.map +1 -1
- package/dist/github/source.d.ts +4 -2
- package/dist/github/source.js +1 -0
- package/dist/github/source.js.map +1 -1
- package/dist/github/state.d.ts +2 -4
- package/dist/github/state.js.map +1 -1
- package/dist/merge.d.ts +10 -3
- package/dist/merge.js +20 -7
- package/dist/merge.js.map +1 -1
- package/dist/panel.html +3 -1
- package/dist/slack.d.ts +57 -0
- package/dist/slack.js +106 -0
- package/dist/slack.js.map +1 -0
- package/dist/source.d.ts +25 -0
- package/dist/source.js +11 -0
- package/dist/source.js.map +1 -0
- package/dist/usage.d.ts +1 -1
- package/dist/usage.js +4 -1
- package/dist/usage.js.map +1 -1
- package/dist/watch.d.ts +5 -2
- package/dist/watch.js +12 -8
- package/dist/watch.js.map +1 -1
- package/dist/wechat.d.ts +142 -0
- package/dist/wechat.js +262 -0
- package/dist/wechat.js.map +1 -0
- package/dist/work.d.ts +14 -2
- package/dist/work.js +31 -9
- package/dist/work.js.map +1 -1
- package/examples/policy.json +57 -9
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -73,8 +73,10 @@ Early. Seed milestone — the admission domain compiles, is tested, and nothing
|
|
|
73
73
|
| Panel — one page of what awaits a human, observe records, mode switch | ✅ v0.4.0 |
|
|
74
74
|
| PR delivery — worker commits become a branch + pull request, linked in the report | ✅ v0.5.0 |
|
|
75
75
|
| Auto-merge — delivery requirements: own PR, allowed-list approval covering head, ±line cap; any CHANGES_REQUESTED vetoes | ✅ v0.6 |
|
|
76
|
-
|
|
|
77
|
-
|
|
|
76
|
+
| Subscription bypass — an open ticket absorbs the opener's follow-ups as context; resume carries the resuming message to the worker | ✅ v0.7 |
|
|
77
|
+
| GitHub App auth — hourly installation tokens, bot identity; person-stages panel | ✅ v0.6 |
|
|
78
|
+
| Feishu / Slack / WeChat channels — same admission table, same loop (`im_dm` / `im_group`) | ✅ v0.8 |
|
|
79
|
+
| Speculative execution, Watchdog, executor sandboxing | v0.9 — see [docs/ROADMAP.md](docs/ROADMAP.md) |
|
|
78
80
|
|
|
79
81
|
## Quick start
|
|
80
82
|
|
|
@@ -124,15 +126,24 @@ Auto-merge (default **off**) closes the loop with structural brakes — every co
|
|
|
124
126
|
- additions + deletions ≤ `maxChangedLines` (default 200)
|
|
125
127
|
- no allowed-list reviewer's latest stance is CHANGES_REQUESTED (a one-person veto until re-reviewed)
|
|
126
128
|
- the merge PUT is pinned to the approved SHA — if the head moved, it re-evaluates next cycle
|
|
129
|
+
- with `policy.merge.requireCi` (default off): the head commit must have CI and all of it green — failing or still-running checks hold the merge
|
|
127
130
|
|
|
128
131
|
> **Sole operators, note:** the approval bullet is why delivery should run under GitHub App auth (next section). With a personal token the agent's PRs are authored by *you* — and GitHub never lets you approve your own PR, so the merge gate can never be satisfied. Team setups can approve each other; a single operator needs the bot identity.
|
|
129
132
|
|
|
133
|
+
Follow-ups on a live ticket join it as **context** instead of spawning duplicates — the subscription bypass: while your ticket is open, adding "also handle X" in the same thread accumulates into the worker's next run (one ticket, one worktree, one PR); a resumed ticket likewise carries the resuming message to the worker. Other people's messages are not joined — their text entering the worker's context would widen the injection surface.
|
|
134
|
+
|
|
130
135
|
**GitHub App auth (required for auto-merge when you operate alone).** By default everything rides a personal token (`GITHUB_TOKEN`): replies post as *you*, and rate limits are per-user. Configure a GitHub App instead and the agent acts as its own principal: PRs and replies carry the App's bot identity (the gate already caps bots at inferred — they can never issue explicit requests), so you become the legitimate approver; limits are per-installation, and installation tokens rotate hourly — no long-lived secret in the environment:
|
|
131
136
|
|
|
132
137
|
1. Create a user-owned App at [github.com/settings/apps/new](https://github.com/settings/apps/new) — permissions: **Issues: read & write, Pull requests: read & write, Contents: read & write, Metadata: read**; no webhook/subscription needed (everything is polled)
|
|
133
138
|
2. Install it on your repo, then set the environment: `GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY` (the PEM, `\n`-escaped — or `GITHUB_APP_PRIVATE_KEY_PATH`), optionally `GITHUB_APP_INSTALLATION_ID` (auto-discovered from `--repo` when omitted)
|
|
134
139
|
3. Run as usual — startup logs `auth: GitHub App …`. Precedence: `--token` flag > App env > `GITHUB_TOKEN`; branch pushes ride the same credential over https (ssh remotes keep using your ssh key)
|
|
135
140
|
|
|
141
|
+
**Feishu channel (v0.8).** `watch` also listens on Feishu when `FEISHU_APP_ID` + `FEISHU_APP_SECRET` are set. One-time setup: create a self-built app at [open.feishu.cn/app](https://open.feishu.cn/app), enable the **bot** capability, subscribe to `im.message.receive_v1` in **long-connection** mode (no public callback URL), and grant `im:message` permissions. DMs and group @mentions then flow through the same admission table (`im_dm` / `im_group` rows — the table stays data), tickets run the same executor loop, and replies post back into the chat. Set `FEISHU_BOT_OPEN_ID` for precise group @mention detection; without it group messages are never "addressing" (fail-closed — allowed-list members still produce inferred via the `listedNotAddressing` cell).
|
|
142
|
+
|
|
143
|
+
**Slack channel (v0.8).** With `SLACK_BOT_TOKEN` (xoxb-) + `SLACK_APP_TOKEN` (xapp-) set, `watch` joins Slack over **Socket Mode** — no public URL. One-time setup: create an app at [api.slack.com/apps](https://api.slack.com/apps), enable Socket Mode, subscribe to the `message.channels` / `message.groups` / `message.im` / `message.mpim` events, and grant `chat:write` plus the read scopes those events require. The bot's own user id is discovered via `auth.test`, so @mention detection in channels is precise with zero manual config; DMs are inherently addressed. Same admission rows (`im_dm` / `im_group`), same loop, replies back into the channel.
|
|
144
|
+
|
|
145
|
+
**WeChat channel (v0.8).** Personal WeChat over the **iLink Bot Protocol** — an HTTP, Telegram-bot-shaped API on WeChat's own domain (`ilinkai.weixin.qq.com`); no reverse-engineering, no client hooks. One-time login: `wechat-login` saves a QR image, you scan it with your WeChat app and confirm; credentials, the long-poll cursor, and per-thread reply routes land in the engine db (same `--db` as your watch daemon, which then arms the source automatically). DMs are inherently addressed and become `im_dm` triggers; group messages become `im_group` with fail-closed addressing (the protocol's group text is not reliably @-parseable — allowed-list members still produce inferred). Replies echo the routing `context_token` verbatim — that token is what routes a reply to the right conversation. Session expiry (`-14`) clears state with a re-login hint; the long-poll aborts itself each cycle so a watch is never blocked. Text-first: media bodies arrive as `[type]` placeholders (AES media is a later slice). Protocol reference: [wechatbot.dev/zh/protocol](https://www.wechatbot.dev/zh/protocol).
|
|
146
|
+
|
|
136
147
|
And the panel (`npm run panel`, localhost) shows only what needs a person — needs-person tickets, observe records marked *would accept*, the full decision log, and the accept-mode switch (switching to `auto` asks you to confirm):
|
|
137
148
|
|
|
138
149
|
## Comparison
|
package/README.zh-CN.md
CHANGED
|
@@ -73,8 +73,10 @@ Super-agent 文章里最锋利的实验发现:给单会话智能体配上 subage
|
|
|
73
73
|
| 面板——只列等人事项、观察记录、模式切换 | ✅ v0.4.0 |
|
|
74
74
|
| PR 交付——Worker 的新提交自动变分支+Pull Request,报告带链接 | ✅ v0.5.0 |
|
|
75
75
|
| Auto-merge——交付门槛:自己的 PR、allowedList 审批覆盖头提交、±行数上限;CHANGES_REQUESTED 一票否决 | ✅ v0.6 |
|
|
76
|
-
|
|
|
77
|
-
|
|
|
76
|
+
| 订阅旁路——开着的工单吸收开单人的后续评论作上下文;resume 把新消息带给 worker | ✅ v0.7 |
|
|
77
|
+
| GitHub App 认证——installation token 每小时轮换、bot 身份;按人分阶段面板 | ✅ v0.6 |
|
|
78
|
+
| 飞书 / Slack / 微信通道——同一张准许表,同一回路(`im_dm` / `im_group`) | ✅ v0.8 |
|
|
79
|
+
| 投机执行、Watchdog、执行器沙箱 | v0.9——见 [docs/ROADMAP.md](docs/ROADMAP.md) |
|
|
78
80
|
|
|
79
81
|
## 快速开始
|
|
80
82
|
|
|
@@ -124,15 +126,24 @@ Auto-merge(默认**关闭**)用结构性刹车把闭环走完——每个条件
|
|
|
124
126
|
- additions + deletions ≤ `maxChangedLines`(默认 200)
|
|
125
127
|
- 没有任何 allowedList 评审的最新立场是 CHANGES_REQUESTED(一人否决,直到重审)
|
|
126
128
|
- 合并请求锁定被审批的那个 SHA——头提交变了就下周期重评
|
|
129
|
+
- 开启 `policy.merge.requireCi`(默认关)后:头提交必须有 CI 且全绿——失败或还在跑都按住不合并
|
|
127
130
|
|
|
128
131
|
> **单人运营者注意:**"审批"那一条正是交付要走 GitHub App 认证(下一节)的原因。用个人令牌时,agent 的 PR 作者*是你本人*——而 GitHub 永远不允许你批准自己的 PR,合并门槛就永远凑不齐。团队可以互批;单人必须靠 bot 身份。
|
|
129
132
|
|
|
133
|
+
活着的工单会把后续评论收作**上下文**而不是开出重复工单——订阅旁路:你的工单开着时,在同一线程补一句"顺便也处理 X",会累积进 worker 的下一次运行(一张工单、一个 worktree、一个 PR);resume 同样把续跑消息带给 worker。其他人的消息不会并入——把他们的文本放进 worker 上下文会扩大注入面。
|
|
134
|
+
|
|
130
135
|
**GitHub App 认证(单人使用 auto-merge 时为必需)。** 默认一切走个人令牌(`GITHUB_TOKEN`):回复以*你本人*身份发出,限额按用户算。改配 GitHub App 后,agent 以自己的主体身份行动:PR 和回复都带 App 的 bot 身份(门禁本就把 bot 封顶在 inferred——bot 永远发不出 explicit 请求),你由此成为合法审批人;限额按安装计,installation token 每小时轮换——环境里不再有长效密钥:
|
|
131
136
|
|
|
132
137
|
1. 在 [github.com/settings/apps/new](https://github.com/settings/apps/new) 创建用户级 App——权限只需 **Issues: read & write、Pull requests: read & write、Contents: read & write、Metadata: read**;不需要 webhook/订阅(全部轮询)
|
|
133
138
|
2. 安装到你的仓库,然后设环境变量:`GITHUB_APP_ID`、`GITHUB_APP_PRIVATE_KEY`(PEM 内容,`\n` 转义——或 `GITHUB_APP_PRIVATE_KEY_PATH` 指文件)、可选 `GITHUB_APP_INSTALLATION_ID`(省略时从 `--repo` 自动发现)
|
|
134
139
|
3. 照常运行——启动会打一行 `auth: GitHub App …`。优先级:`--token` 参数 > App 环境变量 > `GITHUB_TOKEN`;分支推送走 https 时用同一凭证(ssh remote 继续用你的 ssh key)
|
|
135
140
|
|
|
141
|
+
**飞书通道(v0.8)。** 设置 `FEISHU_APP_ID` + `FEISHU_APP_SECRET` 后,`watch` 同时监听飞书。一次性配置:在 [open.feishu.cn/app](https://open.feishu.cn/app) 建自建应用,开启**机器人**能力,订阅 `im.message.receive_v1` 并选**长连接**模式(无需公网回调),授予 `im:message` 权限。此后私聊和群内 @提及走同一张准许表(`im_dm` / `im_group` 行——表保持数据化),工单走同一执行回路,回复自动发回会话。配置 `FEISHU_BOT_OPEN_ID` 可精确判定群内 @提及;不配则群消息永不视为 addressing(失败关闭——allowedList 成员仍可经 `listedNotAddressing` 格产生 inferred)。
|
|
142
|
+
|
|
143
|
+
**Slack 通道(v0.8)。** 设置 `SLACK_BOT_TOKEN`(xoxb-)+ `SLACK_APP_TOKEN`(xapp-)后,`watch` 以 **Socket Mode** 接入 Slack——无需公网地址。一次性配置:在 [api.slack.com/apps](https://api.slack.com/apps) 建应用,启用 Socket Mode,订阅 `message.channels` / `message.groups` / `message.im` / `message.mpim` 事件,授予 `chat:write` 及这些事件所需的读权限。bot 自身的 user id 通过 `auth.test` 自动发现,频道内 @提及判定精确且零手工配置;私聊天然视为 addressing。同一准许表(`im_dm` / `im_group`),同一回路,回复发回频道。
|
|
144
|
+
|
|
145
|
+
**微信通道(v0.8)。** 个人微信走 **iLink Bot Protocol**——微信自有域名(`ilinkai.weixin.qq.com`)上的 HTTP、类 Telegram Bot API;零逆向、零客户端 hook。一次性登录:`wechat-login` 保存二维码图片,你用微信扫码并在手机确认;凭证、长轮询游标、按线程的回复路由全部落进 engine db(与 watch 守护进程同一个 `--db`,自动挂载微信源)。私聊天然视为 addressing,产生 `im_dm` 触发;群消息产生 `im_group`,addressing 失败关闭(该协议的群文本无法可靠解析 @——allowedList 成员仍可产生 inferred)。回复原样回带路由 `context_token`——它决定回复落进哪个会话。会话过期(`-14`)清空状态并提示重登;长轮询每周期自我中止,永不阻塞 watch。文本优先:媒体消息体以 `[类型]` 占位(AES 媒体是后续切片)。协议参考:[wechatbot.dev/zh/protocol](https://www.wechatbot.dev/zh/protocol)。
|
|
146
|
+
|
|
136
147
|
面板(`npm run panel`,仅本机)只显示需要人的事项——needs-person 工单、标注 *would accept* 的观察记录、完整决策日志,以及接受模式切换(切 `auto` 会要求确认):
|
|
137
148
|
|
|
138
149
|
## 对比
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// CLI — poll (Source → gate → optional LLM assessment → Engine), work (claim → subprocess →
|
|
3
3
|
// report → drain), tickets (list / stop). Token and API keys come from the environment only.
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { Engine } from "./engine.js";
|
|
8
8
|
import { classify, formatOutcome } from "./runner.js";
|
|
@@ -12,7 +12,7 @@ import { GitHubClient } from "./github/client.js";
|
|
|
12
12
|
import { AppTokenProvider, appAuthFromEnv } from "./github/app-auth.js";
|
|
13
13
|
import { GitHubSource } from "./github/source.js";
|
|
14
14
|
import { Executor } from "./executor.js";
|
|
15
|
-
import { runWork } from "./work.js";
|
|
15
|
+
import { GitHubReplyChannel, runWork } from "./work.js";
|
|
16
16
|
import { mergePolicyOf } from "./domain.js";
|
|
17
17
|
import { NO_TOKEN_HINT, scaffoldFromExample, USAGE } from "./usage.js";
|
|
18
18
|
function die(msg) {
|
|
@@ -52,7 +52,7 @@ if (args.version) {
|
|
|
52
52
|
console.log(version);
|
|
53
53
|
process.exit(0);
|
|
54
54
|
}
|
|
55
|
-
const COMMANDS = ["poll", "work", "watch", "tickets", "panel", "merge", "help"];
|
|
55
|
+
const COMMANDS = ["poll", "work", "watch", "tickets", "panel", "merge", "wechat-login", "help"];
|
|
56
56
|
const command = positionals[0] ?? "poll";
|
|
57
57
|
if (args.help || command === "help") {
|
|
58
58
|
console.log(USAGE);
|
|
@@ -147,7 +147,7 @@ try {
|
|
|
147
147
|
engine.setPolicyIfChanged(policy);
|
|
148
148
|
const assessor = buildAssessor();
|
|
149
149
|
const source = new GitHubSource({ repo: args.repo, agentLogin: args["agent-login"], client });
|
|
150
|
-
const { triggers, next } = await source.collect(engine.
|
|
150
|
+
const { triggers, next } = await source.collect(engine.sourceState("github"), { exclude: engine.selfPosted() });
|
|
151
151
|
const batch = [];
|
|
152
152
|
for (const t of triggers) {
|
|
153
153
|
// Only inferred candidates reach the (potentially slow, potentially costly) assessment —
|
|
@@ -158,15 +158,15 @@ try {
|
|
|
158
158
|
}
|
|
159
159
|
for (const o of batch)
|
|
160
160
|
console.log(formatOutcome(o));
|
|
161
|
-
const report = engine.ingest(batch, next);
|
|
161
|
+
const report = engine.ingest(batch, { github: next });
|
|
162
162
|
if (batch.length === 0)
|
|
163
163
|
console.log("no new triggers");
|
|
164
164
|
for (const r of report.refusals)
|
|
165
165
|
console.log(`[REFUSED] ${r}`);
|
|
166
|
-
console.log(`— fresh=${report.fresh} duplicates=${report.duplicates} ticketsOpened=${report.ticketsOpened} resumed=${report.resumed} (acceptMode=${policy.acceptMode}, policy v${policy.version}, assess=${args.assessment})`);
|
|
166
|
+
console.log(`— fresh=${report.fresh} duplicates=${report.duplicates} ticketsOpened=${report.ticketsOpened} resumed=${report.resumed} joined=${report.joined} (acceptMode=${policy.acceptMode}, policy v${policy.version}, assess=${args.assessment})`);
|
|
167
167
|
if (args.post) {
|
|
168
168
|
const { drainReplyEffects } = await import("./work.js");
|
|
169
|
-
await drainReplyEffects(engine, client, args.repo);
|
|
169
|
+
await drainReplyEffects(engine, [new GitHubReplyChannel(client, args.repo)]);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
else if (command === "watch") {
|
|
@@ -182,9 +182,44 @@ try {
|
|
|
182
182
|
}
|
|
183
183
|
console.log(`watch: polling ${args.repo} every ${args.interval ?? 30}s (±20% jitter) — Ctrl-C stops after the current cycle`);
|
|
184
184
|
const { runWatch } = await import("./watch.js");
|
|
185
|
+
const sources = [new GitHubSource({ repo: args.repo, agentLogin: args["agent-login"], client })];
|
|
186
|
+
const channels = authenticated ? [new GitHubReplyChannel(client, args.repo)] : [];
|
|
187
|
+
// Feishu (v0.8 M8-2): armed by env — self-built app, WebSocket long connection, no public URL.
|
|
188
|
+
const feishuId = process.env.FEISHU_APP_ID;
|
|
189
|
+
const feishuSecret = process.env.FEISHU_APP_SECRET;
|
|
190
|
+
if (feishuId && feishuSecret) {
|
|
191
|
+
const { FeishuSource, FeishuReplyChannel, createFeishuSender } = await import("./feishu.js");
|
|
192
|
+
sources.push(new FeishuSource({
|
|
193
|
+
appId: feishuId, appSecret: feishuSecret,
|
|
194
|
+
...(process.env.FEISHU_BOT_OPEN_ID ? { botOpenId: process.env.FEISHU_BOT_OPEN_ID } : {}),
|
|
195
|
+
}));
|
|
196
|
+
channels.push(new FeishuReplyChannel(await createFeishuSender(feishuId, feishuSecret)));
|
|
197
|
+
console.log("feishu: long-connection source armed (im.message.receive_v1) — set FEISHU_BOT_OPEN_ID for precise group @mention detection");
|
|
198
|
+
}
|
|
199
|
+
// Slack (v0.8 M8-3): armed by env — Socket Mode, no public URL; bot id via auth.test.
|
|
200
|
+
const slackBot = process.env.SLACK_BOT_TOKEN;
|
|
201
|
+
const slackApp = process.env.SLACK_APP_TOKEN;
|
|
202
|
+
if (slackBot && slackApp) {
|
|
203
|
+
const { SlackSource, SlackReplyChannel, createSlackSender } = await import("./slack.js");
|
|
204
|
+
const { send, botUserId } = await createSlackSender(slackBot);
|
|
205
|
+
sources.push(new SlackSource({ appToken: slackApp, botToken: slackBot, ...(botUserId ? { botUserId } : {}) }));
|
|
206
|
+
channels.push(new SlackReplyChannel(send));
|
|
207
|
+
console.log(`slack: socket-mode source armed${botUserId ? ` (@mention detection for <@${botUserId}>)` : ""}`);
|
|
208
|
+
}
|
|
209
|
+
// WeChat (v0.8 M8-4): armed when `wechat-login` stored credentials in this db.
|
|
210
|
+
{
|
|
211
|
+
const { WechatSource, WechatReplyChannel, WechatApiClient, EngineWechatStore } = await import("./wechat.js");
|
|
212
|
+
const wechatStore = new EngineWechatStore(engine);
|
|
213
|
+
if (wechatStore.loadAuth()) {
|
|
214
|
+
sources.push(new WechatSource({ store: wechatStore, log: (l) => console.log(l) }));
|
|
215
|
+
channels.push(new WechatReplyChannel(wechatStore, (auth) => new WechatApiClient({ token: auth.token, baseUrl: auth.baseUrl }), (l) => console.log(l)));
|
|
216
|
+
console.log("wechat: iLink long-poll source armed (DMs addressed; groups fail closed)");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
185
219
|
await runWatch({
|
|
186
220
|
engine,
|
|
187
|
-
|
|
221
|
+
sources,
|
|
222
|
+
channels,
|
|
188
223
|
executor: new Executor(execCfg),
|
|
189
224
|
client: authenticated ? client : null,
|
|
190
225
|
repo: args.repo,
|
|
@@ -222,7 +257,8 @@ try {
|
|
|
222
257
|
else {
|
|
223
258
|
for (const t of rows) {
|
|
224
259
|
const extra = [t.state === "ended" && t.stoppedBy ? `stopped-by:${t.stoppedBy}` : "",
|
|
225
|
-
t.revokedReason ?? "", t.resumedCount ? `resumed×${t.resumedCount}` : ""
|
|
260
|
+
t.revokedReason ?? "", t.resumedCount ? `resumed×${t.resumedCount}` : "",
|
|
261
|
+
t.followUps ? `fu×${t.followUps}` : ""].filter(Boolean).join(" ");
|
|
226
262
|
console.log(`#${t.id} [${t.stage}] ${t.strength} ${t.threadId} opener=${t.opener} ${extra}`.trimEnd());
|
|
227
263
|
}
|
|
228
264
|
}
|
|
@@ -240,6 +276,23 @@ try {
|
|
|
240
276
|
process.on("SIGTERM", shutdown);
|
|
241
277
|
await new Promise(() => { }); // serve until signal — the finally-close must not run
|
|
242
278
|
}
|
|
279
|
+
else if (command === "wechat-login") {
|
|
280
|
+
// iLink Bot Protocol QR login (v0.8 M8-4): the human scans with their WeChat app.
|
|
281
|
+
const { wechatLogin, EngineWechatStore } = await import("./wechat.js");
|
|
282
|
+
const store = new EngineWechatStore(engine);
|
|
283
|
+
const creds = await wechatLogin((qr) => {
|
|
284
|
+
if (qr.imgBase64) {
|
|
285
|
+
const file = `${process.cwd()}/wechat-login-qr.png`;
|
|
286
|
+
writeFileSync(file, Buffer.from(qr.imgBase64, "base64"));
|
|
287
|
+
console.log(`[wechat] QR image saved to ${file} — scan it with WeChat, then confirm on your phone`);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
console.log(`[wechat] no image payload from the server (qrcode id ${qr.qrcode})`);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
store.saveAuth(creds);
|
|
294
|
+
console.log("[wechat] logged in — credentials stored; the watch daemon (same --db) arms the source automatically");
|
|
295
|
+
}
|
|
243
296
|
else if (command === "merge") {
|
|
244
297
|
// One-shot version of the watch cycle's auto-merge sweep (cron-friendly).
|
|
245
298
|
if (!args.repo)
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/domain.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface Actor {
|
|
|
8
8
|
export interface Trigger {
|
|
9
9
|
/** Source-scoped unique id; accepting twice yields one Ticket. */
|
|
10
10
|
id: string;
|
|
11
|
-
source: "github";
|
|
11
|
+
source: "github" | "feishu" | "slack" | "wechat";
|
|
12
12
|
/** Receiving scope — the admission table's row key. */
|
|
13
13
|
scope: Scope;
|
|
14
14
|
/** Triggers of one conversation, as defined by the Source (e.g. `github:owner/repo/issues/42`). */
|
|
@@ -20,7 +20,11 @@ export interface Trigger {
|
|
|
20
20
|
/** UTC ISO8601. */
|
|
21
21
|
ts: string;
|
|
22
22
|
}
|
|
23
|
-
export type Scope = "issue" | "issue_comment" | "pr" | "pr_comment" | "review_comment" | "ci"
|
|
23
|
+
export type Scope = "issue" | "issue_comment" | "pr" | "pr_comment" | "review_comment" | "ci"
|
|
24
|
+
/** IM direct message (WeChat/Feishu/Slack DM) — shared row for all IM sources. */
|
|
25
|
+
| "im_dm"
|
|
26
|
+
/** IM group chat / channel message — shared row for all IM sources. */
|
|
27
|
+
| "im_group";
|
|
24
28
|
/** Strength of an admitted Trigger. Explicit works in every accept mode; inferred is mode-gated. */
|
|
25
29
|
export type Strength = "explicit" | "inferred";
|
|
26
30
|
/** Progressive-trust ladder for inferred requests. Start in observe; switch to auto after reviewing records. */
|
|
@@ -68,6 +72,9 @@ export interface MergePolicy {
|
|
|
68
72
|
method: "squash" | "merge" | "rebase";
|
|
69
73
|
/** Delete the `dsh/ticket-N` branch after a successful merge. */
|
|
70
74
|
deleteBranch: boolean;
|
|
75
|
+
/** v0.7-2: hold while the head commit has no CI, failing CI, or CI still running. Default off —
|
|
76
|
+
* a repo without checks would otherwise never merge. */
|
|
77
|
+
requireCi: boolean;
|
|
71
78
|
}
|
|
72
79
|
export declare function defaultMergePolicy(): MergePolicy;
|
|
73
80
|
/** Policy.merge is partial in the config file; fill the rest from defaults. */
|
package/dist/domain.js
CHANGED
package/dist/domain.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../src/domain.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,wGAAwG;
|
|
1
|
+
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../src/domain.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,wGAAwG;AA+FxG,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,OAAO,EAAE,KAAK;QACd,2BAA2B,EAAE,IAAI;QACjC,eAAe,EAAE,GAAG;QACpB,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,EAAE,GAAG,kBAAkB,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,CAAC;AACnH,CAAC"}
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Database from "better-sqlite3";
|
|
2
2
|
import type { Policy, Strength, Trigger } from "./domain.js";
|
|
3
3
|
import type { GateResult, Resolution } from "./gate.js";
|
|
4
|
-
import type { SourceState } from "./
|
|
4
|
+
import type { SourceState } from "./source.js";
|
|
5
5
|
export interface IngestItem {
|
|
6
6
|
trigger: Trigger;
|
|
7
7
|
gate: GateResult;
|
|
@@ -12,6 +12,8 @@ export interface IngestReport {
|
|
|
12
12
|
duplicates: number;
|
|
13
13
|
ticketsOpened: number;
|
|
14
14
|
resumed: number;
|
|
15
|
+
/** Subscription bypass: follow-ups that joined an open ticket instead of spawning one (v0.7-1). */
|
|
16
|
+
joined: number;
|
|
15
17
|
refusals: string[];
|
|
16
18
|
}
|
|
17
19
|
export interface TicketView {
|
|
@@ -27,6 +29,8 @@ export interface TicketView {
|
|
|
27
29
|
stoppedBy?: string;
|
|
28
30
|
revokedReason?: string;
|
|
29
31
|
resumedCount: number;
|
|
32
|
+
/** Subscription-bypass follow-ups joined into this ticket's context. */
|
|
33
|
+
followUps: number;
|
|
30
34
|
createdAt: string;
|
|
31
35
|
}
|
|
32
36
|
export interface EffectRow {
|
|
@@ -73,18 +77,25 @@ export declare class Engine {
|
|
|
73
77
|
/** Panel command acting directly: switch acceptMode, versioned. */
|
|
74
78
|
setAcceptMode(mode: Policy["acceptMode"]): Policy | undefined;
|
|
75
79
|
policy(): Policy | undefined;
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
/** Generic kv for channel state (wechat credentials/cursor/routes — v0.8). */
|
|
81
|
+
kvGet(key: string): string | null;
|
|
82
|
+
kvSet(key: string, value: string): void;
|
|
83
|
+
kvDelete(key: string): void;
|
|
84
|
+
/** Per-source read state (v0.8): each Source's positions live under `positions:<kind>`;
|
|
85
|
+
* v0.7 databases kept one unnamed blob — that was GitHub's, so it migrates on first read. */
|
|
86
|
+
sourceState(source: string): SourceState;
|
|
87
|
+
/** Message keys the agent itself posted ("<source>:<externalId>") — never re-ingested (self-echo). */
|
|
78
88
|
selfPosted(): Set<string>;
|
|
79
|
-
markSelfPosted(
|
|
80
|
-
ingest(batch: IngestItem[],
|
|
89
|
+
markSelfPosted(key: string): void;
|
|
90
|
+
ingest(batch: IngestItem[], nextBySource?: Record<string, SourceState>): IngestReport;
|
|
81
91
|
/** Revalidation before resume (docs/002): inferred additionally requires auto; an
|
|
82
92
|
* allowed-list-based basis additionally requires the author to still be listed. */
|
|
83
93
|
private revalidateFailReason;
|
|
84
94
|
/** A person's stop withdraws the Mandate and ends the Ticket. */
|
|
85
95
|
stopTicket(id: number, byLogin: string): boolean;
|
|
86
96
|
/** Open tickets claimable by work: never assigned, or last assignment ended cleanly
|
|
87
|
-
*
|
|
97
|
+
* (a resumed ticket is re-claimable; a failed one waits for a person). The body is the
|
|
98
|
+
* accumulated context: original request + subscription-bypass follow-ups in order. */
|
|
88
99
|
claimQueued(limit: number): {
|
|
89
100
|
id: number;
|
|
90
101
|
threadId: string;
|
package/dist/engine.js
CHANGED
|
@@ -79,6 +79,15 @@ CREATE TABLE IF NOT EXISTS delivery (
|
|
|
79
79
|
UNIQUE(repo, pr_number)
|
|
80
80
|
);
|
|
81
81
|
CREATE INDEX IF NOT EXISTS idx_delivery_state ON delivery(state);
|
|
82
|
+
|
|
83
|
+
CREATE TABLE IF NOT EXISTS ticket_followup (
|
|
84
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
85
|
+
ticket_id INTEGER NOT NULL REFERENCES ticket(id),
|
|
86
|
+
trigger_id TEXT NOT NULL REFERENCES trigger(id),
|
|
87
|
+
ts TEXT NOT NULL,
|
|
88
|
+
UNIQUE(ticket_id, trigger_id)
|
|
89
|
+
);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_followup_ticket ON ticket_followup(ticket_id);
|
|
82
91
|
`;
|
|
83
92
|
const MAX_EFFECT_ATTEMPTS = 5;
|
|
84
93
|
const BACKOFF_BASE_MS = 5_000;
|
|
@@ -122,27 +131,42 @@ export class Engine {
|
|
|
122
131
|
const row = this.db.prepare("SELECT v FROM kv WHERE k = 'policy'").get();
|
|
123
132
|
return row ? JSON.parse(row.v) : undefined;
|
|
124
133
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
return
|
|
134
|
+
/** Generic kv for channel state (wechat credentials/cursor/routes — v0.8). */
|
|
135
|
+
kvGet(key) {
|
|
136
|
+
const row = this.db.prepare("SELECT v FROM kv WHERE k = ?").get(key);
|
|
137
|
+
return row?.v ?? null;
|
|
129
138
|
}
|
|
130
|
-
|
|
139
|
+
kvSet(key, value) {
|
|
140
|
+
this.db.prepare("INSERT INTO kv (k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v").run(key, value);
|
|
141
|
+
}
|
|
142
|
+
kvDelete(key) {
|
|
143
|
+
this.db.prepare("DELETE FROM kv WHERE k = ?").run(key);
|
|
144
|
+
}
|
|
145
|
+
/** Per-source read state (v0.8): each Source's positions live under `positions:<kind>`;
|
|
146
|
+
* v0.7 databases kept one unnamed blob — that was GitHub's, so it migrates on first read. */
|
|
147
|
+
sourceState(source) {
|
|
148
|
+
let row = this.db.prepare("SELECT v FROM kv WHERE k = ?").get(`positions:${source}`);
|
|
149
|
+
if (!row && source === "github") {
|
|
150
|
+
row = this.db.prepare("SELECT v FROM kv WHERE k = 'positions'").get();
|
|
151
|
+
}
|
|
152
|
+
return { positions: row ? JSON.parse(row.v) : {} };
|
|
153
|
+
}
|
|
154
|
+
/** Message keys the agent itself posted ("<source>:<externalId>") — never re-ingested (self-echo). */
|
|
131
155
|
selfPosted() {
|
|
132
156
|
const row = this.db.prepare("SELECT v FROM kv WHERE k = 'self_posted'").get();
|
|
133
157
|
return new Set(row ? JSON.parse(row.v) : []);
|
|
134
158
|
}
|
|
135
|
-
markSelfPosted(
|
|
159
|
+
markSelfPosted(key) {
|
|
136
160
|
const all = this.selfPosted();
|
|
137
|
-
all.add(
|
|
161
|
+
all.add(key);
|
|
138
162
|
this.db
|
|
139
163
|
.prepare("INSERT INTO kv (k, v) VALUES ('self_posted', ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v")
|
|
140
164
|
.run(JSON.stringify([...all]));
|
|
141
165
|
}
|
|
142
166
|
// ── ingest (one transaction: triggers + decisions + tickets + resume + positions) ──
|
|
143
|
-
ingest(batch,
|
|
167
|
+
ingest(batch, nextBySource) {
|
|
144
168
|
const now = new Date().toISOString();
|
|
145
|
-
const report = { fresh: 0, duplicates: 0, ticketsOpened: 0, resumed: 0, refusals: [] };
|
|
169
|
+
const report = { fresh: 0, duplicates: 0, ticketsOpened: 0, resumed: 0, joined: 0, refusals: [] };
|
|
146
170
|
const policy = this.policy();
|
|
147
171
|
const policyVersion = policy?.version ?? 0;
|
|
148
172
|
const insertTrigger = this.db.prepare(`INSERT OR IGNORE INTO trigger
|
|
@@ -158,7 +182,7 @@ export class Engine {
|
|
|
158
182
|
VALUES (?, ?, ?, 'pending', 0, ?, ?, ?)
|
|
159
183
|
ON CONFLICT(kind, key) DO UPDATE SET payload = excluded.payload, status = 'pending',
|
|
160
184
|
attempts = 0, next_due_at = excluded.next_due_at, last_error = NULL, updated_at = excluded.updated_at`);
|
|
161
|
-
const savePositions = this.db.prepare("INSERT INTO kv (k, v) VALUES (
|
|
185
|
+
const savePositions = this.db.prepare("INSERT INTO kv (k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v");
|
|
162
186
|
this.db.transaction(() => {
|
|
163
187
|
for (const item of batch) {
|
|
164
188
|
const t = item.trigger;
|
|
@@ -179,6 +203,18 @@ export class Engine {
|
|
|
179
203
|
const basis = "basis" in item.resolution ? item.resolution.basis : item.gate.basis;
|
|
180
204
|
insertDecision.run(t.id, kind, strength, basis, wouldAccept, policyVersion, now);
|
|
181
205
|
if (item.resolution.action === "accept") {
|
|
206
|
+
// Subscription bypass (v0.7-1, issue #40): a thread with a live ticket fans out to that
|
|
207
|
+
// ticket without re-evaluation — the opener's follow-up joins the ticket's context
|
|
208
|
+
// instead of spawning a duplicate. Same trust as the automatic resume below.
|
|
209
|
+
const open = this.db
|
|
210
|
+
.prepare("SELECT id FROM ticket WHERE thread_id = ? AND opener_login = ? AND state = 'open' ORDER BY id DESC LIMIT 1")
|
|
211
|
+
.get(t.threadId, t.author.login);
|
|
212
|
+
if (open) {
|
|
213
|
+
this.db.prepare("INSERT INTO ticket_followup (ticket_id, trigger_id, ts) VALUES (?, ?, ?)").run(open.id, t.id, now);
|
|
214
|
+
this.db.prepare("UPDATE ticket SET updated_at = ? WHERE id = ?").run(now, open.id);
|
|
215
|
+
report.joined++;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
182
218
|
// An admitted message from an opener with an ended ticket on this thread goes to that
|
|
183
219
|
// ticket (docs/002: "Ended Tickets keep Mandates; a person's message on their own
|
|
184
220
|
// Threads resumes them"); a revoked mandate takes none of its waiting messages;
|
|
@@ -196,6 +232,9 @@ export class Engine {
|
|
|
196
232
|
this.db
|
|
197
233
|
.prepare("UPDATE ticket SET state = 'open', resumed_count = resumed_count + 1, updated_at = ? WHERE id = ?")
|
|
198
234
|
.run(now, ended.id);
|
|
235
|
+
// The resuming message is context too (v0.7-1): without this, the re-claim would
|
|
236
|
+
// only ever show the worker the original request.
|
|
237
|
+
this.db.prepare("INSERT INTO ticket_followup (ticket_id, trigger_id, ts) VALUES (?, ?, ?)").run(ended.id, t.id, now);
|
|
199
238
|
report.resumed++;
|
|
200
239
|
enqueue.run("reply", `ticket-resume:${ended.id}:${Number(ended.resumed_count) + 1}`, JSON.stringify(replyPayload(t, Number(ended.id), "resumed", ended.strength)), now, now, now);
|
|
201
240
|
}
|
|
@@ -211,8 +250,9 @@ export class Engine {
|
|
|
211
250
|
}
|
|
212
251
|
}
|
|
213
252
|
}
|
|
214
|
-
|
|
215
|
-
savePositions.run(JSON.stringify(
|
|
253
|
+
for (const [kind, st] of Object.entries(nextBySource ?? {})) {
|
|
254
|
+
savePositions.run(`positions:${kind}`, JSON.stringify(st.positions));
|
|
255
|
+
}
|
|
216
256
|
})();
|
|
217
257
|
return report;
|
|
218
258
|
}
|
|
@@ -241,7 +281,8 @@ export class Engine {
|
|
|
241
281
|
}
|
|
242
282
|
// ── assignments (docs/001: the binding of a Ticket to one Executor instance) ──
|
|
243
283
|
/** Open tickets claimable by work: never assigned, or last assignment ended cleanly
|
|
244
|
-
*
|
|
284
|
+
* (a resumed ticket is re-claimable; a failed one waits for a person). The body is the
|
|
285
|
+
* accumulated context: original request + subscription-bypass follow-ups in order. */
|
|
245
286
|
claimQueued(limit) {
|
|
246
287
|
const rows = this.db.prepare(`
|
|
247
288
|
SELECT t.id, t.thread_id, tr.body, tr.author_login
|
|
@@ -250,10 +291,18 @@ export class Engine {
|
|
|
250
291
|
AND la.id = (SELECT MAX(b.id) FROM assignment b WHERE b.ticket_id = t.id)
|
|
251
292
|
WHERE t.state = 'open' AND (la.id IS NULL OR (la.state = 'ended' AND la.exit_code = 0))
|
|
252
293
|
ORDER BY t.id LIMIT ?`).all(limit);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
294
|
+
const followupsOf = this.db.prepare(`
|
|
295
|
+
SELECT tr.body, tr.author_login, f.ts FROM ticket_followup f
|
|
296
|
+
JOIN trigger tr ON tr.id = f.trigger_id WHERE f.ticket_id = ? ORDER BY f.id`);
|
|
297
|
+
return rows.map((r) => {
|
|
298
|
+
const id = Number(r.id);
|
|
299
|
+
const extra = followupsOf.all(id).map((f) => `--- follow-up ${String(f.ts)} by @${String(f.author_login)} ---\n${String(f.body).slice(0, 2000)}`);
|
|
300
|
+
return {
|
|
301
|
+
id, threadId: String(r.thread_id),
|
|
302
|
+
body: [String(r.body), ...extra].join("\n\n").slice(0, 12_000),
|
|
303
|
+
author: String(r.author_login),
|
|
304
|
+
};
|
|
305
|
+
});
|
|
257
306
|
}
|
|
258
307
|
startAssignment(ticketId, worktree) {
|
|
259
308
|
const r = this.db
|
|
@@ -276,12 +325,11 @@ export class Engine {
|
|
|
276
325
|
/** Public reply enqueue for adapters acting after commit (work reports, notices). */
|
|
277
326
|
enqueueReply(key, threadId, body) {
|
|
278
327
|
const now = new Date().toISOString();
|
|
279
|
-
const n = threadId.match(/\/(issues|pulls)\/(\d+)$/);
|
|
280
328
|
this.db.prepare(`INSERT INTO effect (kind, key, payload, status, attempts, next_due_at, created_at, updated_at)
|
|
281
329
|
VALUES ('reply', ?, ?, 'pending', 0, ?, ?, ?)
|
|
282
330
|
ON CONFLICT(kind, key) DO UPDATE SET payload = excluded.payload, status = 'pending',
|
|
283
331
|
attempts = 0, next_due_at = excluded.next_due_at, last_error = NULL, updated_at = excluded.updated_at`)
|
|
284
|
-
.run(key, JSON.stringify({ threadId,
|
|
332
|
+
.run(key, JSON.stringify({ threadId, body }), now, now, now);
|
|
285
333
|
}
|
|
286
334
|
// ── deliveries (M6-1: PRs the agent opened — the auto-merge sweep's work list) ──
|
|
287
335
|
/** Record (or re-open on re-delivery) the PR opened for a ticket. */
|
|
@@ -338,6 +386,10 @@ export class Engine {
|
|
|
338
386
|
for (const a of this.db.prepare("SELECT ticket_id, state, exit_code FROM assignment ORDER BY id").all()) {
|
|
339
387
|
lastAssignment.set(Number(a.ticket_id), { state: String(a.state), exitCode: a.exit_code === null ? null : Number(a.exit_code) });
|
|
340
388
|
}
|
|
389
|
+
const followUps = new Map();
|
|
390
|
+
for (const f of this.db.prepare("SELECT ticket_id, COUNT(*) c FROM ticket_followup GROUP BY ticket_id").all()) {
|
|
391
|
+
followUps.set(Number(f.ticket_id), Number(f.c));
|
|
392
|
+
}
|
|
341
393
|
return rows.map((r) => {
|
|
342
394
|
const id = Number(r.id);
|
|
343
395
|
const state = r.state;
|
|
@@ -360,6 +412,7 @@ export class Engine {
|
|
|
360
412
|
...(r.stopped_by !== null ? { stoppedBy: String(r.stopped_by) } : {}),
|
|
361
413
|
...(r.revoked_reason !== null ? { revokedReason: String(r.revoked_reason) } : {}),
|
|
362
414
|
resumedCount: Number(r.resumed_count),
|
|
415
|
+
followUps: followUps.get(id) ?? 0,
|
|
363
416
|
createdAt: String(r.created_at),
|
|
364
417
|
};
|
|
365
418
|
});
|