@margay/ccl-core 1.5.1-alpha.3 → 1.5.1-alpha.4
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/dist/cli.js +2153 -1812
- package/dist/sdk/background.d.ts +14 -0
- package/dist/sdk/background.js +3 -1
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/scheduledNotificationTypes.d.ts +53 -0
- package/dist/sdk/scheduledNotificationTypes.js +18 -0
- package/docs/background-runs.md +46 -2
- package/docs/releases/1.5.1-alpha.4.md +27 -0
- package/package.json +3 -2
- package/sdk/API.md +7 -0
package/dist/sdk/background.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BackgroundRun, BackgroundRunAction, BackgroundRunApproval, BackgroundRunEvents, BackgroundRunLookup, BackgroundRunSelector, BackgroundRunSpec, BackgroundRunSource } from './backgroundRunTypes.js';
|
|
2
2
|
import type { OccurrenceCancelRequest, OccurrenceApprovalRequest, OccurrenceApprovalReceipt, OccurrenceLookup, OccurrenceEvents, ScheduledOccurrence } from './scheduledOccurrenceTypes.js';
|
|
3
|
+
import type { ScheduledNotificationSelector, ScheduledNotificationRebind, ScheduledNotificationBindingLookup } from './scheduledNotificationTypes.js';
|
|
3
4
|
export type BackgroundClientOptions = {
|
|
4
5
|
cwd: string;
|
|
5
6
|
cliPath: string;
|
|
@@ -19,6 +20,19 @@ export declare class BackgroundClientError extends Error {
|
|
|
19
20
|
/** Durable runs do not retain JS callbacks or in-process SDK MCP servers. Use
|
|
20
21
|
* persistent stdio/HTTP tools configured through launch instead. */
|
|
21
22
|
export declare function createBackgroundClient(options: BackgroundClientOptions): {
|
|
23
|
+
getScheduledNotificationBinding: (selector: ScheduledNotificationSelector) => Promise<ScheduledNotificationBindingLookup>;
|
|
24
|
+
rebindScheduledNotifications: (request: ScheduledNotificationRebind) => Promise<{
|
|
25
|
+
selector: {
|
|
26
|
+
taskId: string;
|
|
27
|
+
taskCreatedAt: number;
|
|
28
|
+
} | {
|
|
29
|
+
occurrenceId: string;
|
|
30
|
+
};
|
|
31
|
+
sessionId: string;
|
|
32
|
+
revision: number;
|
|
33
|
+
generation: string;
|
|
34
|
+
updatedAt: number;
|
|
35
|
+
}>;
|
|
22
36
|
getOccurrence: (request: {
|
|
23
37
|
occurrenceId: string;
|
|
24
38
|
}) => Promise<OccurrenceLookup>;
|
package/dist/sdk/background.js
CHANGED
|
@@ -18,7 +18,7 @@ export function createBackgroundClient(options) {
|
|
|
18
18
|
// Serialization can throw (for example for a cyclic input); do it before
|
|
19
19
|
// allocating a subprocess that would otherwise wait forever for stdin.
|
|
20
20
|
const input = JSON.stringify(request);
|
|
21
|
-
const retryAdvice = command.includes('occurrence') ? 'Read the original occurrence and approvalDecisions. Retry approval only with the same actionId and payload.' : 'Query the original requestKey; do not submit a new key.';
|
|
21
|
+
const retryAdvice = command.includes('notification') ? 'Read the original notification binding. Retry a binding mutation only with the same actionId and payload.' : command.includes('occurrence') ? 'Read the original occurrence and approvalDecisions. Retry approval only with the same actionId and payload.' : 'Query the original requestKey; do not submit a new key.';
|
|
22
22
|
return new Promise((resolve, reject) => {
|
|
23
23
|
const child = spawn(options.execPath ?? process.execPath, [options.cliPath, 'daemon', command, '--cwd', options.cwd, '--request-stdin'], {
|
|
24
24
|
cwd: options.cwd, env: options.env ?? process.env, stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -73,6 +73,8 @@ export function createBackgroundClient(options) {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
return {
|
|
76
|
+
getScheduledNotificationBinding: (selector) => invoke('get-scheduled-notification-binding', { selector }),
|
|
77
|
+
rebindScheduledNotifications: (request) => invoke('rebind-scheduled-notifications', request),
|
|
76
78
|
getOccurrence: (request) => invoke('get-occurrence', request),
|
|
77
79
|
listOccurrences: (request = {}) => invoke('list-occurrences', request),
|
|
78
80
|
readOccurrenceEvents: (request) => invoke('occurrence-events', request),
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export type { GatewayRequestPhase, GatewayRequestProgress } from './requestProgr
|
|
|
21
21
|
export type { AccumulatedUsage, CanUseToolContext, CanUseToolFn, CanUseToolResult, InitializationResult, LifecycleHooks, PendingApproval, PendingDecision, ProviderConfig, Query, QueryOptions, SDKEvent, SDKUserMessage, SessionStore, SessionLifecycleEvent, Transport, Usage, WireMessage, } from './types.js';
|
|
22
22
|
export { getExecutionGuidance } from './executionGuidance.js';
|
|
23
23
|
export { createBackgroundClient, BackgroundClientError, type BackgroundClientOptions } from './background.js';
|
|
24
|
+
export type { ScheduledNotificationSelector, ScheduledNotificationRebind, ScheduledNotificationBinding, ScheduledNotificationBindingLookup, EffectiveScheduledNotificationRoute } from './scheduledNotificationTypes.js';
|
|
24
25
|
export type { BackgroundRun, BackgroundRunSpec, BackgroundRunLookup, BackgroundRunSelector, BackgroundRunEvent, BackgroundRunEvents, BackgroundRunAction, BackgroundRunApproval, BackgroundPermission, BackgroundRunSource } from './backgroundRunTypes.js';
|
|
25
26
|
export { runCommandProcess, type CommandProcessInput, type CommandProcessResult } from './commandProcess.js';
|
|
26
27
|
export { createCommandAdapter, type CommandAdapter, type CommandAdapterSpec, type CommandDefinition, type CommandOperation, type CommandOutcome, type CommandExecution, type JsonValue } from './commandAdapter.js';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
export declare const scheduledNotificationSelectorSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
3
|
+
taskId: z.ZodString;
|
|
4
|
+
taskCreatedAt: z.ZodNumber;
|
|
5
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
6
|
+
occurrenceId: z.ZodString;
|
|
7
|
+
}, z.core.$strict>]>;
|
|
8
|
+
export type ScheduledNotificationSelector = z.infer<typeof scheduledNotificationSelectorSchema>;
|
|
9
|
+
export declare const scheduledNotificationLookupSchema: z.ZodObject<{
|
|
10
|
+
selector: z.ZodUnion<readonly [z.ZodObject<{
|
|
11
|
+
taskId: z.ZodString;
|
|
12
|
+
taskCreatedAt: z.ZodNumber;
|
|
13
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
14
|
+
occurrenceId: z.ZodString;
|
|
15
|
+
}, z.core.$strict>]>;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
export declare const scheduledNotificationRebindSchema: z.ZodObject<{
|
|
18
|
+
selector: z.ZodUnion<readonly [z.ZodObject<{
|
|
19
|
+
taskId: z.ZodString;
|
|
20
|
+
taskCreatedAt: z.ZodNumber;
|
|
21
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
22
|
+
occurrenceId: z.ZodString;
|
|
23
|
+
}, z.core.$strict>]>;
|
|
24
|
+
targetSessionId: z.ZodString;
|
|
25
|
+
expectedRevision: z.ZodNumber;
|
|
26
|
+
actionId: z.ZodString;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
export type ScheduledNotificationRebind = z.infer<typeof scheduledNotificationRebindSchema>;
|
|
29
|
+
export declare const scheduledNotificationBindingSchema: z.ZodObject<{
|
|
30
|
+
selector: z.ZodUnion<readonly [z.ZodObject<{
|
|
31
|
+
taskId: z.ZodString;
|
|
32
|
+
taskCreatedAt: z.ZodNumber;
|
|
33
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
34
|
+
occurrenceId: z.ZodString;
|
|
35
|
+
}, z.core.$strict>]>;
|
|
36
|
+
sessionId: z.ZodString;
|
|
37
|
+
revision: z.ZodNumber;
|
|
38
|
+
generation: z.ZodString;
|
|
39
|
+
updatedAt: z.ZodNumber;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
export type ScheduledNotificationBinding = z.infer<typeof scheduledNotificationBindingSchema>;
|
|
42
|
+
export type EffectiveScheduledNotificationRoute = {
|
|
43
|
+
sessionId: string | null;
|
|
44
|
+
source: 'occurrence' | 'task' | 'delegation' | 'unbound';
|
|
45
|
+
binding?: ScheduledNotificationBinding;
|
|
46
|
+
};
|
|
47
|
+
export type ScheduledNotificationBindingLookup = {
|
|
48
|
+
selector: ScheduledNotificationSelector;
|
|
49
|
+
revision: number;
|
|
50
|
+
binding: ScheduledNotificationBinding | null;
|
|
51
|
+
/** For occurrence selectors, includes inherited task routing. */
|
|
52
|
+
effective?: EffectiveScheduledNotificationRoute;
|
|
53
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
export const scheduledNotificationSelectorSchema = z.union([
|
|
3
|
+
z.strictObject({ taskId: z.string().min(1), taskCreatedAt: z.number().int().nonnegative() }),
|
|
4
|
+
z.strictObject({ occurrenceId: z.string().regex(/^[a-f0-9]{64}$/) }),
|
|
5
|
+
]);
|
|
6
|
+
export const scheduledNotificationLookupSchema = z.strictObject({ selector: scheduledNotificationSelectorSchema });
|
|
7
|
+
export const scheduledNotificationRebindSchema = scheduledNotificationLookupSchema.extend({
|
|
8
|
+
targetSessionId: z.string().min(1).max(200),
|
|
9
|
+
expectedRevision: z.number().int().nonnegative(),
|
|
10
|
+
actionId: z.string().min(1).max(200),
|
|
11
|
+
});
|
|
12
|
+
export const scheduledNotificationBindingSchema = z.strictObject({
|
|
13
|
+
selector: scheduledNotificationSelectorSchema,
|
|
14
|
+
sessionId: z.string().min(1).max(200),
|
|
15
|
+
revision: z.number().int().positive(),
|
|
16
|
+
generation: z.string().uuid(),
|
|
17
|
+
updatedAt: z.number().int().nonnegative(),
|
|
18
|
+
});
|
package/docs/background-runs.md
CHANGED
|
@@ -93,6 +93,24 @@ await background.cancelRun({ runId, expectedRevision, actionId: 'cancel-1' })
|
|
|
93
93
|
|
|
94
94
|
`ccl daemon submit|get|events|cancel-run|approve-run --request-stdin --cwd PROJECT` 从 stdin 接收 JSON。submit 可启动缺失的兼容 daemon;读取不会启动进程。旧活 owner 配置不匹配时明确拒绝,不暗中替换。daemon stop 停调度;取消某一 run 使用 cancel-run。
|
|
95
95
|
|
|
96
|
+
### 安装升级与已有定时任务
|
|
97
|
+
|
|
98
|
+
安装新包不会重启正在运行的 daemon。`ccl daemon status --cwd PROJECT`、`scheduledStatus` 和 `CronList` 的 background 结果包含:
|
|
99
|
+
|
|
100
|
+
- `runningCliDigest`:通过活 owner 协议核实的启动时 CLI SHA-256;旧 owner 未保存该字段或没有核实到活 owner 时为 `null`。
|
|
101
|
+
- `installedCliDigest`:执行这次查询的 CLI 文件 SHA-256;读取失败时为 `null`。嵌入 service 的调用者可显式传比较路径。
|
|
102
|
+
- `cliCompatibility`:`match`、`mismatch` 或 `unknown`,另有 `cliCompatibilityReason` 解释不同或未知的原因。
|
|
103
|
+
|
|
104
|
+
`owner.ready` 仍表示已获得调度租约,不等于版本一致或任务已完成。摘要一致只表示 CLI 字节一致,不证明启动配置一致。旧 owner 的 `configId` 不能反推其 CLI 摘要;升级覆盖同一路径后也不能从新文件推断旧进程版本。`CronCreate` 的后台 handoff 结果也带相同的摘要字段。
|
|
105
|
+
|
|
106
|
+
产品启动或巡检可只读查询并提示用户。需要切换时,保留任务 ID、原启动配置及 occurrence 状态,由用户决定时机;明确执行 `ccl daemon stop --cwd PROJECT`,确认旧 owner 已退出、租约已释放,再从原宿主以相同配置对原 taskId 重试 `CronCreate operation:handoff`。采用 CLI start 时也要保留原宿主对应的配置;无条件裸 start 可能使用不同模型/设置,导致下一次 handoff 仍拒绝。不要删除重建排程,也不要循环重试不同配置或自动杀进程。stop 超时先查原 owner 状态,不能把超时当成已停止。
|
|
107
|
+
|
|
108
|
+
已接受的 occurrence 独立于排程定义:删除定义只影响未来触发,旧 occurrence 仍可按原 ID 查询、按明确决定取消;取消不会撤销已经发生的外部效果。新 owner 保留 waiting_permission,running/resuming 的不确定执行按 interrupted 处理,不自动重放。错过时点仍按原 missed/coalesce 规则处理,不意味着所有错过任务都自动补跑。
|
|
109
|
+
|
|
110
|
+
恢复审批必须同时存在原 session 的 confirmed pending 与精确匹配的 suspended 事件。`pendingPermission` 缺失时,新 owner 尝试恢复;失败会保留 `approvalRecoveryError`,不能编造 request/tool ID 批准。alpha.4 的原生 pending 没有新版 confirmed 挂起协议,因此不能承诺它能直接恢复,也不能补写 confirmed 绕过检查。由获授权的项目宿主先查询原 occurrence、核实已有外部效果,再按用户决定保留或使用 `cancel-occurrence`(snapshot.revision + 稳定 actionId)取消;不会自动取消或重新执行整项工作。
|
|
111
|
+
|
|
112
|
+
未显式绑定时,通知仍按原 `delegation.sourceSessionId` 投递。新会话可以使用下面的独立换绑接口;没有 delegation 或已删定义的旧 occurrence 也能绑定。`reauthorize` 只更新未来触发的权限委托,不改变既有 occurrence 或显式通知绑定。
|
|
113
|
+
|
|
96
114
|
| 目的 | SDK | CLI 子命令 | `BackgroundRun` 模型工具 action |
|
|
97
115
|
| --- | --- | --- | --- |
|
|
98
116
|
| 持久接受 | `submitRun` | `submit` | `submit` |
|
|
@@ -217,11 +235,37 @@ CLI 使用 `ccl daemon <子命令> --request-stdin --cwd PROJECT`,stdin 中为
|
|
|
217
235
|
|
|
218
236
|
只读查询不启动 owner,也不消费通知;决定和取消需要兼容的运行 owner。旧 `daemon approve <id> allow` 无精确身份,返回迁移错误。模型工具用 `BackgroundRun` 的 `occurrence_id` 配合 `get/events/approve/cancel`;批准字段为 `expected_revision/request_id/tool_use_id/action_id/decision`,事件使用 `after_sequence`,不用 run 的 opaque `cursor`。模型收到宿主通知不等于用户授权,allow 仍遵循前台权限确认或明确适用策略。
|
|
219
237
|
|
|
238
|
+
### 新会话接收原任务通知
|
|
239
|
+
|
|
240
|
+
换绑只改变通知收件人,不启动 owner,不删除重建任务,也不改变计划、执行状态、worker session、权限或待批身份。CLI/SDK 是受信本机宿主接口,可指定目标 session;模型工具请求确认,并由宿主填入当前 session,模型不能指定其他会话。
|
|
241
|
+
|
|
242
|
+
- 整项排程:在新会话用 `CronList` 读取原任务的 `notificationBinding.revision`,调用 `CronCreate`,输入 `operation: "rebind-notifications"`、原 `taskId`、`bindingRevision` 和稳定 `actionId`。首次 revision 为 0。此入口要求定义仍存在;一次性任务触发后定义可能已移除。
|
|
243
|
+
- 单次发生:使用 `BackgroundRun action:"notification-binding", occurrence_id:原ID` 读取该 occurrence 的绑定 revision,再用 `action:"rebind-notifications"`、相同 `occurrence_id`、`binding_revision`、稳定 `action_id` 换绑。它适用于定义已删或没有 delegation 的旧记录。
|
|
244
|
+
- SDK/CLI 整项选择器为 `{taskId, taskCreatedAt}`;它匹配已有记录和未来触发,防止同 ID 重建任务串收件人。定义已删时可从原 occurrence 的 task 快照取得身份。单次选择器为 `{occurrenceId}`。两种选择器不能混用。
|
|
245
|
+
|
|
246
|
+
```js
|
|
247
|
+
const selector = { occurrenceId: originalOccurrenceId }
|
|
248
|
+
const binding = await background.getScheduledNotificationBinding(selector)
|
|
249
|
+
const request = {
|
|
250
|
+
selector, targetSessionId: newSessionId,
|
|
251
|
+
expectedRevision: binding.revision, actionId: stableActionId,
|
|
252
|
+
}
|
|
253
|
+
const receipt = await background.rebindScheduledNotifications(request)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
对应 CLI 为 `ccl daemon get-scheduled-notification-binding --request-stdin --cwd PROJECT`,stdin 内容 `{ "selector": { "occurrenceId": "原64位ID" } }`;写接口为 `rebind-scheduled-notifications`,另加 `targetSessionId`、`expectedRevision`、`actionId`。读取不创建绑定。确认回执不确定时重试原请求;同一 actionId 同一内容返回原回执,不再次换绑。复用 actionId 改内容报 `action_conflict`;新动作遇到 `stale_binding` 时先读现状,再由宿主决定是否发起新的修改。
|
|
257
|
+
|
|
258
|
+
有效路由优先级是单次 occurrence 显式绑定、task 身份绑定、原 delegation。换绑整项任务不会覆盖单次显式选择。lookup 的 revision 只属于所选绑定,不能把 `effective.binding.revision` 当成另一选择器的 revision。`CronList.background` 和 `daemon status` 显示 task 的绑定 revision、收件 session,以及 occurrence 的有效 route;路由文件损坏时报告 `notificationRoutingError`,不会回退投递给原收件人,owner readiness 和 CLI 摘要仍可查询。修复路由存储前先保留原文件并核实目标,不用删文件来隐式恢复旧路由。
|
|
259
|
+
|
|
260
|
+
显式换绑后只补发最新可通知状态,不回放过期审批历史。稳定通知 UUID 包含绑定代次和当前待批身份/终态;coalesce 或 delivery 更新不重复同一待办,新的 pending 或终态会通知。A→B→A 使用新代次,旧 A 回执不会吞掉新通知。只有实际持久 transcript 消息才算接收回执,入队、get/events 或缓存本身都不算。
|
|
261
|
+
|
|
262
|
+
换绑对尚未被消费者 prepare 接受的通知生效:旧队列项在消费前复核路由和当前状态,不匹配则丢弃重取。已经接受或持久保存的旧通知无法撤回,因此不承诺两个会话在换绑瞬间零重叠。收到通知不授予审批权,批准仍须查询原 occurrence 并使用精确 pending 身份。旧格式无法恢复 pending 时,通知报告恢复错误,不生成虚构批准。
|
|
263
|
+
|
|
220
264
|
### 前端体验与故障恢复
|
|
221
265
|
|
|
222
|
-
- TUI 与持续运行的 SDK/headless
|
|
266
|
+
- TUI 与持续运行的 SDK/headless 主循环:有效绑定会话收到 `scheduled-task` 宿主事件,主助手解释具体待批工具、当前结果或失败。此事件不冒充新的用户指令。SDK 的自主通知结果不绑定到上一条用户输入的 turn UUID。
|
|
223
267
|
- 已退出的一次性 headless:不承诺向已关闭的输出流推送。消费者可通过上述 SDK/CLI 查询和处理结构化 pending;恢复原会话时补收未投递消息。Pepper 等 assistant 负责自己的外部消息渠道及送达回执。
|
|
224
|
-
- 接收者离线、入队失败或入队后尚未写入 transcript:保留通知游标,补投稳定 UUID
|
|
268
|
+
- 接收者离线、入队失败或入队后尚未写入 transcript:保留通知游标,补投稳定 UUID。只有接收会话持久保存的通知消息才算宿主接收回执;get/events 和队列操作记录都不算。已保存不代表模型已解释或 IM 已送达。
|
|
225
269
|
- 同一待批调用跨周期只提示一次,查询及实际消费时显示最新合并次数。投递前、队列消费前重查状态,已经批准、拒绝、取消或结束的旧审批不再提问;历史事件仍可读。状态读取失败不会冒充“已解决”。
|
|
226
270
|
- 等待批准时 owner 重启:保留经确认尚未执行的原调用,可在明确批准后恢复原 session。恢复严格核对工具与完整输入,不因同名工具就套用旧批准。
|
|
227
271
|
- 决定和恢复 intent 已保存后崩溃:重启标记 `interrupted`,不自动再执行。先核查原收据、工具结果及适用的 Operation 恢复契约;宿主不保证任意外部系统 exactly-once。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 1.5.1-alpha.4
|
|
2
|
+
|
|
3
|
+
本预发布版在 [1.5.1-alpha.3](1.5.1-alpha.3.md) 基础上交付 #60 的 daemon 升级状态和独立通知换绑。安装指定版本或使用 `alpha` 标签;`latest` 保持不变。CLI 与 SDK 应使用同版本。
|
|
4
|
+
|
|
5
|
+
## 升级状态与旧记录
|
|
6
|
+
|
|
7
|
+
`daemon status`、`CronList.background` 和 `CronCreate` 的后台返回包含运行/安装 CLI 摘要及 `cliCompatibility: match | mismatch | unknown`。旧 owner 没有启动摘要时明确 unknown;不会把升级后同路径的新文件当成旧进程版本。`owner.ready` 与版本一致性分开。
|
|
8
|
+
|
|
9
|
+
安装不会重启现有 daemon。需要切换时保留原任务身份和启动配置,明确 stop 并确认旧 owner 退出,再从原宿主对原 taskId handoff;不要删除重建排程。stop 导致活动 SDK aborted 时保存 interrupted,重启不自动重放;等待审批记录保留,错过周期按既有 missed/coalesce 契约处理。
|
|
10
|
+
|
|
11
|
+
恢复审批仍要求原 session 的 confirmed pending 和精确请求身份。旧 alpha.4 原生 pending 没有该确认协议时,保留恢复错误,不伪造批准或自动重跑;可查询原 occurrence,并在明确授权下取消。删除定义不删除已接受记录,取消不撤销已发生的外部效果。
|
|
12
|
+
|
|
13
|
+
## 新会话通知换绑
|
|
14
|
+
|
|
15
|
+
SDK `getScheduledNotificationBinding` / `rebindScheduledNotifications` 与同名 kebab-case CLI 子命令支持原 `{taskId, taskCreatedAt}` 或 `{occurrenceId}` 选择器。换绑含 `targetSessionId`、`expectedRevision`(首次 0)、稳定 `actionId`;同动作重试返回原回执,冲突和损坏明确报错。
|
|
16
|
+
|
|
17
|
+
模型工具使用 `CronCreate operation:rebind-notifications` 或 `BackgroundRun action:notification-binding/rebind-notifications`;经过权限确认,收件人固定为宿主当前会话。换绑不启动 owner,不改任务、计划、执行、权限或待批身份。单 occurrence 显式绑定优先于 task,最后才使用原 delegation。已删定义的 occurrence 仍可换绑。
|
|
18
|
+
|
|
19
|
+
REPL 和持续 headless 会话使用共同通知实现。新绑定只投当前待办/结果,以持久 transcript 为回执;代次隔离支持 A→B→A,合并周期不重复同一待办。消费前复核会丢弃旧路由队列项,已经接受的旧通知无法撤回,不承诺换绑瞬间零重叠。通知不是审批,仍需查询原 occurrence 后针对精确 pending 决定。
|
|
20
|
+
|
|
21
|
+
## 验证与兼容边界
|
|
22
|
+
|
|
23
|
+
隔离测试覆盖真实旧 alpha.4 产物切换、现代 pending 原会话恢复、运行任务中止与 missed/coalesce,以及最终候选 CLI/SDK、真实 detached owner、两个持续会话、工具拒绝/允许换绑、真实 transcript 和原精确批准一次执行。确定性 provider 证明接线与生命周期,不证明真实模型自主规划质量;REPL 验证为实际 hook/队列消费,不是整屏视觉验收。
|
|
24
|
+
|
|
25
|
+
独立路由是新增可选存储,未绑定任务沿用原路由。旧运行版本不会理解新绑定,启用此功能后不应混用旧前台消费者或直接降级并期待新路由仍生效。包回退不能撤销已经接受的通知或业务效果,回退前需核实接收方与待执行记录。
|
|
26
|
+
|
|
27
|
+
完整升级顺序、CLI/SDK/工具字段、优先级及失败处理见 [后台任务契约](../background-runs.md) 与 [SDK API](../../sdk/API.md)。本版包含 alpha.3 的 #58/#59 修复,不宣称解决视觉模型准确性问题。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@margay/ccl-core",
|
|
3
|
-
"version": "1.5.1-alpha.
|
|
3
|
+
"version": "1.5.1-alpha.4",
|
|
4
4
|
"description": "Core runtime extracted from Claude Code (ccl) for Margay integration",
|
|
5
5
|
"license": "SEE LICENSE IN README.md",
|
|
6
6
|
"type": "module",
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"docs/releases/1.5.1-alpha.md",
|
|
56
56
|
"docs/releases/1.5.1-alpha.1.md",
|
|
57
57
|
"docs/releases/1.5.1-alpha.2.md",
|
|
58
|
-
"docs/releases/1.5.1-alpha.3.md"
|
|
58
|
+
"docs/releases/1.5.1-alpha.3.md",
|
|
59
|
+
"docs/releases/1.5.1-alpha.4.md"
|
|
59
60
|
],
|
|
60
61
|
"engines": {
|
|
61
62
|
"node": ">=22.19.0"
|
package/sdk/API.md
CHANGED
|
@@ -732,3 +732,10 @@ Increasing output allowance can increase cost and does not establish visual
|
|
|
732
732
|
accuracy. Verify page observations separately; a complete response alone is not
|
|
733
733
|
business acceptance. These variables require a build containing this feature;
|
|
734
734
|
the previously published alpha.2 does not support them.
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
## Scheduled notification bindings
|
|
738
|
+
|
|
739
|
+
`createBackgroundClient()` 提供 `getScheduledNotificationBinding(selector)` 与 `rebindScheduledNotifications(request)`,用于新会话接收原定时任务通知。选择器为 `{ taskId, taskCreatedAt }` 或 `{ occurrenceId }`;请求包含 `selector`、`targetSessionId`、`expectedRevision`(初始 0)和稳定 `actionId`。返回绑定含 `sessionId/revision/generation/updatedAt`。读取 occurrence 绑定还返回 `effective` 路由;显式 occurrence 优先于 task,task 优先于原 delegation。
|
|
740
|
+
|
|
741
|
+
换绑不启动 owner、不改变原任务或审批状态。超时重试原 actionId 和原请求;同 ID 改内容拒绝,revision 冲突须读取当前状态后决定新动作。模型工具固定绑定到自己的宿主 session,并请求权限确认。已被消费者接受的旧通知不会撤回;新代次只通知当前待办或结果,不重放过期历史。完整 CLI、工具字段、错误和恢复说明见 [新会话接收原任务通知](../docs/background-runs.md#新会话接收原任务通知)。
|