@deepseek-ai/dsh-experimental-forge 0.2.2-alpha.2 → 0.2.2-alpha.3
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.i18n.yaml +2 -2
- package/README.md +5 -1
- package/README.zh.md +5 -1
- package/lib/index.js +48 -6
- package/lib/types/index.d.ts +17 -1
- package/lib/types/types.d.ts +34 -0
- package/package.json +6 -6
package/README.i18n.yaml
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 2f8a621b991260a1
|
|
17
17
|
/deepseek-ai-dsh-experimental-forge/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
18
|
+
en: 9ca86ee541048ff2
|
|
19
|
+
zh: 7aef4feb76542dd6
|
|
20
20
|
/deepseek-ai-dsh-experimental-forge/understand-the-implementation:
|
|
21
21
|
en: e193cb547c47069b
|
|
22
22
|
zh: faa517522402ea41
|
package/README.md
CHANGED
|
@@ -38,10 +38,14 @@ Mount the registry with at least one provider package, such as the GitHub provid
|
|
|
38
38
|
|
|
39
39
|
`diff(ref, signal)` reads the change request's unified patch as the host computes it, with `a/` and `b/` path prefixes, and `fileText(ref, commit, path, signal)` reads one file of its repository at a commit. Both delegate to the provider of the reference's forge, throw when none is registered, and resolve to the text or to a `ForgeFailure`, which is `too-large` when the host or the provider refuses an answer over its size limit. `fileUrl(ref, commit, path)` returns the web page of that file at that commit.
|
|
40
40
|
|
|
41
|
-
`
|
|
41
|
+
`fetchChecks(ref, signal)` reads one change request’s complete checks on demand. It has its own `fetchTimeoutMs` deadline and does not occupy the polling batch or publish to its watchers. Failure leaves previously polled snapshots intact. A provider without `fetchChecks` returns `unavailable`. Caller cancellation and provider or service disposal abort the read; disposal waits for it to settle.
|
|
42
|
+
|
|
43
|
+
`ctx.forge.watch(ref, listener)` is also an effect. The first watcher of a change request polls it at once; `latest(ref)` returns the most recent result. Each forge has at most one polling fetch in flight, and that fetch includes every due change request of the forge. An open change request is polled every `activeIntervalMs` while checks are pending or mergeability is unknown, and every `idleIntervalMs` otherwise. Closed change requests use `idleIntervalMs` to detect reopening; merged requests stop automatic polling. `refresh(ref)` polls a watched change request at once, including after a terminal state; if a fetch is already in flight for its forge, another fetch starts immediately after it settles. A failed read repeats after `activeIntervalMs` doubled for each consecutive failure, up to `maxBackoffMs`, which must be at least `activeIntervalMs`. Unregistering a provider settles its watched change requests as `unavailable`. Polling stops when the last watcher leaves. The [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-forge) lists the defaults.
|
|
42
44
|
|
|
43
45
|
Reaching `fetchTimeoutMs` aborts the fetch signal with `FORGE_FETCH_TIMEOUT`. Providers must stop their work and settle when the signal aborts; rejected fetches become `unavailable` failures. A provider that ignores cancellation can stall polling and service disposal.
|
|
44
46
|
|
|
47
|
+
Providers may implement `submitReview` to publish a line comment or a completed review at an explicit head commit. The registry returns unsupported when that capability is absent and refreshes watched status after a submission. Successful writes return their web URL; failures distinguish changed heads, refusals, and unknown outcomes. Callers must reconcile unknown outcomes before another submission. Pending drafts belong to the consumer, not the polling registry.
|
|
48
|
+
|
|
45
49
|
-----
|
|
46
50
|
|
|
47
51
|
<a id="understand-the-implementation"></a>
|
package/README.zh.md
CHANGED
|
@@ -38,10 +38,14 @@ kind: "package-reference"
|
|
|
38
38
|
|
|
39
39
|
`diff(ref, signal)` 读取托管平台计算出的变更请求统一补丁,路径带 `a/` 与 `b/` 前缀;`fileText(ref, commit, path, signal)` 读取其仓库中某个提交下的一个文件。两者都委托给引用所属 forge 的提供方,没有注册提供方时抛错,resolve 为文本或 `ForgeFailure`;托管平台或提供方因结果超过其大小上限而拒绝时,失败为 `too-large`。`fileUrl(ref, commit, path)` 返回该文件在该提交下的网页地址。
|
|
40
40
|
|
|
41
|
-
`
|
|
41
|
+
`fetchChecks(ref, signal)` 按需读取单个变更请求的完整检查,使用独立的 `fetchTimeoutMs` 时限,不占用轮询批次,也不向其监听方发布结果。读取失败时保留已有轮询快照。提供方未实现 `fetchChecks` 时返回 `unavailable`。调用方取消、提供方或服务销毁都会中止读取;销毁会等待读取结束。
|
|
42
|
+
|
|
43
|
+
`ctx.forge.watch(ref, listener)` 同样是 effect。变更请求的第一个监听方会立即触发轮询;`latest(ref)` 返回最近一次结果。每个 forge 同时最多只有一次轮询读取在进行,这次读取包含该 forge 所有到期的变更请求。打开状态的变更请求在检查未完成或可合并性未知时每 `activeIntervalMs` 轮询一次,否则每 `idleIntervalMs` 轮询一次。已关闭的变更请求按 `idleIntervalMs` 轮询以检测重新打开;已合并的停止自动轮询。`refresh(ref)` 立即轮询一个被监听的变更请求,已结束的也包括在内;该 forge 已有读取在进行时,等待其结束后立即再读一次。读取失败后,重试间隔为 `activeIntervalMs` 按连续失败次数翻倍,最长 `maxBackoffMs`;该值必须大于或等于 `activeIntervalMs`。注销提供方会让其被监听的变更请求以 `unavailable` 结束。最后一个监听方离开后轮询停止。默认值见[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-forge)。
|
|
42
44
|
|
|
43
45
|
达到 `fetchTimeoutMs` 时,读取信号会以 `FORGE_FETCH_TIMEOUT` 中止。提供方必须在信号中止时停止工作并结束请求;被拒绝的读取会转为 `unavailable` 失败。忽略取消的提供方可能阻塞轮询和服务销毁。
|
|
44
46
|
|
|
47
|
+
provider 可以实现 `submitReview`,在指定的 head 提交上发布行内评论或完整评审。未实现该能力时,注册表返回不支持;提交结束后会刷新受关注的状态。成功的写操作返回网页 URL;失败区分 head 变化、明确拒绝与结果不明。调用方必须先核对结果不明的操作,再次提交。待提交草稿由消费者管理,不由轮询注册表保存。
|
|
48
|
+
|
|
45
49
|
-----
|
|
46
50
|
|
|
47
51
|
<a id="understand-the-implementation"></a>
|
package/lib/index.js
CHANGED
|
@@ -255,6 +255,32 @@ var ForgeService = class extends Service {
|
|
|
255
255
|
return failure;
|
|
256
256
|
}
|
|
257
257
|
/**
|
|
258
|
+
* Read complete check details independently of periodic polling.
|
|
259
|
+
* @param ref - change request served by a registered provider.
|
|
260
|
+
* @param signal - cancellation of the detail view.
|
|
261
|
+
* @returns a complete snapshot or the provider's failure; unsupported providers return unavailable.
|
|
262
|
+
* @throws on cancellation, provider disposal, or expiry of this read's own `fetchTimeoutMs` deadline.
|
|
263
|
+
*/
|
|
264
|
+
async fetchChecks(ref, signal) {
|
|
265
|
+
const env_1 = {
|
|
266
|
+
stack: [],
|
|
267
|
+
error: void 0,
|
|
268
|
+
hasError: false
|
|
269
|
+
};
|
|
270
|
+
try {
|
|
271
|
+
const timeout = __addDisposableResource(env_1, deadline(signal, this.config.fetchTimeoutMs, "FORGE_FETCH_TIMEOUT"), false);
|
|
272
|
+
return await this.invoke(this.registration(ref.repository.forge), timeout.signal, (provider, operation) => provider.fetchChecks?.(ref, operation) ?? Promise.resolve({
|
|
273
|
+
code: "unavailable",
|
|
274
|
+
message: "This provider does not support complete check reads"
|
|
275
|
+
}));
|
|
276
|
+
} catch (e_1) {
|
|
277
|
+
env_1.error = e_1;
|
|
278
|
+
env_1.hasError = true;
|
|
279
|
+
} finally {
|
|
280
|
+
__disposeResources(env_1);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
258
284
|
* Read the changes of a change request as its host computes them.
|
|
259
285
|
* @param ref - change request served by a registered provider.
|
|
260
286
|
* @param signal - cancellation of the read.
|
|
@@ -265,6 +291,22 @@ var ForgeService = class extends Service {
|
|
|
265
291
|
return await this.invoke(this.registration(ref.repository.forge), signal, (provider, operation) => provider.diff(ref, operation));
|
|
266
292
|
}
|
|
267
293
|
/**
|
|
294
|
+
* Publish one comment or a completed review, then refresh the watched status.
|
|
295
|
+
* @param ref - change request served by a registered provider.
|
|
296
|
+
* @param request - explicitly selected commit, comments, and review decision.
|
|
297
|
+
* @param signal - request cancellation.
|
|
298
|
+
* @returns a publication URL or a failure, including an unknown write outcome.
|
|
299
|
+
*/
|
|
300
|
+
async submitReview(ref, request, signal) {
|
|
301
|
+
const result = await this.invoke(this.registration(ref.repository.forge), signal, (provider, operation) => provider.submitReview?.(ref, request, operation) ?? Promise.resolve({
|
|
302
|
+
ok: false,
|
|
303
|
+
code: "unsupported",
|
|
304
|
+
message: "This provider does not support review submission"
|
|
305
|
+
}));
|
|
306
|
+
this.refresh(ref);
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
268
310
|
* Read the text of one file at a commit of a change request's repository.
|
|
269
311
|
* @param ref - change request served by a registered provider.
|
|
270
312
|
* @param commit - commit object name.
|
|
@@ -425,19 +467,19 @@ var ForgeService = class extends Service {
|
|
|
425
467
|
try {
|
|
426
468
|
if (registration === void 0) failure = this.missing(forge);
|
|
427
469
|
else {
|
|
428
|
-
const
|
|
470
|
+
const env_2 = {
|
|
429
471
|
stack: [],
|
|
430
472
|
error: void 0,
|
|
431
473
|
hasError: false
|
|
432
474
|
};
|
|
433
475
|
try {
|
|
434
|
-
const timeout = __addDisposableResource(
|
|
476
|
+
const timeout = __addDisposableResource(env_2, deadline(this.lifetime.signal, this.config.fetchTimeoutMs, "FORGE_FETCH_TIMEOUT"), false);
|
|
435
477
|
results = await this.invoke(registration, timeout.signal, (provider, operation) => provider.fetch(batch.map((watch) => watch.ref), operation));
|
|
436
|
-
} catch (
|
|
437
|
-
|
|
438
|
-
|
|
478
|
+
} catch (e_2) {
|
|
479
|
+
env_2.error = e_2;
|
|
480
|
+
env_2.hasError = true;
|
|
439
481
|
} finally {
|
|
440
|
-
__disposeResources(
|
|
482
|
+
__disposeResources(env_2);
|
|
441
483
|
}
|
|
442
484
|
}
|
|
443
485
|
} catch (error) {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Registry of code-host providers with provider-neutral change requests and shared status polling. */
|
|
2
2
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
3
3
|
import z from '@deepseek-ai/schemastery';
|
|
4
|
-
import type { ChangeRequestListener, ChangeRequestRef, ChangeRequestUpdate, Config, ForgeActionFailure, ForgeFailure, ForgeProvider, ForgeReadiness, ForgeRepository, MergeRequest } from './types.ts';
|
|
4
|
+
import type { ChangeRequestListener, ChangeRequestRef, ChangeRequestSnapshot, ChangeRequestUpdate, Config, ForgeActionFailure, ForgeFailure, ForgeProvider, ForgeReadiness, ForgeRepository, ForgeReviewRequest, ForgeReviewResult, MergeRequest } from './types.ts';
|
|
5
5
|
export { changeRequestKey } from './keys.ts';
|
|
6
6
|
export type * from './types.ts';
|
|
7
7
|
declare module '@deepseek-ai/cordis' {
|
|
@@ -104,6 +104,14 @@ export declare class ForgeService extends Service {
|
|
|
104
104
|
* @throws when no provider serves the change request's forge, or with `signal.reason` when it aborts.
|
|
105
105
|
*/
|
|
106
106
|
merge(ref: ChangeRequestRef, request: MergeRequest, signal: AbortSignal): Promise<ForgeActionFailure | undefined>;
|
|
107
|
+
/**
|
|
108
|
+
* Read complete check details independently of periodic polling.
|
|
109
|
+
* @param ref - change request served by a registered provider.
|
|
110
|
+
* @param signal - cancellation of the detail view.
|
|
111
|
+
* @returns a complete snapshot or the provider's failure; unsupported providers return unavailable.
|
|
112
|
+
* @throws on cancellation, provider disposal, or expiry of this read's own `fetchTimeoutMs` deadline.
|
|
113
|
+
*/
|
|
114
|
+
fetchChecks(ref: ChangeRequestRef, signal: AbortSignal): Promise<ChangeRequestSnapshot | ForgeFailure>;
|
|
107
115
|
/**
|
|
108
116
|
* Read the changes of a change request as its host computes them.
|
|
109
117
|
* @param ref - change request served by a registered provider.
|
|
@@ -112,6 +120,14 @@ export declare class ForgeService extends Service {
|
|
|
112
120
|
* @throws when no provider serves the change request's forge, or with `signal.reason` when it aborts.
|
|
113
121
|
*/
|
|
114
122
|
diff(ref: ChangeRequestRef, signal: AbortSignal): Promise<string | ForgeFailure>;
|
|
123
|
+
/**
|
|
124
|
+
* Publish one comment or a completed review, then refresh the watched status.
|
|
125
|
+
* @param ref - change request served by a registered provider.
|
|
126
|
+
* @param request - explicitly selected commit, comments, and review decision.
|
|
127
|
+
* @param signal - request cancellation.
|
|
128
|
+
* @returns a publication URL or a failure, including an unknown write outcome.
|
|
129
|
+
*/
|
|
130
|
+
submitReview(ref: ChangeRequestRef, request: ForgeReviewRequest, signal: AbortSignal): Promise<ForgeReviewResult>;
|
|
115
131
|
/**
|
|
116
132
|
* Read the text of one file at a commit of a change request's repository.
|
|
117
133
|
* @param ref - change request served by a registered provider.
|
package/lib/types/types.d.ts
CHANGED
|
@@ -126,6 +126,36 @@ export interface MergeRequest {
|
|
|
126
126
|
/** Commit object name the head must still have; the merge is refused once the head moves. */
|
|
127
127
|
readonly headSha: string;
|
|
128
128
|
}
|
|
129
|
+
/** One inline comment addressed to the old or new side of a pull request diff. */
|
|
130
|
+
export interface ForgeLineComment {
|
|
131
|
+
readonly path: string;
|
|
132
|
+
readonly side: 'L' | 'R';
|
|
133
|
+
readonly startLine: number;
|
|
134
|
+
readonly endLine: number;
|
|
135
|
+
readonly body: string;
|
|
136
|
+
}
|
|
137
|
+
/** A single published comment or one completed review containing all pending comments. */
|
|
138
|
+
export type ForgeReviewRequest = {
|
|
139
|
+
/** Commit the user reviewed; providers must check it before writing and address that commit explicitly. */
|
|
140
|
+
readonly headSha: string;
|
|
141
|
+
} & ({
|
|
142
|
+
readonly kind: 'comment';
|
|
143
|
+
readonly comment: ForgeLineComment;
|
|
144
|
+
} | {
|
|
145
|
+
readonly kind: 'review';
|
|
146
|
+
readonly event: 'comment' | 'approve' | 'request-changes';
|
|
147
|
+
readonly body: string;
|
|
148
|
+
readonly comments: readonly ForgeLineComment[];
|
|
149
|
+
});
|
|
150
|
+
/** Result of a review write; unknown outcomes must be checked on the host before another submission. */
|
|
151
|
+
export type ForgeReviewResult = {
|
|
152
|
+
readonly ok: true;
|
|
153
|
+
readonly url: string;
|
|
154
|
+
} | {
|
|
155
|
+
readonly ok: false;
|
|
156
|
+
readonly code: 'unsupported' | 'stale' | 'failed' | 'unknown';
|
|
157
|
+
readonly message: string;
|
|
158
|
+
};
|
|
129
159
|
/** Why a provider could not change a change request. */
|
|
130
160
|
export interface ForgeActionFailure {
|
|
131
161
|
/**
|
|
@@ -150,6 +180,8 @@ export interface ForgeReadiness {
|
|
|
150
180
|
export interface ForgeProvider {
|
|
151
181
|
/** Forge family name stored in every repository this provider returns. */
|
|
152
182
|
readonly forge: string;
|
|
183
|
+
/** Publish a comment or completed review. Omission declares that this provider cannot write reviews. */
|
|
184
|
+
submitReview?(ref: ChangeRequestRef, request: ForgeReviewRequest, signal: AbortSignal): Promise<ForgeReviewResult>;
|
|
153
185
|
/** Map a Git remote URL to its repository, or undefined when this provider does not serve it. */
|
|
154
186
|
repositoryFromRemote(url: string): ForgeRepository | undefined;
|
|
155
187
|
/** Map a change request web URL to its reference, or undefined when this provider does not serve it. */
|
|
@@ -158,6 +190,8 @@ export interface ForgeProvider {
|
|
|
158
190
|
changeRequestUrl(ref: ChangeRequestRef): string;
|
|
159
191
|
/** Read the status of several change requests, returning one result per requested key. */
|
|
160
192
|
fetch(refs: readonly ChangeRequestRef[], signal: AbortSignal): Promise<ReadonlyMap<ChangeRequestKey, ChangeRequestSnapshot | ForgeFailure>>;
|
|
193
|
+
/** Read all checks for one change request on demand; omission declares that only the polling preview is available. */
|
|
194
|
+
fetchChecks?(ref: ChangeRequestRef, signal: AbortSignal): Promise<ChangeRequestSnapshot | ForgeFailure>;
|
|
161
195
|
/** Find open change requests whose head is `branch` in `repository`, excluding the default branch and forks. */
|
|
162
196
|
findByHead(repository: ForgeRepository, branch: string, signal: AbortSignal): Promise<readonly ChangeRequestRef[]>;
|
|
163
197
|
/** Report whether the provider can reach `host` with current credentials. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-experimental-forge",
|
|
3
3
|
"description": "Provider-neutral change request registry with shared status polling",
|
|
4
|
-
"version": "0.2.2-alpha.
|
|
4
|
+
"version": "0.2.2-alpha.3",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
"directory": "packages/experimental/forge"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@deepseek-ai/schemastery": "~3.18.6-alpha.
|
|
36
|
-
"@deepseek-ai/dsh-brand": "0.2.2-alpha.
|
|
37
|
-
"@deepseek-ai/dsh-timeout": "0.2.2-alpha.
|
|
35
|
+
"@deepseek-ai/schemastery": "~3.18.6-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-brand": "0.2.2-alpha.3",
|
|
37
|
+
"@deepseek-ai/dsh-timeout": "0.2.2-alpha.3"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@deepseek-ai/cordis": "~4.0.6-alpha.
|
|
40
|
+
"@deepseek-ai/cordis": "~4.0.6-alpha.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@deepseek-ai/cordis": "~4.0.6-alpha.
|
|
43
|
+
"@deepseek-ai/cordis": "~4.0.6-alpha.2"
|
|
44
44
|
}
|
|
45
45
|
}
|