ws-spec-kit 0.1.0-beta.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/LICENSE +201 -0
- package/README.md +79 -0
- package/dist/adapters/cli/output.d.ts +15 -0
- package/dist/adapters/cli/output.js +21 -0
- package/dist/adapters/cli/output.js.map +1 -0
- package/dist/adapters/cli/workflow.d.ts +25 -0
- package/dist/adapters/cli/workflow.js +131 -0
- package/dist/adapters/cli/workflow.js.map +1 -0
- package/dist/adapters/connectors/git-native.d.ts +23 -0
- package/dist/adapters/connectors/git-native.js +521 -0
- package/dist/adapters/connectors/git-native.js.map +1 -0
- package/dist/adapters/connectors/github-cli.d.ts +23 -0
- package/dist/adapters/connectors/github-cli.js +213 -0
- package/dist/adapters/connectors/github-cli.js.map +1 -0
- package/dist/adapters/connectors/gitlab-cli.d.ts +23 -0
- package/dist/adapters/connectors/gitlab-cli.js +199 -0
- package/dist/adapters/connectors/gitlab-cli.js.map +1 -0
- package/dist/adapters/connectors/lark-cli.d.ts +24 -0
- package/dist/adapters/connectors/lark-cli.js +296 -0
- package/dist/adapters/connectors/lark-cli.js.map +1 -0
- package/dist/adapters/process/redaction.d.ts +2 -0
- package/dist/adapters/process/redaction.js +51 -0
- package/dist/adapters/process/redaction.js.map +1 -0
- package/dist/adapters/process/spawn-json.d.ts +37 -0
- package/dist/adapters/process/spawn-json.js +312 -0
- package/dist/adapters/process/spawn-json.js.map +1 -0
- package/dist/adapters/skills/claude.d.ts +1 -0
- package/dist/adapters/skills/claude.js +3 -0
- package/dist/adapters/skills/claude.js.map +1 -0
- package/dist/adapters/skills/codex.d.ts +1 -0
- package/dist/adapters/skills/codex.js +3 -0
- package/dist/adapters/skills/codex.js.map +1 -0
- package/dist/adapters/skills/cursor.d.ts +1 -0
- package/dist/adapters/skills/cursor.js +3 -0
- package/dist/adapters/skills/cursor.js.map +1 -0
- package/dist/adapters/skills/generic.d.ts +1 -0
- package/dist/adapters/skills/generic.js +2 -0
- package/dist/adapters/skills/generic.js.map +1 -0
- package/dist/adapters/skills/install.d.ts +28 -0
- package/dist/adapters/skills/install.js +571 -0
- package/dist/adapters/skills/install.js.map +1 -0
- package/dist/application/acquire.d.ts +60 -0
- package/dist/application/acquire.js +964 -0
- package/dist/application/acquire.js.map +1 -0
- package/dist/application/application.d.ts +21 -0
- package/dist/application/application.js +31 -0
- package/dist/application/application.js.map +1 -0
- package/dist/application/artifact-reader.d.ts +1 -0
- package/dist/application/artifact-reader.js +150 -0
- package/dist/application/artifact-reader.js.map +1 -0
- package/dist/application/artifact-writer.d.ts +1 -0
- package/dist/application/artifact-writer.js +268 -0
- package/dist/application/artifact-writer.js.map +1 -0
- package/dist/application/artifact.d.ts +28 -0
- package/dist/application/artifact.js +523 -0
- package/dist/application/artifact.js.map +1 -0
- package/dist/application/decide.d.ts +12 -0
- package/dist/application/decide.js +168 -0
- package/dist/application/decide.js.map +1 -0
- package/dist/application/doctor-connectors.d.ts +34 -0
- package/dist/application/doctor-connectors.js +99 -0
- package/dist/application/doctor-connectors.js.map +1 -0
- package/dist/application/external-action.d.ts +164 -0
- package/dist/application/external-action.js +670 -0
- package/dist/application/external-action.js.map +1 -0
- package/dist/application/initial-stages.d.ts +3 -0
- package/dist/application/initial-stages.js +7 -0
- package/dist/application/initial-stages.js.map +1 -0
- package/dist/application/inspect.d.ts +2 -0
- package/dist/application/inspect.js +31 -0
- package/dist/application/inspect.js.map +1 -0
- package/dist/application/profile.d.ts +32 -0
- package/dist/application/profile.js +70 -0
- package/dist/application/profile.js.map +1 -0
- package/dist/application/snapshot.d.ts +75 -0
- package/dist/application/snapshot.js +338 -0
- package/dist/application/snapshot.js.map +1 -0
- package/dist/application/start.d.ts +43 -0
- package/dist/application/start.js +360 -0
- package/dist/application/start.js.map +1 -0
- package/dist/application/state.d.ts +17 -0
- package/dist/application/state.js +94 -0
- package/dist/application/state.js.map +1 -0
- package/dist/application/submit.d.ts +18 -0
- package/dist/application/submit.js +1090 -0
- package/dist/application/submit.js.map +1 -0
- package/dist/cli/commands/core.d.ts +2 -0
- package/dist/cli/commands/core.js +205 -0
- package/dist/cli/commands/core.js.map +1 -0
- package/dist/cli/commands/public-contract.d.ts +12 -0
- package/dist/cli/commands/public-contract.js +47 -0
- package/dist/cli/commands/public-contract.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +23 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/domain/artifacts.d.ts +52 -0
- package/dist/domain/artifacts.js +241 -0
- package/dist/domain/artifacts.js.map +1 -0
- package/dist/domain/digests.d.ts +11 -0
- package/dist/domain/digests.js +106 -0
- package/dist/domain/digests.js.map +1 -0
- package/dist/domain/external-receipt.d.ts +48 -0
- package/dist/domain/external-receipt.js +138 -0
- package/dist/domain/external-receipt.js.map +1 -0
- package/dist/domain/ids.d.ts +7 -0
- package/dist/domain/ids.js +5 -0
- package/dist/domain/ids.js.map +1 -0
- package/dist/domain/repository-path.d.ts +3 -0
- package/dist/domain/repository-path.js +87 -0
- package/dist/domain/repository-path.js.map +1 -0
- package/dist/domain/states.d.ts +38 -0
- package/dist/domain/states.js +69 -0
- package/dist/domain/states.js.map +1 -0
- package/dist/domain/work-package-identity.d.ts +2 -0
- package/dist/domain/work-package-identity.js +10 -0
- package/dist/domain/work-package-identity.js.map +1 -0
- package/dist/domain/workflow.d.ts +58 -0
- package/dist/domain/workflow.js +2 -0
- package/dist/domain/workflow.js.map +1 -0
- package/dist/engine/actor-roles.d.ts +15 -0
- package/dist/engine/actor-roles.js +53 -0
- package/dist/engine/actor-roles.js.map +1 -0
- package/dist/engine/approvals.d.ts +44 -0
- package/dist/engine/approvals.js +239 -0
- package/dist/engine/approvals.js.map +1 -0
- package/dist/engine/archive.d.ts +24 -0
- package/dist/engine/archive.js +442 -0
- package/dist/engine/archive.js.map +1 -0
- package/dist/engine/compiler.d.ts +25 -0
- package/dist/engine/compiler.js +828 -0
- package/dist/engine/compiler.js.map +1 -0
- package/dist/engine/control/condition.d.ts +10 -0
- package/dist/engine/control/condition.js +49 -0
- package/dist/engine/control/condition.js.map +1 -0
- package/dist/engine/control/loop.d.ts +23 -0
- package/dist/engine/control/loop.js +96 -0
- package/dist/engine/control/loop.js.map +1 -0
- package/dist/engine/control/retry.d.ts +15 -0
- package/dist/engine/control/retry.js +54 -0
- package/dist/engine/control/retry.js.map +1 -0
- package/dist/engine/docs-integrity.d.ts +13 -0
- package/dist/engine/docs-integrity.js +34 -0
- package/dist/engine/docs-integrity.js.map +1 -0
- package/dist/engine/expressions/ast.d.ts +18 -0
- package/dist/engine/expressions/ast.js +9 -0
- package/dist/engine/expressions/ast.js.map +1 -0
- package/dist/engine/expressions/evaluate.d.ts +7 -0
- package/dist/engine/expressions/evaluate.js +47 -0
- package/dist/engine/expressions/evaluate.js.map +1 -0
- package/dist/engine/expressions/parser.d.ts +2 -0
- package/dist/engine/expressions/parser.js +173 -0
- package/dist/engine/expressions/parser.js.map +1 -0
- package/dist/engine/external-effects/authorization.d.ts +146 -0
- package/dist/engine/external-effects/authorization.js +222 -0
- package/dist/engine/external-effects/authorization.js.map +1 -0
- package/dist/engine/external-effects/idempotency.d.ts +14 -0
- package/dist/engine/external-effects/idempotency.js +26 -0
- package/dist/engine/external-effects/idempotency.js.map +1 -0
- package/dist/engine/external-effects/reconciliation.d.ts +11 -0
- package/dist/engine/external-effects/reconciliation.js +18 -0
- package/dist/engine/external-effects/reconciliation.js.map +1 -0
- package/dist/engine/results.d.ts +14 -0
- package/dist/engine/results.js +88 -0
- package/dist/engine/results.js.map +1 -0
- package/dist/engine/scheduler.d.ts +60 -0
- package/dist/engine/scheduler.js +225 -0
- package/dist/engine/scheduler.js.map +1 -0
- package/dist/engine/tdd/green-gate.d.ts +6 -0
- package/dist/engine/tdd/green-gate.js +72 -0
- package/dist/engine/tdd/green-gate.js.map +1 -0
- package/dist/engine/tdd/red-gate.d.ts +30 -0
- package/dist/engine/tdd/red-gate.js +531 -0
- package/dist/engine/tdd/red-gate.js.map +1 -0
- package/dist/engine/tdd/types.d.ts +89 -0
- package/dist/engine/tdd/types.js +38 -0
- package/dist/engine/tdd/types.js.map +1 -0
- package/dist/engine/verification.d.ts +56 -0
- package/dist/engine/verification.js +196 -0
- package/dist/engine/verification.js.map +1 -0
- package/dist/policy/profile.d.ts +24 -0
- package/dist/policy/profile.js +23 -0
- package/dist/policy/profile.js.map +1 -0
- package/dist/policy/risk.d.ts +33 -0
- package/dist/policy/risk.js +138 -0
- package/dist/policy/risk.js.map +1 -0
- package/dist/protocol/application.d.ts +196 -0
- package/dist/protocol/application.js +2 -0
- package/dist/protocol/application.js.map +1 -0
- package/dist/protocol/public-contract.d.ts +81 -0
- package/dist/protocol/public-contract.js +231 -0
- package/dist/protocol/public-contract.js.map +1 -0
- package/dist/protocol/work-package.d.ts +55 -0
- package/dist/protocol/work-package.js +2 -0
- package/dist/protocol/work-package.js.map +1 -0
- package/dist/registry/connectors/external-executor.d.ts +4 -0
- package/dist/registry/connectors/external-executor.js +249 -0
- package/dist/registry/connectors/external-executor.js.map +1 -0
- package/dist/registry/connectors/feishu-document.d.ts +21 -0
- package/dist/registry/connectors/feishu-document.js +197 -0
- package/dist/registry/connectors/feishu-document.js.map +1 -0
- package/dist/registry/connectors/git-commit.d.ts +32 -0
- package/dist/registry/connectors/git-commit.js +122 -0
- package/dist/registry/connectors/git-commit.js.map +1 -0
- package/dist/registry/connectors/issue.d.ts +68 -0
- package/dist/registry/connectors/issue.js +301 -0
- package/dist/registry/connectors/issue.js.map +1 -0
- package/dist/registry/connectors/knowledge-publish.d.ts +30 -0
- package/dist/registry/connectors/knowledge-publish.js +157 -0
- package/dist/registry/connectors/knowledge-publish.js.map +1 -0
- package/dist/registry/connectors/local-requirement.d.ts +19 -0
- package/dist/registry/connectors/local-requirement.js +177 -0
- package/dist/registry/connectors/local-requirement.js.map +1 -0
- package/dist/registry/connectors/manifest.d.ts +6 -0
- package/dist/registry/connectors/manifest.js +164 -0
- package/dist/registry/connectors/manifest.js.map +1 -0
- package/dist/registry/connectors/registry.d.ts +11 -0
- package/dist/registry/connectors/registry.js +34 -0
- package/dist/registry/connectors/registry.js.map +1 -0
- package/dist/registry/connectors/requirement-source.d.ts +46 -0
- package/dist/registry/connectors/requirement-source.js +513 -0
- package/dist/registry/connectors/requirement-source.js.map +1 -0
- package/dist/registry/connectors/runtime.d.ts +38 -0
- package/dist/registry/connectors/runtime.js +127 -0
- package/dist/registry/connectors/runtime.js.map +1 -0
- package/dist/registry/connectors/secret-detector.d.ts +19 -0
- package/dist/registry/connectors/secret-detector.js +85 -0
- package/dist/registry/connectors/secret-detector.js.map +1 -0
- package/dist/registry/connectors/semver.d.ts +8 -0
- package/dist/registry/connectors/semver.js +57 -0
- package/dist/registry/connectors/semver.js.map +1 -0
- package/dist/registry/connectors/types.d.ts +45 -0
- package/dist/registry/connectors/types.js +2 -0
- package/dist/registry/connectors/types.js.map +1 -0
- package/dist/registry/executors/registry.d.ts +15 -0
- package/dist/registry/executors/registry.js +68 -0
- package/dist/registry/executors/registry.js.map +1 -0
- package/dist/registry/executors/types.d.ts +19 -0
- package/dist/registry/executors/types.js +2 -0
- package/dist/registry/executors/types.js.map +1 -0
- package/dist/registry/skills/lock.d.ts +3 -0
- package/dist/registry/skills/lock.js +278 -0
- package/dist/registry/skills/lock.js.map +1 -0
- package/dist/registry/skills/resolver.d.ts +16 -0
- package/dist/registry/skills/resolver.js +353 -0
- package/dist/registry/skills/resolver.js.map +1 -0
- package/dist/registry/skills/types.d.ts +75 -0
- package/dist/registry/skills/types.js +9 -0
- package/dist/registry/skills/types.js.map +1 -0
- package/dist/resources/catalog.d.ts +20 -0
- package/dist/resources/catalog.js +111 -0
- package/dist/resources/catalog.js.map +1 -0
- package/dist/schemas/definitions.d.ts +5 -0
- package/dist/schemas/definitions.js +958 -0
- package/dist/schemas/definitions.js.map +1 -0
- package/dist/schemas/generate.d.ts +1 -0
- package/dist/schemas/generate.js +26 -0
- package/dist/schemas/generate.js.map +1 -0
- package/dist/schemas/index.d.ts +11 -0
- package/dist/schemas/index.js +54 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/storage/control-plane.d.ts +136 -0
- package/dist/storage/control-plane.js +688 -0
- package/dist/storage/control-plane.js.map +1 -0
- package/dist/storage/events.d.ts +36 -0
- package/dist/storage/events.js +185 -0
- package/dist/storage/events.js.map +1 -0
- package/dist/storage/external-action-payload.d.ts +33 -0
- package/dist/storage/external-action-payload.js +190 -0
- package/dist/storage/external-action-payload.js.map +1 -0
- package/dist/storage/files.d.ts +13 -0
- package/dist/storage/files.js +45 -0
- package/dist/storage/files.js.map +1 -0
- package/dist/storage/git.d.ts +4 -0
- package/dist/storage/git.js +21 -0
- package/dist/storage/git.js.map +1 -0
- package/dist/storage/project-config.d.ts +11 -0
- package/dist/storage/project-config.js +60 -0
- package/dist/storage/project-config.js.map +1 -0
- package/dist/storage/repository.d.ts +14 -0
- package/dist/storage/repository.js +151 -0
- package/dist/storage/repository.js.map +1 -0
- package/dist/storage/work-items.d.ts +77 -0
- package/dist/storage/work-items.js +373 -0
- package/dist/storage/work-items.js.map +1 -0
- package/dist/storage/workflow-trust.d.ts +38 -0
- package/dist/storage/workflow-trust.js +310 -0
- package/dist/storage/workflow-trust.js.map +1 -0
- package/dist/workflow-package/loader.d.ts +12 -0
- package/dist/workflow-package/loader.js +249 -0
- package/dist/workflow-package/loader.js.map +1 -0
- package/dist/workflow-package/lock.d.ts +6 -0
- package/dist/workflow-package/lock.js +12 -0
- package/dist/workflow-package/lock.js.map +1 -0
- package/dist/workflow-package/path-boundary.d.ts +5 -0
- package/dist/workflow-package/path-boundary.js +38 -0
- package/dist/workflow-package/path-boundary.js.map +1 -0
- package/dist/workflow-package/trust.d.ts +27 -0
- package/dist/workflow-package/trust.js +61 -0
- package/dist/workflow-package/trust.js.map +1 -0
- package/dist/workflow-package/types.d.ts +176 -0
- package/dist/workflow-package/types.js +9 -0
- package/dist/workflow-package/types.js.map +1 -0
- package/dist/workflow-package/workflow-v1.d.ts +3 -0
- package/dist/workflow-package/workflow-v1.js +274 -0
- package/dist/workflow-package/workflow-v1.js.map +1 -0
- package/package.json +40 -0
- package/resources/catalog.yaml +37 -0
- package/resources/connectors/github-cli.yaml +24 -0
- package/resources/connectors/gitlab-cli.yaml +24 -0
- package/resources/connectors/lark-cli.yaml +28 -0
- package/resources/skills/bug-fixing/SKILL.md +16 -0
- package/resources/skills/code-review/SKILL.md +16 -0
- package/resources/skills/documentation-editing/SKILL.md +16 -0
- package/resources/skills/documentation-exploration/SKILL.md +16 -0
- package/resources/skills/documentation-review/SKILL.md +16 -0
- package/resources/skills/requirement-exploration/SKILL.md +16 -0
- package/resources/skills/solution-design/SKILL.md +16 -0
- package/resources/skills/task-planning/SKILL.md +16 -0
- package/resources/skills/tdd-implementation/SKILL.md +16 -0
- package/resources/workflows/documentation-delivery/manifest.yaml +8 -0
- package/resources/workflows/documentation-delivery/profiles/governed.yaml +23 -0
- package/resources/workflows/documentation-delivery/profiles/quick.yaml +23 -0
- package/resources/workflows/documentation-delivery/profiles/standard.yaml +21 -0
- package/resources/workflows/documentation-delivery/workflow.yaml +109 -0
- package/resources/workflows/feature-delivery/manifest.yaml +8 -0
- package/resources/workflows/feature-delivery/profiles/governed.yaml +27 -0
- package/resources/workflows/feature-delivery/profiles/quick.yaml +25 -0
- package/resources/workflows/feature-delivery/profiles/standard.yaml +26 -0
- package/resources/workflows/feature-delivery/workflow.yaml +150 -0
- package/schemas/builtin-agent-action-v1.schema.json +509 -0
- package/schemas/builtin-application-acquire-input-v1.schema.json +25 -0
- package/schemas/builtin-application-artifact-create-input-v1.schema.json +49 -0
- package/schemas/builtin-application-decision-input-v1.schema.json +284 -0
- package/schemas/builtin-application-inspect-input-v1.schema.json +20 -0
- package/schemas/builtin-application-project-config-snapshot-v1.schema.json +289 -0
- package/schemas/builtin-application-project-config-v1.schema.json +293 -0
- package/schemas/builtin-application-start-input-v1.schema.json +92 -0
- package/schemas/builtin-application-submit-input-v1.schema.json +145 -0
- package/schemas/builtin-artifact-v1.schema.json +48 -0
- package/schemas/builtin-evidence-v1.schema.json +65 -0
- package/schemas/builtin-external-action-grant-v1.schema.json +298 -0
- package/schemas/builtin-external-action-request-v1.schema.json +288 -0
- package/schemas/builtin-external-binding-v1.schema.json +59 -0
- package/schemas/builtin-external-receipt-v1.schema.json +109 -0
- package/schemas/builtin-external-write-receipt-v1.schema.json +253 -0
- package/schemas/builtin-source-artifact-v1.schema.json +293 -0
- package/schemas/builtin-submit-result-v1.schema.json +111 -0
- package/schemas/builtin-tdd-cycle-evidence-v1.schema.json +119 -0
- package/schemas/builtin-tdd-node-test-report-v1.schema.json +103 -0
- package/schemas/builtin-tdd-trusted-evidence-v1.schema.json +184 -0
- package/schemas/builtin-work-item-v1.schema.json +201 -0
- package/schemas/builtin-work-package-v1.schema.json +254 -0
- package/schemas/builtin-workflow-selection-v1.schema.json +40 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import * as canonicalizeModule from "canonicalize";
|
|
4
|
+
import { parse, stringify } from "yaml";
|
|
5
|
+
import { sha256 } from "./digests.js";
|
|
6
|
+
import { resolveRepositoryRegularFile } from "./repository-path.js";
|
|
7
|
+
import { SchemaValidationError, validate } from "../schemas/index.js";
|
|
8
|
+
const canonicalize = canonicalizeModule.default;
|
|
9
|
+
export function artifactOutputId(reference) {
|
|
10
|
+
if (reference.outputId !== undefined && reference.outputId !== "")
|
|
11
|
+
return reference.outputId;
|
|
12
|
+
return reference.artifactType === "requirement-source" ? "requirement-source" : undefined;
|
|
13
|
+
}
|
|
14
|
+
export class ArtifactError extends Error {
|
|
15
|
+
code;
|
|
16
|
+
constructor(code, message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.name = "ArtifactError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const sectionContracts = {
|
|
23
|
+
specification: ["目标与背景", "范围", "需求", "验收条件", "约束", "排除项", "开放问题"],
|
|
24
|
+
design: ["上下文与架构", "组件职责和边界", "接口与数据契约", "安全与权限", "失败与恢复", "兼容或迁移", "测试策略", "已知权衡"],
|
|
25
|
+
plan: ["有序交付任务", "任务依赖", "精确文件范围", "验证方式", "人工检查点", "回滚方式"],
|
|
26
|
+
tasks: ["任务"],
|
|
27
|
+
"implementation-result": ["实际改动", "修改文件", "计划偏差", "验证摘要", "未完成项", "残余风险"],
|
|
28
|
+
"review-result": ["Findings"],
|
|
29
|
+
"verification-result": ["Gate/Evidence 矩阵", "未通过项", "覆盖限制", "残余风险"],
|
|
30
|
+
"knowledge-entry": ["背景", "需求或 Bug", "关键决策", "实现摘要", "验证证据", "适用范围", "限制", "相关引用"],
|
|
31
|
+
};
|
|
32
|
+
export function normalizeArtifactBody(body) {
|
|
33
|
+
const normalized = body
|
|
34
|
+
.replaceAll("\r\n", "\n")
|
|
35
|
+
.replaceAll("\r", "\n")
|
|
36
|
+
.split("\n")
|
|
37
|
+
.map((line) => line.replace(/[ \t]+$/u, ""))
|
|
38
|
+
.join("\n")
|
|
39
|
+
.replace(/\n*$/u, "");
|
|
40
|
+
return `${normalized}\n`;
|
|
41
|
+
}
|
|
42
|
+
export function computeArtifactContentHash(metadataWithoutHash, body) {
|
|
43
|
+
const canonicalMetadata = canonicalize(metadataWithoutHash);
|
|
44
|
+
if (canonicalMetadata === undefined) {
|
|
45
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "Artifact 元数据无法规范化。");
|
|
46
|
+
}
|
|
47
|
+
return sha256(`${canonicalMetadata}\n${normalizeArtifactBody(body)}`);
|
|
48
|
+
}
|
|
49
|
+
export function createArtifactDocument(input) {
|
|
50
|
+
const body = normalizeArtifactBody(input.body);
|
|
51
|
+
verifySections(input.artifactType, body, true);
|
|
52
|
+
const metadataWithoutHash = {
|
|
53
|
+
artifactType: input.artifactType,
|
|
54
|
+
outputId: input.outputId,
|
|
55
|
+
schemaVersion: 1,
|
|
56
|
+
workItemId: input.workItemId,
|
|
57
|
+
stageId: input.stageId,
|
|
58
|
+
attemptId: input.attemptId,
|
|
59
|
+
revision: 1,
|
|
60
|
+
};
|
|
61
|
+
const contentHash = computeArtifactContentHash(metadataWithoutHash, body);
|
|
62
|
+
const metadata = { ...metadataWithoutHash, contentHash };
|
|
63
|
+
return {
|
|
64
|
+
content: `---\n${stringify(metadata, { lineWidth: 0 })}---\n${body}`,
|
|
65
|
+
reference: {
|
|
66
|
+
artifactType: input.artifactType,
|
|
67
|
+
outputId: input.outputId,
|
|
68
|
+
schemaVersion: 1,
|
|
69
|
+
mediaType: "text/markdown",
|
|
70
|
+
revision: 1,
|
|
71
|
+
contentHash,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function decodeStrict(buffer) {
|
|
76
|
+
if (buffer.length >= 3 && buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) {
|
|
77
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_ENCODING_INVALID", "Artifact 禁止 UTF-8 BOM。");
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_ENCODING_INVALID", "Artifact 必须是严格 UTF-8。");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function readArtifact(filename) {
|
|
87
|
+
const content = decodeStrict(await readFile(filename));
|
|
88
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/u.exec(content);
|
|
89
|
+
if (match === null) {
|
|
90
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "Artifact 缺少完整 YAML front matter。");
|
|
91
|
+
}
|
|
92
|
+
let metadata;
|
|
93
|
+
try {
|
|
94
|
+
metadata = validate("builtin.artifact.v1", parse(match[1]));
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error instanceof SchemaValidationError) {
|
|
98
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `${error.path}: ${error.message}`);
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
return { metadata, body: match[2] };
|
|
103
|
+
}
|
|
104
|
+
function escapeRegExp(value) {
|
|
105
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
106
|
+
}
|
|
107
|
+
function sectionBody(type, section, body) {
|
|
108
|
+
const heading = new RegExp(`^#{1,6}\\s+${escapeRegExp(section)}\\s*$`, "mu");
|
|
109
|
+
const match = heading.exec(body);
|
|
110
|
+
if (match === null)
|
|
111
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_INCOMPLETE", `${type} 缺少必需章节:${section}`);
|
|
112
|
+
const afterHeading = body.slice(match.index + match[0].length).replace(/^\r?\n/u, "");
|
|
113
|
+
const nextHeading = /^#{1,6}\s+/mu.exec(afterHeading);
|
|
114
|
+
const content = afterHeading.slice(0, nextHeading?.index ?? afterHeading.length).trim();
|
|
115
|
+
if (content === "")
|
|
116
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_INCOMPLETE", `${type} 的必需章节为空:${section}`);
|
|
117
|
+
return content;
|
|
118
|
+
}
|
|
119
|
+
function isRecord(value) {
|
|
120
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
121
|
+
}
|
|
122
|
+
function structuredYaml(type, section, body) {
|
|
123
|
+
const fenced = /```yaml\s*\n([\s\S]*?)\n```/u.exec(sectionBody(type, section, body));
|
|
124
|
+
if (fenced === null)
|
|
125
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `${type}.${section} 缺少 fenced YAML。`);
|
|
126
|
+
const value = parse(fenced[1]);
|
|
127
|
+
if (!isRecord(value))
|
|
128
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `${type}.${section} 必须是对象。`);
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
function requireString(record, field) {
|
|
132
|
+
const value = record[field];
|
|
133
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
134
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `结构化字段 ${field} 必须是非空字符串。`);
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
function verifyStructuredContent(type, body) {
|
|
139
|
+
if (type === "tasks") {
|
|
140
|
+
const tasks = structuredYaml(type, "任务", body).tasks;
|
|
141
|
+
if (!Array.isArray(tasks) || tasks.length === 0)
|
|
142
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "tasks 必须是非空数组。");
|
|
143
|
+
for (const task of tasks) {
|
|
144
|
+
if (!isRecord(task) || !Array.isArray(task.dependencies))
|
|
145
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "task 结构不完整。");
|
|
146
|
+
requireString(task, "id");
|
|
147
|
+
requireString(task, "completion");
|
|
148
|
+
if (!["pending", "in_progress", "completed", "blocked"].includes(requireString(task, "status"))) {
|
|
149
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "task.status 不合法。");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (type === "review-result") {
|
|
154
|
+
const findings = structuredYaml(type, "Findings", body).findings;
|
|
155
|
+
if (!Array.isArray(findings))
|
|
156
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "findings 必须是数组。");
|
|
157
|
+
for (const finding of findings) {
|
|
158
|
+
if (!isRecord(finding))
|
|
159
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding 必须是对象。");
|
|
160
|
+
requireString(finding, "id");
|
|
161
|
+
if (!["P0", "P1", "P2", "P3"].includes(requireString(finding, "severity"))) {
|
|
162
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.severity 不合法。");
|
|
163
|
+
}
|
|
164
|
+
requireString(finding, "description");
|
|
165
|
+
requireString(finding, "evidence");
|
|
166
|
+
const findingPath = requireString(finding, "path");
|
|
167
|
+
if (path.isAbsolute(findingPath) || findingPath.split(/[\\/]/u).includes("..")) {
|
|
168
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.path 必须是仓库相对路径。");
|
|
169
|
+
}
|
|
170
|
+
if (!["open", "fixed", "accepted", "false-positive"].includes(requireString(finding, "disposition"))) {
|
|
171
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.disposition 不合法。");
|
|
172
|
+
}
|
|
173
|
+
if (finding.line !== undefined && (!Number.isInteger(finding.line) || finding.line < 1)) {
|
|
174
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.line 必须是正整数。");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (type === "verification-result") {
|
|
179
|
+
const gates = structuredYaml(type, "Gate/Evidence 矩阵", body).gates;
|
|
180
|
+
if (!Array.isArray(gates) || gates.length === 0)
|
|
181
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "gates 必须是非空数组。");
|
|
182
|
+
for (const gate of gates) {
|
|
183
|
+
if (!isRecord(gate) || typeof gate.required !== "boolean")
|
|
184
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "gate 结构不完整。");
|
|
185
|
+
for (const field of ["gateId", "expectedLevel", "evidenceId", "workspaceTreeDigest", "result"])
|
|
186
|
+
requireString(gate, field);
|
|
187
|
+
if (!(typeof gate.occurredAt === "string" || gate.occurredAt instanceof Date)) {
|
|
188
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "gate.occurredAt 必须是时间字符串。");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function verifySections(type, body, allowUnregisteredType) {
|
|
194
|
+
const sections = sectionContracts[type];
|
|
195
|
+
if (sections === undefined) {
|
|
196
|
+
if (allowUnregisteredType)
|
|
197
|
+
return;
|
|
198
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_NOT_FOUND", `未注册内置 Artifact 类型:${type}`);
|
|
199
|
+
}
|
|
200
|
+
for (const section of sections)
|
|
201
|
+
sectionBody(type, section, body);
|
|
202
|
+
verifyStructuredContent(type, body);
|
|
203
|
+
}
|
|
204
|
+
export async function verifyArtifact(filename, expected, options = {}) {
|
|
205
|
+
const root = await realpath(expected.repositoryRoot);
|
|
206
|
+
const relative = path.relative(path.resolve(expected.repositoryRoot), path.resolve(filename));
|
|
207
|
+
if (relative.startsWith("..") || path.isAbsolute(relative) || relative === "") {
|
|
208
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_REFERENCE_INVALID", "Artifact 路径越出仓库边界。");
|
|
209
|
+
}
|
|
210
|
+
let actual;
|
|
211
|
+
try {
|
|
212
|
+
actual = await resolveRepositoryRegularFile(root, relative.split(path.sep).join("/"));
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_REFERENCE_INVALID", "Artifact 必须是仓库内的普通文件,且不能经过符号链接。");
|
|
216
|
+
}
|
|
217
|
+
const artifact = await readArtifact(actual);
|
|
218
|
+
const { metadata } = artifact;
|
|
219
|
+
if (metadata.artifactType !== expected.artifactType ||
|
|
220
|
+
metadata.workItemId !== expected.workItemId ||
|
|
221
|
+
metadata.stageId !== expected.stageId ||
|
|
222
|
+
metadata.attemptId !== expected.attemptId) {
|
|
223
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_REFERENCE_INVALID", "Artifact 类型或生产者身份与预期不符。");
|
|
224
|
+
}
|
|
225
|
+
verifySections(metadata.artifactType, artifact.body, options.allowUnregisteredType === true);
|
|
226
|
+
const { contentHash, ...metadataWithoutHash } = metadata;
|
|
227
|
+
const actualHash = computeArtifactContentHash(metadataWithoutHash, artifact.body);
|
|
228
|
+
if (actualHash !== contentHash) {
|
|
229
|
+
throw new ArtifactError("WSSPEC_ARTIFACT_HASH_MISMATCH", "Artifact 内容哈希与规范化内容不匹配。");
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
artifactType: metadata.artifactType,
|
|
233
|
+
...(metadata.outputId === undefined ? {} : { outputId: metadata.outputId }),
|
|
234
|
+
schemaVersion: metadata.schemaVersion,
|
|
235
|
+
path: relative.split(path.sep).join("/"),
|
|
236
|
+
mediaType: "text/markdown",
|
|
237
|
+
revision: metadata.revision,
|
|
238
|
+
contentHash,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/domain/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TreeEntry {
|
|
2
|
+
path: string;
|
|
3
|
+
type: "file" | "symlink" | "deleted";
|
|
4
|
+
mode: "100644" | "100755" | "120000" | "deleted";
|
|
5
|
+
digest?: string;
|
|
6
|
+
target?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function sha256(content: string | Uint8Array): string;
|
|
9
|
+
export declare function computeWorkspaceSnapshot(cwd: string): Promise<TreeEntry[]>;
|
|
10
|
+
export declare function computeWorkspaceTreeDigest(cwd: string): Promise<string>;
|
|
11
|
+
export declare function computeArtifactTreeDigest(cwd: string): Promise<string>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { lstat, readFile, readdir, readlink } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { repositoryRoot, runGitRaw } from "../storage/git.js";
|
|
5
|
+
export function sha256(content) {
|
|
6
|
+
return `sha256:${createHash("sha256").update(content).digest("hex")}`;
|
|
7
|
+
}
|
|
8
|
+
function volatileRuntimePath(candidate) {
|
|
9
|
+
return /^\.wsspec\/work-items\/[^/]+\/control-plane\/(?:runtime\.json|events\.jsonl|runtime\.lock)$/u.test(candidate);
|
|
10
|
+
}
|
|
11
|
+
function artifactPath(candidate) {
|
|
12
|
+
return /^\.wsspec\/work-items\/[^/]+\/artifacts\//u.test(candidate);
|
|
13
|
+
}
|
|
14
|
+
async function snapshotPaths(root, paths) {
|
|
15
|
+
const entries = [];
|
|
16
|
+
for (const relativePath of paths) {
|
|
17
|
+
const absolutePath = path.join(root, relativePath);
|
|
18
|
+
try {
|
|
19
|
+
const stat = await lstat(absolutePath);
|
|
20
|
+
if (stat.isSymbolicLink()) {
|
|
21
|
+
entries.push({ path: relativePath, type: "symlink", mode: "120000", target: await readlink(absolutePath) });
|
|
22
|
+
}
|
|
23
|
+
else if (stat.isFile()) {
|
|
24
|
+
entries.push({
|
|
25
|
+
path: relativePath,
|
|
26
|
+
type: "file",
|
|
27
|
+
mode: (stat.mode & 0o111) === 0 ? "100644" : "100755",
|
|
28
|
+
digest: sha256(await readFile(absolutePath)),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error.code === "ENOENT")
|
|
34
|
+
entries.push({ path: relativePath, type: "deleted", mode: "deleted" });
|
|
35
|
+
else
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return entries;
|
|
40
|
+
}
|
|
41
|
+
async function listedPaths(root) {
|
|
42
|
+
const output = await runGitRaw(root, ["ls-files", "-z", "--cached", "--others", "--exclude-standard"]);
|
|
43
|
+
return output.split("\0").filter((candidate) => candidate !== "")
|
|
44
|
+
.sort((left, right) => Buffer.from(left).compare(Buffer.from(right)));
|
|
45
|
+
}
|
|
46
|
+
async function artifactPaths(root) {
|
|
47
|
+
const itemRoot = path.join(root, ".wsspec", "work-items");
|
|
48
|
+
const result = [];
|
|
49
|
+
const walk = async (directory, relative) => {
|
|
50
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
51
|
+
entries.sort((left, right) => Buffer.from(left.name).compare(Buffer.from(right.name)));
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
const childRelative = `${relative}/${entry.name}`;
|
|
54
|
+
if (entry.isDirectory())
|
|
55
|
+
await walk(path.join(directory, entry.name), childRelative);
|
|
56
|
+
else
|
|
57
|
+
result.push(childRelative);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
let items;
|
|
61
|
+
try {
|
|
62
|
+
items = await readdir(itemRoot, { withFileTypes: true });
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error.code === "ENOENT")
|
|
66
|
+
return [];
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
items.sort((left, right) => Buffer.from(left.name).compare(Buffer.from(right.name)));
|
|
70
|
+
for (const item of items) {
|
|
71
|
+
if (!item.isDirectory())
|
|
72
|
+
continue;
|
|
73
|
+
const artifacts = path.join(itemRoot, item.name, "artifacts");
|
|
74
|
+
const relative = `.wsspec/work-items/${item.name}/artifacts`;
|
|
75
|
+
let stat;
|
|
76
|
+
try {
|
|
77
|
+
stat = await lstat(artifacts);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (error.code === "ENOENT")
|
|
81
|
+
continue;
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
if (stat.isDirectory())
|
|
85
|
+
await walk(artifacts, relative);
|
|
86
|
+
else
|
|
87
|
+
result.push(relative);
|
|
88
|
+
}
|
|
89
|
+
return result.sort((left, right) => Buffer.from(left).compare(Buffer.from(right)));
|
|
90
|
+
}
|
|
91
|
+
export async function computeWorkspaceSnapshot(cwd) {
|
|
92
|
+
const root = await repositoryRoot(cwd);
|
|
93
|
+
const paths = (await listedPaths(root)).filter((candidate) => !artifactPath(candidate)
|
|
94
|
+
&& !volatileRuntimePath(candidate) && !candidate.startsWith(".wsspec/archive/"));
|
|
95
|
+
return snapshotPaths(root, paths);
|
|
96
|
+
}
|
|
97
|
+
export async function computeWorkspaceTreeDigest(cwd) {
|
|
98
|
+
const entries = await computeWorkspaceSnapshot(cwd);
|
|
99
|
+
return sha256(`${JSON.stringify({ version: 1, entries })}\n`);
|
|
100
|
+
}
|
|
101
|
+
export async function computeArtifactTreeDigest(cwd) {
|
|
102
|
+
const root = await repositoryRoot(cwd);
|
|
103
|
+
const entries = await snapshotPaths(root, await artifactPaths(root));
|
|
104
|
+
return sha256(`${JSON.stringify({ version: 1, entries })}\n`);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=digests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digests.js","sourceRoot":"","sources":["../../src/domain/digests.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { WorkPackage } from "../protocol/work-package.js";
|
|
2
|
+
export type ExternalTarget = "issue" | "knowledge";
|
|
3
|
+
export interface ExternalBinding {
|
|
4
|
+
version: 1;
|
|
5
|
+
kind: "external-binding";
|
|
6
|
+
target: ExternalTarget;
|
|
7
|
+
exists: true;
|
|
8
|
+
stableId: string;
|
|
9
|
+
externalWorkItemId: string;
|
|
10
|
+
publishStepId: string;
|
|
11
|
+
publishAttemptId: string;
|
|
12
|
+
publishInputDigest: string;
|
|
13
|
+
expectedPublishedContentDigest: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ExternalReceipt {
|
|
16
|
+
version: 1;
|
|
17
|
+
kind: "external-receipt";
|
|
18
|
+
target: ExternalTarget;
|
|
19
|
+
stableId: string;
|
|
20
|
+
externalEffectKind?: "issue.comment";
|
|
21
|
+
externalEffectId?: string;
|
|
22
|
+
externalWorkItemId: string;
|
|
23
|
+
publishStepId: string;
|
|
24
|
+
publishAttemptId: string;
|
|
25
|
+
publishInputDigest: string;
|
|
26
|
+
publishedContentDigest: string;
|
|
27
|
+
readBackContentDigest: string;
|
|
28
|
+
status: "confirmed";
|
|
29
|
+
readBackStatus: "confirmed" | "stale" | "failed";
|
|
30
|
+
}
|
|
31
|
+
export declare function parseExternalReceipt(value: unknown): ExternalReceipt | undefined;
|
|
32
|
+
export declare function parseExternalBinding(value: unknown): ExternalBinding | undefined;
|
|
33
|
+
export declare function externalPublishTarget(action: string | undefined): ExternalTarget | undefined;
|
|
34
|
+
export declare function createExternalBinding(input: {
|
|
35
|
+
target: ExternalTarget;
|
|
36
|
+
workPackage: WorkPackage;
|
|
37
|
+
discoveryBinding: unknown;
|
|
38
|
+
expectedPublishedContentDigest?: string;
|
|
39
|
+
}): ExternalBinding;
|
|
40
|
+
export declare function externalReceiptValues(evidence: Readonly<Record<string, unknown>>): unknown[];
|
|
41
|
+
export declare function externalBindingValues(evidence: Readonly<Record<string, unknown>>): unknown[];
|
|
42
|
+
export declare function assertExternalReceipts(evidence: Readonly<Record<string, unknown>>, code: `WSSPEC_${string}`): void;
|
|
43
|
+
export declare function externalReceiptMatches(input: {
|
|
44
|
+
receipt: unknown;
|
|
45
|
+
target: ExternalTarget;
|
|
46
|
+
binding: unknown;
|
|
47
|
+
readBackRequired: boolean;
|
|
48
|
+
}): boolean;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as canonicalizeModule from "canonicalize";
|
|
2
|
+
import { sha256 } from "./digests.js";
|
|
3
|
+
import { validate } from "../schemas/index.js";
|
|
4
|
+
const canonicalize = canonicalizeModule.default;
|
|
5
|
+
function record(value) {
|
|
6
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
7
|
+
}
|
|
8
|
+
export function parseExternalReceipt(value) {
|
|
9
|
+
try {
|
|
10
|
+
return validate("builtin.external-receipt.v1", value);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function parseExternalBinding(value) {
|
|
17
|
+
try {
|
|
18
|
+
return validate("builtin.external-binding.v1", value);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function normalizedArtifacts(artifacts) {
|
|
25
|
+
if (artifacts.length === 0 || artifacts.some((artifact) => typeof artifact.contentHash !== "string" || artifact.contentHash === "")) {
|
|
26
|
+
throw new Error("External publish input 必须包含至少一个具有内容摘要的 Artifact。");
|
|
27
|
+
}
|
|
28
|
+
return artifacts.map((artifact) => ({
|
|
29
|
+
artifactType: artifact.artifactType,
|
|
30
|
+
...(artifact.outputId === undefined ? {} : { outputId: artifact.outputId }),
|
|
31
|
+
schemaVersion: artifact.schemaVersion,
|
|
32
|
+
...(artifact.path === undefined ? {} : { path: artifact.path.replaceAll("\\", "/") }),
|
|
33
|
+
...(artifact.revision === undefined ? {} : { revision: artifact.revision }),
|
|
34
|
+
...(artifact.contentHash === undefined ? {} : { contentHash: artifact.contentHash }),
|
|
35
|
+
...(artifact.mediaType === undefined ? {} : { mediaType: artifact.mediaType }),
|
|
36
|
+
...(artifact.contentLevel === undefined ? {} : { contentLevel: artifact.contentLevel }),
|
|
37
|
+
})).sort((left, right) => Buffer.from(JSON.stringify(left)).compare(Buffer.from(JSON.stringify(right))));
|
|
38
|
+
}
|
|
39
|
+
export function externalPublishTarget(action) {
|
|
40
|
+
if (action === "issue.update")
|
|
41
|
+
return "issue";
|
|
42
|
+
if (action === "knowledge.publish")
|
|
43
|
+
return "knowledge";
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
export function createExternalBinding(input) {
|
|
47
|
+
const discovery = record(input.discoveryBinding);
|
|
48
|
+
if (discovery?.exists !== true || typeof discovery.stableId !== "string" || discovery.stableId === ""
|
|
49
|
+
|| typeof discovery.externalWorkItemId !== "string" || discovery.externalWorkItemId !== input.workPackage.workItemId) {
|
|
50
|
+
throw new Error(`External ${input.target} discovery binding 缺少当前 Work Item 的稳定身份。`);
|
|
51
|
+
}
|
|
52
|
+
const artifacts = normalizedArtifacts(input.workPackage.artifacts);
|
|
53
|
+
const content = canonicalize({ version: 1, target: input.target, artifacts });
|
|
54
|
+
const publishInput = canonicalize({
|
|
55
|
+
version: 1,
|
|
56
|
+
target: input.target,
|
|
57
|
+
workItemId: input.workPackage.workItemId,
|
|
58
|
+
stepId: input.workPackage.stepId,
|
|
59
|
+
attemptId: input.workPackage.attemptId,
|
|
60
|
+
artifacts,
|
|
61
|
+
});
|
|
62
|
+
if (content === undefined || publishInput === undefined)
|
|
63
|
+
throw new Error(`External ${input.target} publish input 无法规范化。`);
|
|
64
|
+
const expectedPublishedContentDigest = input.target === "knowledge"
|
|
65
|
+
? input.expectedPublishedContentDigest
|
|
66
|
+
: sha256(content);
|
|
67
|
+
if ((input.target === "knowledge" && !/^sha256:[a-f0-9]{64}$/u.test(expectedPublishedContentDigest ?? ""))
|
|
68
|
+
|| (input.target === "issue" && input.expectedPublishedContentDigest !== undefined)) {
|
|
69
|
+
throw new Error(`External ${input.target} publish content 摘要缺失或不符合生成规则。`);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
version: 1,
|
|
73
|
+
kind: "external-binding",
|
|
74
|
+
target: input.target,
|
|
75
|
+
exists: true,
|
|
76
|
+
stableId: discovery.stableId,
|
|
77
|
+
externalWorkItemId: discovery.externalWorkItemId,
|
|
78
|
+
publishStepId: input.workPackage.stepId,
|
|
79
|
+
publishAttemptId: input.workPackage.attemptId,
|
|
80
|
+
publishInputDigest: sha256(publishInput),
|
|
81
|
+
expectedPublishedContentDigest: expectedPublishedContentDigest,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function externalReceiptValues(evidence) {
|
|
85
|
+
return Object.entries(evidence).filter(([key, value]) => key.startsWith("external-receipt:") || record(value)?.kind === "external-receipt")
|
|
86
|
+
.map(([, value]) => value);
|
|
87
|
+
}
|
|
88
|
+
export function externalBindingValues(evidence) {
|
|
89
|
+
return Object.entries(evidence).filter(([key, value]) => key.startsWith("external-binding:") || record(value)?.kind === "external-binding")
|
|
90
|
+
.map(([, value]) => value);
|
|
91
|
+
}
|
|
92
|
+
export function assertExternalReceipts(evidence, code) {
|
|
93
|
+
const invalidBinding = Object.entries(evidence)
|
|
94
|
+
.filter(([key, value]) => key.startsWith("external-binding:") || record(value)?.kind === "external-binding")
|
|
95
|
+
.some(([key, value]) => {
|
|
96
|
+
const binding = parseExternalBinding(value);
|
|
97
|
+
return binding === undefined
|
|
98
|
+
|| key !== `external-binding:${binding.target}`;
|
|
99
|
+
});
|
|
100
|
+
const invalidReceipt = Object.entries(evidence)
|
|
101
|
+
.filter(([key, value]) => key.startsWith("external-receipt:") || record(value)?.kind === "external-receipt")
|
|
102
|
+
.some(([key, value]) => {
|
|
103
|
+
const receipt = parseExternalReceipt(value);
|
|
104
|
+
if (receipt === undefined)
|
|
105
|
+
return true;
|
|
106
|
+
return key !== `external-receipt:${receipt.target}`
|
|
107
|
+
|| !externalReceiptMatches({
|
|
108
|
+
receipt,
|
|
109
|
+
target: receipt.target,
|
|
110
|
+
binding: evidence[`external-binding:${receipt.target}`],
|
|
111
|
+
readBackRequired: true,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
if (invalidBinding || invalidReceipt) {
|
|
115
|
+
const error = new Error("External receipt 不符合严格身份与内容摘要契约。");
|
|
116
|
+
error.code = code;
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export function externalReceiptMatches(input) {
|
|
121
|
+
const receipt = parseExternalReceipt(input.receipt);
|
|
122
|
+
const binding = parseExternalBinding(input.binding);
|
|
123
|
+
return receipt !== undefined
|
|
124
|
+
&& binding !== undefined
|
|
125
|
+
&& receipt.target === input.target
|
|
126
|
+
&& binding.target === input.target
|
|
127
|
+
&& receipt.stableId === binding.stableId
|
|
128
|
+
&& receipt.externalWorkItemId === binding.externalWorkItemId
|
|
129
|
+
&& receipt.publishStepId === binding.publishStepId
|
|
130
|
+
&& receipt.publishAttemptId === binding.publishAttemptId
|
|
131
|
+
&& receipt.publishInputDigest === binding.publishInputDigest
|
|
132
|
+
&& receipt.publishedContentDigest === binding.expectedPublishedContentDigest
|
|
133
|
+
&& receipt.readBackContentDigest === binding.expectedPublishedContentDigest
|
|
134
|
+
&& receipt.status === "confirmed"
|
|
135
|
+
&& (!input.readBackRequired || (receipt.readBackStatus === "confirmed"
|
|
136
|
+
&& receipt.readBackContentDigest === receipt.publishedContentDigest));
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=external-receipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-receipt.js","sourceRoot":"","sources":["../../src/domain/external-receipt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type RepositoryId = `repo-${string}`;
|
|
2
|
+
export type WorkItemId = `WSS-${string}`;
|
|
3
|
+
export type ErrorCode = `WSSPEC_${string}`;
|
|
4
|
+
export type StageId = string;
|
|
5
|
+
export type AttemptId = `attempt-${string}`;
|
|
6
|
+
export declare const isWorkItemId: (value: string) => value is WorkItemId;
|
|
7
|
+
export declare const isErrorCode: (value: string) => value is ErrorCode;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const workItemIdPattern = /^WSS-[A-Za-z0-9-]+$/;
|
|
2
|
+
const errorCodePattern = /^WSSPEC_[A-Z0-9_]+$/;
|
|
3
|
+
export const isWorkItemId = (value) => workItemIdPattern.test(value);
|
|
4
|
+
export const isErrorCode = (value) => errorCodePattern.test(value);
|
|
5
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/domain/ids.ts"],"names":[],"mappings":"AAMA,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAChD,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAuB,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClG,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAsB,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function isRepositoryRelativePattern(value: string): boolean;
|
|
2
|
+
export declare function matchesRepositoryPath(pattern: string, candidate: string): boolean;
|
|
3
|
+
export declare function resolveRepositoryRegularFile(root: string, relativePath: string): Promise<string>;
|