fix(feedback): keep payload in feedback event
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/plan/plan-mode/README.md
|
||||
README.md: d3c2c14fe616e1c9b4e33b716570b084db6474cf
|
||||
README.zh.md: 6d6878c4b0300a716ad16be60fd86bc79f1514ba
|
||||
README.md: e3a98115d2d9f14fa0bb46e4d867f6b79cbf269d
|
||||
README.zh.md: f8481cff12992e83af39498908c5ca2624a4f974
|
||||
|
||||
@@ -20,7 +20,7 @@ The TUI consumes the plugin-owned `/plan` command; other front doors may drive t
|
||||
|
||||
## Session projection
|
||||
|
||||
When the composition mounts `ctx.sessionProjections` ([`@deepseek-ai/dsh-session-projection`](../../session-projection/session-projection/README.md)), this package registers the `plan` projection unit under an injected child. The unit folds two event kinds: a `command/run` record named `plan` sets the wanted target (`off` → inactive, anything else → active), and `plan/mode` commits the logged state and clears it; every other event returns the same state reference. `view` derives `{ active, pending }`, where `pending` is true only while an outstanding selection differs from the logged state — a pure replay quantity, so host restarts, other tabs, and cold reads all recover it from the log alone (the `/plan` handler calls `set()` before any failing path, keeping the logged request and the run plane from forking). The key merges into `SessionProjectionMap` from `src/types.ts` (served to host consumers via `./types` and client aggregates via `./client`); the framework drives the unit and carriers serve the value on the history tail page and the `session/projection` push frame. Compositions without the registry are unaffected.
|
||||
When the composition mounts `ctx.sessionProjections` ([`@deepseek-ai/dsh-session-projection`](../../session-projection/session-projection/README.md)), this package registers the `plan` projection unit under an injected child. The unit folds two event kinds: a `command/run` record named `plan` with recorded `args` sets the wanted target (`off` → inactive, anything else → active), and `plan/mode` commits the logged state and clears it; every other event returns the same state reference. `view` derives `{ active, pending }`, where `pending` is true only while an outstanding selection differs from the logged state — a pure replay quantity, so host restarts, other tabs, and cold reads all recover it from the log alone (the `/plan` handler calls `set()` before any failing path, keeping the logged request and the run plane from forking). The key merges into `SessionProjectionMap` from `src/types.ts` (served to host consumers via `./types` and client aggregates via `./client`); the framework drives the unit and carriers serve the value on the history tail page and the `session/projection` push frame. Compositions without the registry are unaffected.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ TUI 消费插件拥有的 `/plan` 命令;其他入口可以直接驱动同一
|
||||
|
||||
## 会话投影
|
||||
|
||||
当组合挂载 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session-projection/session-projection/README.md))时,本包在注入子插件下注册 `plan` 投影单元。该单元折叠两种事件:名为 `plan` 的 `command/run` 记录设置目标值(`off` → 未激活,其余 → 激活),`plan/mode` 提交已记录状态并将其清除;其他任何事件返回同一状态引用。`view` 推导 `{ active, pending }`,其中 `pending` 仅在未兑现的选择不同于已记录状态时为 true——它是纯回放量,host 重启、其他标签页与冷读都只凭日志即可恢复(`/plan` 处理器在任何可能失败的路径之前调用 `set()`,使已入日志的请求与运行面不可能分叉)。key 从 `src/types.ts` merge 进 `SessionProjectionMap`(host 消费方经 `./types`、client 聚合经 `./client`);框架驱动单元,载体在历史尾页与 `session/projection` 推送帧上提供该值。未挂注册表的组合不受影响。
|
||||
当组合挂载 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session-projection/session-projection/README.md))时,本包在注入子插件下注册 `plan` 投影单元。该单元折叠两种事件:名为 `plan` 且带有已记录 `args` 的 `command/run` 记录设置目标值(`off` → 未激活,其余 → 激活),`plan/mode` 提交已记录状态并将其清除;其他任何事件返回同一状态引用。`view` 推导 `{ active, pending }`,其中 `pending` 仅在未兑现的选择不同于已记录状态时为 true——它是纯回放量,host 重启、其他标签页与冷读都只凭日志即可恢复(`/plan` 处理器在任何可能失败的路径之前调用 `set()`,使已入日志的请求与运行面不可能分叉)。key 从 `src/types.ts` merge 进 `SessionProjectionMap`(host 消费方经 `./types`、client 聚合经 `./client`);框架驱动单元,载体在历史尾页与 `session/projection` 推送帧上提供该值。未挂注册表的组合不受影响。
|
||||
|
||||
## 配置
|
||||
|
||||
|
||||
@@ -234,6 +234,7 @@ export class PlanModeService extends Service {
|
||||
init: () => ({ active: false, wanted: null }),
|
||||
apply: (state, event) => {
|
||||
if (event.type === 'command/run' && event.data.name === 'plan') {
|
||||
if (event.data.args === undefined) return state
|
||||
const wanted = event.data.args.trim() !== 'off'
|
||||
return wanted === state.wanted ? state : { active: state.active, wanted }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* The `plan` projection unit (session-projection RFC's complete example): a
|
||||
* double-event fold over the session log. `command/run` records named `plan`
|
||||
* set the wanted target (`off` → false, anything else → true); `plan/mode`
|
||||
* commits and clears it; `view` derives `{ active, pending }` where pending
|
||||
* is true only while an outstanding selection differs from the logged state.
|
||||
* with recorded input set the wanted target (`off` → false, anything else
|
||||
* → true); `plan/mode` commits and clears it. `view` reports pending only
|
||||
* while an outstanding selection differs from the logged state.
|
||||
* Pending is thereby a pure replay quantity — a cold fold answers it without
|
||||
* the service's in-memory intent. Composition without plan-mode has no `plan`
|
||||
* key; unloading the fiber removes it (HMR safety).
|
||||
@@ -88,6 +88,11 @@ describe('plan projection unit', () => {
|
||||
commandId: CommandId('other-1'), name: 'compact', args: '', source: { kind: 'user' },
|
||||
})
|
||||
expect(bench.values().plan).toEqual({ active: true, pending: false })
|
||||
// A command lifecycle with omitted input carries no plan selection.
|
||||
bench.session.append('command/run', {
|
||||
commandId: CommandId('plan-no-input'), name: 'plan', source: { kind: 'user' },
|
||||
})
|
||||
expect(bench.values().plan).toEqual({ active: true, pending: false })
|
||||
runPlanCommand(bench.session, ' off', 1)
|
||||
expect(bench.values().plan).toEqual({ active: true, pending: true })
|
||||
commitPlanMode(bench.session, false, 1)
|
||||
|
||||
Reference in New Issue
Block a user