@william2000/dsh-nova-ui-task-board 0.1.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 +86 -0
- package/cordis.patch.yml +13 -0
- package/lib/client.js +5641 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +4873 -0
- package/lib/types/client/NovaTaskBoardSettingsCard.d.ts +17 -0
- package/lib/types/client/PlaceholderBoard.d.ts +9 -0
- package/lib/types/client/apply-guard.d.ts +25 -0
- package/lib/types/client/board/ConfirmDialog.d.ts +12 -0
- package/lib/types/client/board/ConfirmTaskDialog.d.ts +8 -0
- package/lib/types/client/board/ConvertTaskModal.d.ts +17 -0
- package/lib/types/client/board/NewTaskModal.d.ts +6 -0
- package/lib/types/client/board/RequirementSplitModal.d.ts +14 -0
- package/lib/types/client/board/SplitConfirmDialog.d.ts +9 -0
- package/lib/types/client/board/TagEditor.d.ts +6 -0
- package/lib/types/client/board/TaskBoard.d.ts +9 -0
- package/lib/types/client/board/TaskCard.d.ts +52 -0
- package/lib/types/client/board/TaskDetail.d.ts +7 -0
- package/lib/types/client/board/status-key.d.ts +8 -0
- package/lib/types/client/board-controller.d.ts +274 -0
- package/lib/types/client/board-mount.d.ts +10 -0
- package/lib/types/client/chat-integration.d.ts +99 -0
- package/lib/types/client/drag-utils.d.ts +78 -0
- package/lib/types/client/filter.d.ts +42 -0
- package/lib/types/client/grouping.d.ts +54 -0
- package/lib/types/client/host-api.d.ts +62 -0
- package/lib/types/client/index.d.ts +46 -0
- package/lib/types/client/legacy-store.d.ts +28 -0
- package/lib/types/client/locales.d.ts +202 -0
- package/lib/types/client/schedule-presets.d.ts +20 -0
- package/lib/types/client/sidebar-entry-core.d.ts +54 -0
- package/lib/types/client/sidebar-entry.d.ts +19 -0
- package/lib/types/core/context.d.ts +139 -0
- package/lib/types/core/cron.d.ts +54 -0
- package/lib/types/core/migrate.d.ts +39 -0
- package/lib/types/core/model.d.ts +446 -0
- package/lib/types/core/recovery.d.ts +25 -0
- package/lib/types/core/split.d.ts +81 -0
- package/lib/types/core/transitions.d.ts +436 -0
- package/lib/types/dsh-home.d.ts +21 -0
- package/lib/types/host-automation.d.ts +59 -0
- package/lib/types/host-ledger.d.ts +146 -0
- package/lib/types/host-routes.d.ts +65 -0
- package/lib/types/host-runner.d.ts +177 -0
- package/lib/types/host-service.d.ts +291 -0
- package/lib/types/index.d.ts +90 -0
- package/lib/types/loopback.d.ts +23 -0
- package/lib/types/mount-once.d.ts +9 -0
- package/lib/types/protocol.d.ts +210 -0
- package/package.json +89 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 上下文闭环与自动收集的纯函数(DSH-REQ-001 §14.3/§9.5,T010/P3)。
|
|
3
|
+
*
|
|
4
|
+
* 本模块只做「无副作用」的转换与判定,全部可脱离宿主单测:
|
|
5
|
+
* - **清洗(§14.3 安全红线)**:`sanitizeCollectedText` 剥离控制字符、封顶长度;
|
|
6
|
+
* 自动收集/评论内容一律先清洗再落账;
|
|
7
|
+
* - **人工审核闸门(§14.3)**:`isAutoCollected` 判定自动收集来源
|
|
8
|
+
* (github_issue / bookmark_collector);未 promote(仍在 backlog)前不可
|
|
9
|
+
* 执行/不可定时(守卫落在 transitions 层,见 canRunTask / set-schedule /
|
|
10
|
+
* set-one-shot);
|
|
11
|
+
* - **收集映射**:GitHub Issue / 书签条目 → 标准化的 backlog `TaskRecord`
|
|
12
|
+
* (source/metadata 写入,供去重与追溯);`collectorDedupKey`/`hasCollected`
|
|
13
|
+
* 提供按 (source, metadata.url) 的幂等去重;
|
|
14
|
+
* - **上下文注入(§14.3/§9.5,B5 调研落定)**:`composeInjectionContext` 只带
|
|
15
|
+
* 摘要 + 必要片段(goal/lastAiSummary/latestUserFeedback/relatedLinks),
|
|
16
|
+
* `CONTEXT_INJECTION_BUDGET` 给出逐字段与总量 token 预算;`composePrompt`
|
|
17
|
+
* 在有快照的任务 Prompt 尾部追加注入块——后续调用只使用摘要与必要片段,
|
|
18
|
+
* 不再把全量历史/描述灌给 agent。
|
|
19
|
+
*
|
|
20
|
+
* 收集器的 I/O(GitHub API 拉取、书签文件读取)与账本落账在 host-automation.ts
|
|
21
|
+
* / host-service.ts,本层只产出数据。
|
|
22
|
+
*/
|
|
23
|
+
import type { AutomationRule, TaskRecord, TaskSource } from './model.ts';
|
|
24
|
+
/** 自动收集来源(§14.3:只进 backlog,必须人工 promote 才可执行)。 */
|
|
25
|
+
export declare const AUTO_COLLECTED_SOURCES: readonly TaskSource[];
|
|
26
|
+
/** 是否自动收集来源(人工审核闸门的判据之一)。 */
|
|
27
|
+
export declare function isAutoCollected(task: Pick<TaskRecord, 'source'>): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 清洗文本(§14.3):剥离控制字符(保留 \n \t)、trim、长度封顶。
|
|
30
|
+
* 用于自动收集的标题/描述、评论正文等一切外部输入。
|
|
31
|
+
*/
|
|
32
|
+
export declare function sanitizeCollectedText(text: unknown, maxLength?: number): string;
|
|
33
|
+
/** 收集去重键(§14.1/14.2):同来源同 URL 视为同一条外部内容。 */
|
|
34
|
+
export declare function collectorDedupKey(source: TaskSource, metadata: Record<string, string> | undefined): string | undefined;
|
|
35
|
+
/** 账本中是否已存在同 (source, url) 的收集任务(去重判定,Host 落账前调用)。 */
|
|
36
|
+
export declare function hasCollected(tasks: readonly TaskRecord[], source: TaskSource, metadata: Record<string, string> | undefined): boolean;
|
|
37
|
+
/** GitHub 标签命中判定(§14.1 过滤器):规则标签非空时,Issue 至少命中一个(大小写不敏感)。 */
|
|
38
|
+
export declare function matchesGithubLabels(issueLabels: readonly string[] | undefined, ruleLabels: readonly string[]): boolean;
|
|
39
|
+
/** 从 Issue 载荷/API 响应的 labels 提取标签名数组(string 或 {name} 两种形态)。 */
|
|
40
|
+
export declare function issueLabelNames(issue: GithubIssueLike): string[];
|
|
41
|
+
/** 收集任务的最小输入面(title/description 已清洗,metadata 已归置)。 */
|
|
42
|
+
export interface CollectedTaskInput {
|
|
43
|
+
title: string;
|
|
44
|
+
description: string;
|
|
45
|
+
source: TaskSource;
|
|
46
|
+
metadata: Record<string, string>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 由收集输入构造一条标准的 backlog 任务(§14.3:只进 backlog;prompt 回退用
|
|
50
|
+
* 标题——promote 到 todo 后执行即以标题为 Prompt;tags 默认 [] 待人工标注)。
|
|
51
|
+
*/
|
|
52
|
+
export declare function newCollectedTask(input: CollectedTaskInput, id: string, now: number, order: number): TaskRecord;
|
|
53
|
+
/** GitHub Issue 的最小结构面(webhook 载荷 / API 响应的共同子集)。 */
|
|
54
|
+
export interface GithubIssueLike {
|
|
55
|
+
/** Issue 编号(webhook 恒有;API 恒有)。 */
|
|
56
|
+
number?: number;
|
|
57
|
+
title?: string;
|
|
58
|
+
html_url?: string;
|
|
59
|
+
body?: string | null;
|
|
60
|
+
labels?: Array<{
|
|
61
|
+
name?: string;
|
|
62
|
+
} | string>;
|
|
63
|
+
}
|
|
64
|
+
/** GitHub webhook `issues` 事件载荷的最小结构面(§14.1)。 */
|
|
65
|
+
export interface GithubWebhookIssuePayload {
|
|
66
|
+
action?: string;
|
|
67
|
+
issue?: GithubIssueLike;
|
|
68
|
+
repository?: {
|
|
69
|
+
full_name?: string;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 严格解析 GitHub webhook `issues` 事件载荷(§14.1):只消费已知字段、未知
|
|
74
|
+
* 字段剥离(载荷为外部输入,永不被解释为任务字段);结构非法返回 undefined。
|
|
75
|
+
* 收集内容(标题/正文)在映射时经 sanitizeCollectedText 清洗(§14.3)。
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseGithubWebhookPayload(value: unknown): GithubWebhookIssuePayload | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* GitHub Issue → 收集任务输入(§14.1):标题/描述清洗、来源链接等写入
|
|
80
|
+
* metadata(url/externalId/repo/labels),供去重与追溯。
|
|
81
|
+
*/
|
|
82
|
+
export declare function githubIssueToCollectedTaskInput(issue: GithubIssueLike, repo: string | undefined): CollectedTaskInput;
|
|
83
|
+
/** 书签收件箱条目(§14.2:JSONL 一行一条;浏览器书签导出/手动维护均可)。 */
|
|
84
|
+
export interface BookmarkEntry {
|
|
85
|
+
title?: string;
|
|
86
|
+
url?: string;
|
|
87
|
+
note?: string;
|
|
88
|
+
}
|
|
89
|
+
/** 书签条目 → 收集任务输入(§14.2):URL 缺失丢弃;标题回退用 URL。 */
|
|
90
|
+
export declare function bookmarkEntryToCollectedTaskInput(entry: BookmarkEntry): CollectedTaskInput | undefined;
|
|
91
|
+
/** 解析书签收件箱文件(JSONL:每行一个 JSON 对象;空行/非法行跳过)。 */
|
|
92
|
+
export declare function parseBookmarkEntries(content: string): BookmarkEntry[];
|
|
93
|
+
/**
|
|
94
|
+
* 注入 token 预算(B5 调研结论:Host 侧摘取 + 固定预算,避免把全量上下文灌给
|
|
95
|
+
* agent)。逐字段上限 + 注入块总量上限(约 400 token,中文按 0.6 token/字)。
|
|
96
|
+
*/
|
|
97
|
+
export declare const CONTEXT_INJECTION_BUDGET: {
|
|
98
|
+
/** goal 上限(字符)。 */
|
|
99
|
+
readonly goalMax: 200;
|
|
100
|
+
/** lastAiSummary 上限(字符)。 */
|
|
101
|
+
readonly summaryMax: 600;
|
|
102
|
+
/** latestUserFeedback 上限(字符)。 */
|
|
103
|
+
readonly feedbackMax: 300;
|
|
104
|
+
/** relatedLinks 合计上限(字符)。 */
|
|
105
|
+
readonly linksMax: 400;
|
|
106
|
+
/** 注入块总量上限(字符)。 */
|
|
107
|
+
readonly totalMax: 1500;
|
|
108
|
+
};
|
|
109
|
+
/** 任务最近一条 user_feedback 评论的正文(供快照 latestUserFeedback)。 */
|
|
110
|
+
export declare function latestUserFeedback(task: TaskRecord): string | undefined;
|
|
111
|
+
/** 截断文本到上限(中文友好:按字符计)。 */
|
|
112
|
+
export declare function truncateText(text: string, max: number): string;
|
|
113
|
+
/**
|
|
114
|
+
* 组合注入块(B5):只带摘要与必要片段——goal / lastAiSummary /
|
|
115
|
+
* latestUserFeedback / relatedLinks,逐字段按预算截断,总量再封顶。
|
|
116
|
+
* 快照不存在或无可注入内容时返回 undefined(不追加注入)。
|
|
117
|
+
*/
|
|
118
|
+
export declare function composeInjectionContext(task: TaskRecord): string | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* 执行 Prompt 合成(B5 落定,runner.launch 使用):基线为任务 Prompt(空则
|
|
121
|
+
* 回退标题);任务有上下文快照时在尾部追加注入块——后续调用只使用摘要与
|
|
122
|
+
* 必要片段。无快照的任务行为与 T005 完全一致(不影响既有执行语义)。
|
|
123
|
+
*/
|
|
124
|
+
export declare function composePrompt(task: TaskRecord): string;
|
|
125
|
+
/** 快照字段可注入子集(service 结算时由 Host 合成更新,见 host-service.ts)。 */
|
|
126
|
+
export interface ContextSnapshotPatch {
|
|
127
|
+
goal?: string;
|
|
128
|
+
keyDecisions?: string[];
|
|
129
|
+
filePaths?: string[];
|
|
130
|
+
lastAiSummary?: string;
|
|
131
|
+
latestUserFeedback?: string;
|
|
132
|
+
relatedLinks?: string[];
|
|
133
|
+
}
|
|
134
|
+
/** 从快照补丁构造 Host 侧结算后快照更新(B5:只覆盖可注入字段)。 */
|
|
135
|
+
export declare function contextPatchFromSettle(task: TaskRecord, lastAiSummary: string | undefined): ContextSnapshotPatch;
|
|
136
|
+
/** 上下文快照的数组字段归一化(跨模块共用:去空、去重、封顶)。 */
|
|
137
|
+
export declare function normalizeSnapshotList(value: readonly string[] | undefined): string[];
|
|
138
|
+
/** 从 AutomationRule 读取收集来源配置(带默认值)。 */
|
|
139
|
+
export declare function ruleConfig(rule: AutomationRule, key: string, fallback?: string): string | undefined;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 5 段 cron 语法校验(DSH-REQ-001 §9.4 / §11.2 协议严格校验「cron 合法性」)。
|
|
3
|
+
*
|
|
4
|
+
* T003 交付语法层(parseCron + isValidCron,纯函数、无依赖、无 fs):协议层
|
|
5
|
+
* 用它对 import 载荷里的 schedule.cron 做合法性校验。T006(cron 周期定时调度)
|
|
6
|
+
* 在本模块之上扩展到期计算(nextRunAtMs,§9.4/§13.1:Host 本地时区、DST 正确
|
|
7
|
+
* 处理、错过不补跑由调度 tick 的滚动语义承担),语法面保持一致。
|
|
8
|
+
*
|
|
9
|
+
* 语法(对齐参考实现 core/schedule.ts 的引擎基线):五个空白分隔字段
|
|
10
|
+
* `分 时 日 月 周`;每字段支持通配星号、步长(星号或区间 + 斜杠 n)、单值、
|
|
11
|
+
* 闭区间 a-b、逗号列表(以上任意混排)。范围:分 0-59、时 0-23、日 1-31、
|
|
12
|
+
* 月 1-12、周 0-7(0 与 7 均表示周日)。非法表达式解析为 null。
|
|
13
|
+
*
|
|
14
|
+
* 与 model.ts `isPlausibleCron` 的分层关系:`isPlausibleCron` 是持久化层的
|
|
15
|
+
* 宽松形状检查(字符集 + 段数,用于行级修复「修复或丢弃 schedule」);
|
|
16
|
+
* 本模块是协议层的严格语法校验(字段取值范围/区间/步长合法性),二者不互换。
|
|
17
|
+
*/
|
|
18
|
+
/** 解析后的各字段匹配集合(不含周字段 7→0 归一化,见 parseCron)。 */
|
|
19
|
+
export interface ParsedCron {
|
|
20
|
+
minutes: ReadonlySet<number>;
|
|
21
|
+
hours: ReadonlySet<number>;
|
|
22
|
+
days: ReadonlySet<number>;
|
|
23
|
+
months: ReadonlySet<number>;
|
|
24
|
+
weekdays: ReadonlySet<number>;
|
|
25
|
+
/** 日字段是否为字面 `*`(未限制)。 */
|
|
26
|
+
dayWildcard: boolean;
|
|
27
|
+
/** 周字段是否为字面 `*`(未限制)。 */
|
|
28
|
+
weekdayWildcard: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 解析一个 5 段 cron 表达式。
|
|
32
|
+
* @returns 各字段匹配集合;表达式非法时返回 null。
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseCron(expr: string): ParsedCron | null;
|
|
35
|
+
/** 表达式是否可解析(语法合法)。 */
|
|
36
|
+
export declare function isValidCron(expr: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* 计算 `fromMs`(ms epoch)之后的下一个匹配时刻(T006 §9.4/§13.1)。返回匹配
|
|
39
|
+
* 分钟起点的 ms epoch,**严格大于** fromMs;日历约束永不可能满足时返回
|
|
40
|
+
* undefined(如 `0 0 30 2 *`——五年视界包含完整闰周期,合法的 2 月 29 日
|
|
41
|
+
* 计划在任意非闰年仍可达)。
|
|
42
|
+
*
|
|
43
|
+
* 语义(对齐参考实现 core/schedule.ts,T006 验收 3):
|
|
44
|
+
* - **Host 本地时区**:按 `new Date(y, m, d, h, min)` 墙钟字段遍历候选,不换算
|
|
45
|
+
* 到 UTC——DST 由本地时间语义自然承担;
|
|
46
|
+
* - **日/周 OR 语义**:日字段与周字段字面 `*` 时各自视为未限制(见 parseCron),
|
|
47
|
+
* 二者都受限时用 OR 组合(标准 cron);
|
|
48
|
+
* - **DST 正确性**:墙钟字段构造 + 最终 `matches` 复检复现旧分钟扫描的 DST
|
|
49
|
+
* 语义——春令时不存在的时间(如 02:30 → 03:30)被 JS 归一化前移,回拨的
|
|
50
|
+
* 重复小时(fall-back)只访问第一次出现;本实现不逐分钟扫描,而是直接从
|
|
51
|
+
* 解析后的字段集合遍历年/月/日/时/分候选,稀疏表达式(如 `0 0 29 2 *`)不会
|
|
52
|
+
* 扫过约 150 万分钟。
|
|
53
|
+
*/
|
|
54
|
+
export declare function nextRunAtMs(expr: string, fromMs: number): number | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v1 数据迁移的纯函数(DSH-REQ-001 §9.5 / §11.2 `import`)。
|
|
3
|
+
*
|
|
4
|
+
* 迁移协议:浏览器首次加载时读取 `dsh.taskBoard.v1`(localStorage),按
|
|
5
|
+
* sourceId(如 `'localStorage:dsh.taskBoard.v1'`)+ requestId 一次性提交 import
|
|
6
|
+
* action;Host 侧由本模块按 id 合并进账本,并把 sourceId 追加到
|
|
7
|
+
* `scheduler.importedSources`(**导入 marker 只在 Host 原子落账确认后写入**)。
|
|
8
|
+
* 浏览器以「import 请求成功返回 + 记住返回快照的 ledgerId」作为确认凭证,确认
|
|
9
|
+
* 后才自行处置 v1 原值——v1 原值保留为只读回退副本(对齐参考实现的
|
|
10
|
+
* `dsh.taskBoard.v2.hostImported` marker 模式)。重复 import 同一 sourceId 为
|
|
11
|
+
* 幂等 no-op(changed: false,不落账不 bump revision)。
|
|
12
|
+
*
|
|
13
|
+
* 合并语义(对齐参考实现):同 id 任务取 `updatedAt` 较新者为底;执行记录按
|
|
14
|
+
* execution id 合并——已结算记录胜过陈旧未结算记录,平局取较晚者。
|
|
15
|
+
*/
|
|
16
|
+
import type { ExecutionRecord, LedgerDocument, TaskRecord } from './model.ts';
|
|
17
|
+
/**
|
|
18
|
+
* 二选一并取更「有信息量」的同 id 执行记录:
|
|
19
|
+
* - 已结算胜过未结算(未结算多为陈旧副本的残留 open 记录);
|
|
20
|
+
* - 同为已结算/未结算时取较晚者(以 endedAt ?? startedAt 为准)。
|
|
21
|
+
*/
|
|
22
|
+
export declare function mergeExecution(a: ExecutionRecord, b: ExecutionRecord): ExecutionRecord;
|
|
23
|
+
/** 按 id 合并两条任务:较新 `updatedAt` 为底,执行记录按 id 合并并按时序排序。 */
|
|
24
|
+
export declare function mergeTask(a: TaskRecord, b: TaskRecord): TaskRecord;
|
|
25
|
+
/** import 落账结果。 */
|
|
26
|
+
export interface ImportResult {
|
|
27
|
+
/** 是否发生了实际变更(false = sourceId 已导入过,幂等 no-op)。 */
|
|
28
|
+
changed: boolean;
|
|
29
|
+
/** 可见错误(如被丢弃的非法任务行)。 */
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 将一批 v1 任务按 sourceId 导入账本(就地修改 `doc`):
|
|
34
|
+
* - `doc.scheduler.importedSources` 已含 sourceId → `{ changed: false }`(跳过);
|
|
35
|
+
* - 否则逐条 `normalizeTask`(防御性校验:协议层已校验过类型,这里兜底),
|
|
36
|
+
* 非法行丢弃并记入 error;合法行按 id 合并进 `doc.tasks`;
|
|
37
|
+
* - 追加 sourceId 到 importedSources(导入 marker,随下次原子落账持久化)。
|
|
38
|
+
*/
|
|
39
|
+
export declare function importIntoLedger(doc: LedgerDocument, sourceId: string, incoming: readonly TaskRecord[]): ImportResult;
|