dsh-task-dispatch-table 0.0.0 → 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/README.md +101 -31
- package/README.zh.md +119 -0
- package/assets/icon-scheduler.svg +1 -0
- package/cordis.patch.yml +9 -0
- package/dist/attachment-allowlist.d.ts +24 -0
- package/dist/attachment-allowlist.js +41 -0
- package/dist/calendar-plan.d.ts +55 -0
- package/dist/calendar-plan.js +104 -0
- package/dist/client.js +72655 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +79 -0
- package/dist/config.js +80 -0
- package/dist/deps.d.ts +25 -0
- package/dist/deps.js +54 -0
- package/dist/dispatch.d.ts +133 -0
- package/dist/dispatch.js +509 -0
- package/dist/event-bus.d.ts +16 -0
- package/dist/event-bus.js +67 -0
- package/dist/event-catalog.d.ts +42 -0
- package/dist/event-catalog.js +60 -0
- package/dist/host.d.ts +299 -0
- package/dist/host.js +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +0 -0
- package/dist/receipt.d.ts +38 -0
- package/dist/receipt.js +236 -0
- package/dist/reconcile.d.ts +105 -0
- package/dist/reconcile.js +641 -0
- package/dist/runtime-index.d.ts +102 -0
- package/dist/runtime-index.js +340 -0
- package/dist/schedule-next.d.ts +44 -0
- package/dist/schedule-next.js +216 -0
- package/dist/scheduler.d.ts +82 -0
- package/dist/scheduler.js +639 -0
- package/dist/store.d.ts +461 -0
- package/dist/store.js +845 -0
- package/dist/submit.d.ts +1 -0
- package/dist/submit.js +60 -0
- package/dist/task-assets.d.ts +124 -0
- package/dist/task-assets.js +380 -0
- package/dist/task-sort.d.ts +27 -0
- package/dist/task-sort.js +59 -0
- package/dist/tasks.d.ts +191 -0
- package/dist/tasks.js +527 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +67 -6
- package/index.js +0 -7
package/dist/tasks.d.ts
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { HostLogger } from './host.js';
|
|
3
|
+
export { filterSlotsBySchedule, logicalDateOf, nextSlotAfter, onceScheduledAt, scheduledSlotsFor, } from './schedule-next.js';
|
|
4
|
+
export declare const dependencySemantics: readonly ["same_period", "latest_success"];
|
|
5
|
+
export type DependencySemantics = (typeof dependencySemantics)[number];
|
|
6
|
+
/**
|
|
7
|
+
* 任务定义输入 schema(决策 25/30):身份三字段分离——
|
|
8
|
+
* `id` = **机器身份**,录入瞬间由系统生成 UUID 并**写回这段 JSON**(inline 回写 settings、
|
|
9
|
+
* 目录模式回写该文件),人不手写、不参与展示;`title` = 任务名称(人读、随时可改);
|
|
10
|
+
* `code` = 任务编号(**可选**、用户自编,仅便于查询与管理,**只做记录、不参与任何唯一性判断**
|
|
11
|
+
* ——空格、重名、格式差异都不影响身份判定,因为判断只走 id + 计划刻度)。
|
|
12
|
+
*/
|
|
13
|
+
export declare const taskDefinitionSchema: z.ZodObject<{
|
|
14
|
+
id: z.ZodOptional<z.ZodString>;
|
|
15
|
+
title: z.ZodOptional<z.ZodString>;
|
|
16
|
+
code: z.ZodOptional<z.ZodString>;
|
|
17
|
+
enabled: z.ZodBoolean;
|
|
18
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
19
|
+
schedule: z.ZodObject<{
|
|
20
|
+
cron: z.ZodOptional<z.ZodString>;
|
|
21
|
+
timezone: z.ZodOptional<z.ZodString>;
|
|
22
|
+
window: z.ZodString;
|
|
23
|
+
once: z.ZodOptional<z.ZodString>;
|
|
24
|
+
start: z.ZodOptional<z.ZodString>;
|
|
25
|
+
everyNWeeks: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
ui: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
target: z.ZodObject<{
|
|
29
|
+
workspace: z.ZodString;
|
|
30
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
31
|
+
model: z.ZodOptional<z.ZodString>;
|
|
32
|
+
manual: z.ZodOptional<z.ZodString>;
|
|
33
|
+
prompt: z.ZodString;
|
|
34
|
+
goal: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
agentTeam: z.ZodOptional<z.ZodBoolean>;
|
|
36
|
+
permission: z.ZodOptional<z.ZodEnum<{
|
|
37
|
+
default: "default";
|
|
38
|
+
readOnly: "readOnly";
|
|
39
|
+
workspace: "workspace";
|
|
40
|
+
full: "full";
|
|
41
|
+
}>>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
contract: z.ZodDefault<z.ZodObject<{
|
|
44
|
+
validStatuses: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
45
|
+
}, z.core.$strip>>;
|
|
46
|
+
retry: z.ZodDefault<z.ZodObject<{
|
|
47
|
+
maxAttempts: z.ZodDefault<z.ZodNumber>;
|
|
48
|
+
}, z.core.$strip>>;
|
|
49
|
+
depends_on: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
50
|
+
task: z.ZodString;
|
|
51
|
+
semantics: z.ZodEnum<{
|
|
52
|
+
same_period: "same_period";
|
|
53
|
+
latest_success: "latest_success";
|
|
54
|
+
}>;
|
|
55
|
+
}, z.core.$strip>>>;
|
|
56
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
57
|
+
id: z.ZodString;
|
|
58
|
+
name: z.ZodString;
|
|
59
|
+
kind: z.ZodEnum<{
|
|
60
|
+
link: "link";
|
|
61
|
+
upload: "upload";
|
|
62
|
+
}>;
|
|
63
|
+
ref: z.ZodString;
|
|
64
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, z.core.$strip>>>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
/** 用户书写形态:`id` 可缺省。 */
|
|
68
|
+
export type TaskDefinitionInput = z.infer<typeof taskDefinitionSchema>;
|
|
69
|
+
/**
|
|
70
|
+
* 解析后的任务定义:`id` **必有**(用户未写时由 `withIdentity` 生成并回写 JSON)。
|
|
71
|
+
* 全链路(scheduler / dispatch / reconcile)都按这个类型走,避免到处判空。
|
|
72
|
+
*/
|
|
73
|
+
export type TaskDefinition = Omit<TaskDefinitionInput, 'id'> & {
|
|
74
|
+
id: string;
|
|
75
|
+
};
|
|
76
|
+
/** 展示名:优先 title,回退 id(决策 25:title 只是给人看的,永不参与身份)。 */
|
|
77
|
+
export declare function titleOf(task: TaskDefinition): string;
|
|
78
|
+
/**
|
|
79
|
+
* 会话显示名标题(决策 42):title 回退 code,再回退短 id(前 8 位)。
|
|
80
|
+
* 与 titleOf 的差别:code 也参与回退(编号比 UUID 对人更有意义),且永不落完整 UUID。
|
|
81
|
+
*/
|
|
82
|
+
export declare function displayNameOf(task: TaskDefinition): string;
|
|
83
|
+
/** 计划时刻短格式 `YYMMDD-HHmm`(本地时区,决策 42;例 `260928-1600`)。 */
|
|
84
|
+
export declare function formatSlotShort(scheduledAtIso: string): string;
|
|
85
|
+
/**
|
|
86
|
+
* 派发会话名(决策 42):`[TASK] <260928-1600> · <标题>`,attempt>0(第 2 次起)追加「 · 第N次」。
|
|
87
|
+
* 时间取计划时刻(重试不变,与执行记录「计划时刻」列一致);重试后缀既点明重试、又防同刻度重名。
|
|
88
|
+
*/
|
|
89
|
+
export declare function sessionTitleOf(scheduledAtIso: string, displayName: string, attempt: number): string;
|
|
90
|
+
/** 任务 id 是否合法:必须是标准 UUID。手写 kebab-case / 旧内容指纹等一律不算。 */
|
|
91
|
+
export declare function isUuid(value: unknown): value is string;
|
|
92
|
+
/** 生成一个任务 id:标准 UUID(决策 30:机器身份与内容、名称彻底解耦,保存时生成并固化写入)。 */
|
|
93
|
+
export declare function newTaskId(): string;
|
|
94
|
+
/** 保存闸门的身份处理结果。 */
|
|
95
|
+
export interface EnsureIdsResult {
|
|
96
|
+
json: string;
|
|
97
|
+
changed: boolean;
|
|
98
|
+
assigned: number;
|
|
99
|
+
/** 非 null = **整批拒绝保存**:id 非 UUID,或 UUID 不在现有任务表中(决策 30 第三次拍板)。 */
|
|
100
|
+
error: string | null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 从已保存的 tasksInline 文本里提取全部合法 UUID 集合(保存闸门「修改必须命中」的比对基准)。
|
|
104
|
+
* 非法 JSON / 非数组 / 非 UUID id(老数据)一律不算 ⇒ 拿 UUID 去改老记录同样会被拒(老记录无 UUID 身份,想用就删 id 重录)。
|
|
105
|
+
*/
|
|
106
|
+
export declare function existingUuidIds(raw: string): ReadonlySet<string>;
|
|
107
|
+
/**
|
|
108
|
+
* 保存闸门(决策 30 修订版 + 第三次拍板,用户 2026-09-25:**保存时固化,运行时只认,UUID 不能凭空引入**)。
|
|
109
|
+
* ① 条目无 id ⇒ 生成随机 UUID 补上(= 新增任务,这一刻固化进 JSON);
|
|
110
|
+
* ② 有 id 且是 UUID ⇒ 必须在 `existingIds`(现有已保存任务表)中命中,命中即原样保留(= 修改既有任务);
|
|
111
|
+
* 不命中 ⇒ 报错拒绝——带 UUID 就是修改,修改目标必须存在,UUID 身份只能由本闸门生成,不允许凭空写入;
|
|
112
|
+
* ③ 有 id 但不是 UUID ⇒ 报错,**整批拒绝保存**;
|
|
113
|
+
* 非法 JSON / 非数组原样返回(error=null)——那是既有校验的职责,不是身份闸门的。
|
|
114
|
+
* `existingIds` 缺省(undefined)时跳过 ② 的命中校验(仅单测直调用)。
|
|
115
|
+
*/
|
|
116
|
+
export declare function ensureIdsInInlineJson(raw: string, existingIds?: ReadonlySet<string>): EnsureIdsResult;
|
|
117
|
+
/**
|
|
118
|
+
* 运行时身份校验(保存闸门的另一半,用户拍板:**运行时只认不修**)。
|
|
119
|
+
* 有 id 且为 UUID ⇒ 归一返回(code trim、title 缺省回退 id);
|
|
120
|
+
* 无 id(老数据)或 id 非 UUID ⇒ 返回 null,调用方记一条 warn 后跳过,不做任何兜底。
|
|
121
|
+
*/
|
|
122
|
+
export declare function applyIdentity(def: TaskDefinitionInput): TaskDefinition | null;
|
|
123
|
+
export interface SaveValidation {
|
|
124
|
+
ok: boolean;
|
|
125
|
+
/** 不通过的原因(中文,直接给 UI 展示)。 */
|
|
126
|
+
error: string | null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 单条任务定义的保存校验(服务端把关,data-model §5.2 校验清单):
|
|
130
|
+
* ① 提示词非空;② 工作区非空;③ `cron` 与 `once` **恰有其一**且 cron 可解析;
|
|
131
|
+
* ④ 前置任务必须指向已存在的任务(**停用可以、不存在不行**)。
|
|
132
|
+
* `title` / `code` **不做**格式与唯一性校验(决策 30:它们只是人读字段)。
|
|
133
|
+
*/
|
|
134
|
+
export declare function validateDefinitionForSave(def: TaskDefinitionInput, existingIds: ReadonlySet<string>): SaveValidation;
|
|
135
|
+
export interface UpsertResult {
|
|
136
|
+
json: string;
|
|
137
|
+
mode: 'create' | 'update';
|
|
138
|
+
/** 落定后的任务 id(新增时为系统刚生成的 UUID)。 */
|
|
139
|
+
id: string;
|
|
140
|
+
error: string | null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 把一条任务定义并回整表(新增 = 追加,修改 = 按 id 替换)。
|
|
144
|
+
* **身份闸门在这里落地**:无 id ⇒ 生成 UUID(新增);带 UUID ⇒ 必须命中现有表(修改);
|
|
145
|
+
* 非 UUID ⇒ 拒绝。
|
|
146
|
+
* @param opts.allowNew - 表单通道专用:带 UUID 但表中没有 ⇒ **视为新增**(id 由服务端刚生成,
|
|
147
|
+
* 可信)。整批 JSON 通道不传 ⇒ 沿用闸门语义(凭空引入的 UUID 一律拒)。
|
|
148
|
+
*/
|
|
149
|
+
export declare function upsertDefinitionInline(raw: string, definition: TaskDefinitionInput, opts?: {
|
|
150
|
+
allowNew?: boolean;
|
|
151
|
+
}): UpsertResult;
|
|
152
|
+
export interface RemoveResult {
|
|
153
|
+
json: string;
|
|
154
|
+
removed: boolean;
|
|
155
|
+
error: string | null;
|
|
156
|
+
}
|
|
157
|
+
/** 从整表里摘掉一条任务定义(删除任务;实例 / 事件保留在库里做审计)。 */
|
|
158
|
+
export declare function removeDefinitionInline(raw: string, id: string): RemoveResult;
|
|
159
|
+
export interface SetEnabledResult {
|
|
160
|
+
json: string;
|
|
161
|
+
changed: boolean;
|
|
162
|
+
error: string | null;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 只改一条任务的 `enabled`(编辑器头部的启用开关实时写回,用户 2026-09-30:独立于保存按钮)。
|
|
166
|
+
* 定义不存在 ⇒ error(404 语义);值没变 ⇒ changed=false(不落库不审计)。
|
|
167
|
+
*/
|
|
168
|
+
export declare function setEnabledDefinitionInline(raw: string, id: string, enabled: boolean): SetEnabledResult;
|
|
169
|
+
/** 把 ISO 8601 时长解析成毫秒。 */
|
|
170
|
+
export declare function durationMs(iso: string): number;
|
|
171
|
+
/** 用 Intl 验证 IANA 时区名(schedule.timezone 缺省 = 宿主时区)。 */
|
|
172
|
+
export declare function isValidTimeZone(tz: string): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* 某日历日上的第一个刻度(面板展示「下次执行」/ 目录模式历史锚点用;
|
|
175
|
+
* 决策 20 的 live 重排与 §7 backfill 已于决策 31 移除,不再依赖「天」粒度补跑)。
|
|
176
|
+
*/
|
|
177
|
+
export declare function firstSlotOnDay(task: TaskDefinition, day: string): Date | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* 解析内嵌任务表 JSON(tasksInline 配置):须为数组,逐项校验,坏项告警跳过。
|
|
180
|
+
* 身份走 `applyIdentity`(决策 30 修订:**运行时只认不修**)——无 id / 非 UUID 的条目
|
|
181
|
+
* warn 跳过,绝不在这里生成或兜底 id;生成只发生在保存闸门 `ensureIdsInInlineJson`。
|
|
182
|
+
*/
|
|
183
|
+
export declare function parseInlineTasks(logger: HostLogger, raw: string, opts?: {
|
|
184
|
+
includeDisabled?: boolean;
|
|
185
|
+
}): TaskDefinition[];
|
|
186
|
+
/**
|
|
187
|
+
* 读任务表目录:逐文件 safeParse,坏文件告警跳过;返回 enabled 的定义。
|
|
188
|
+
* 身份同样「运行时只认」(决策 30 修订):缺 id / id 非 UUID 的文件 warn 跳过,**不再写回**。
|
|
189
|
+
* 目录不存在(ENOENT)= 合法空态(用户没在用目录模式),静默返回,不刷告警。
|
|
190
|
+
*/
|
|
191
|
+
export declare function loadTasks(logger: HostLogger, tasksDir: string): TaskDefinition[];
|