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,157 @@
|
|
|
1
|
+
import { canonicalRequirementText, MAX_REQUIREMENT_BYTES, MAX_REQUIREMENT_CHARACTERS } from "./local-requirement.js";
|
|
2
|
+
import { parseExternalBinding } from "../../domain/external-receipt.js";
|
|
3
|
+
import { sha256 } from "../../domain/digests.js";
|
|
4
|
+
import { inspectDecodedCredentialSurface, inspectDecodedCredentialText } from "./secret-detector.js";
|
|
5
|
+
import { validateFeishuDocumentTarget } from "./feishu-document.js";
|
|
6
|
+
const tokenPattern = /^[A-Za-z0-9_-]{8,128}$/u;
|
|
7
|
+
const spacePattern = /^(?:[1-9][0-9]{5,31}|my_library)$/u;
|
|
8
|
+
const allowedKeys = new Set(["documentToken", "folderToken", "markdown", "title", "wikiNode", "wikiSpace"]);
|
|
9
|
+
export class KnowledgePublishError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
constructor(code, message) {
|
|
12
|
+
super(`${code}: ${message}`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.name = "KnowledgePublishError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function fail(code, message) {
|
|
18
|
+
throw new KnowledgePublishError(code, message);
|
|
19
|
+
}
|
|
20
|
+
function record(value) {
|
|
21
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)
|
|
22
|
+
|| (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)) {
|
|
23
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "知识发布目标包含不允许的字段。");
|
|
24
|
+
}
|
|
25
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
26
|
+
if (Reflect.ownKeys(value).some((key) => typeof key !== "string" || !allowedKeys.has(key))
|
|
27
|
+
|| Object.values(descriptors).some((descriptor) => !descriptor.enumerable || !("value" in descriptor))) {
|
|
28
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "知识发布目标包含不允许的属性。");
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function title(value) {
|
|
33
|
+
if (typeof value !== "string" || value === "" || Buffer.byteLength(value, "utf8") > 3_200) {
|
|
34
|
+
return fail("WSSPEC_KNOWLEDGE_CONTENT_INVALID", "知识发布标题无效。");
|
|
35
|
+
}
|
|
36
|
+
const normalized = value.normalize("NFC").trim();
|
|
37
|
+
if (normalized === "" || [...normalized].length > 800 || /[\u0000-\u001f\u007f-\u009f]/u.test(normalized)
|
|
38
|
+
|| !inspectDecodedCredentialText(value, { maximumBytes: 3_200, maximumDecodeRounds: 4 }).ok
|
|
39
|
+
|| !inspectDecodedCredentialText(normalized, { maximumBytes: 3_200, maximumDecodeRounds: 4 }).ok) {
|
|
40
|
+
return fail("WSSPEC_KNOWLEDGE_CONTENT_INVALID", "知识发布标题必须是有界单行文本。");
|
|
41
|
+
}
|
|
42
|
+
return normalized;
|
|
43
|
+
}
|
|
44
|
+
function markdown(value) {
|
|
45
|
+
if (typeof value !== "string" || Buffer.byteLength(value, "utf8") > MAX_REQUIREMENT_BYTES || [...value].length > MAX_REQUIREMENT_CHARACTERS) {
|
|
46
|
+
return fail("WSSPEC_KNOWLEDGE_CONTENT_INVALID", "知识发布 Markdown 超过上限。");
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
if (!inspectDecodedCredentialText(value, { maximumBytes: MAX_REQUIREMENT_BYTES, maximumDecodeRounds: 4 }).ok) {
|
|
50
|
+
return fail("WSSPEC_KNOWLEDGE_CONTENT_INVALID", "知识发布 Markdown 包含不允许的凭据或编码表面。");
|
|
51
|
+
}
|
|
52
|
+
const canonical = canonicalRequirementText(value);
|
|
53
|
+
if (!inspectDecodedCredentialText(canonical, { maximumBytes: MAX_REQUIREMENT_BYTES, maximumDecodeRounds: 4 }).ok) {
|
|
54
|
+
return fail("WSSPEC_KNOWLEDGE_CONTENT_INVALID", "知识发布 Markdown 包含不允许的凭据或编码表面。");
|
|
55
|
+
}
|
|
56
|
+
return canonical;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return fail("WSSPEC_KNOWLEDGE_CONTENT_INVALID", "知识发布 Markdown 无效。");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function decoded(value, label) {
|
|
63
|
+
if (typeof value !== "string" || value === "" || Buffer.byteLength(value, "utf8") > 2_048) {
|
|
64
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", `${label} 无效。`);
|
|
65
|
+
}
|
|
66
|
+
const inspected = inspectDecodedCredentialSurface(value, { detectCredentialKeys: true, maximumBytes: 8_192, maximumDecodeRounds: 4 });
|
|
67
|
+
if (!inspected.ok)
|
|
68
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", `${label} 无效或包含凭据样式内容。`);
|
|
69
|
+
return inspected.value.normalize("NFC");
|
|
70
|
+
}
|
|
71
|
+
function plainToken(value, label) {
|
|
72
|
+
const result = decoded(value, label);
|
|
73
|
+
if (!tokenPattern.test(result))
|
|
74
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", `${label} 必须是规范 token。`);
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
function folderToken(value) {
|
|
78
|
+
const source = decoded(value, "folderToken");
|
|
79
|
+
if (source.includes("://")) {
|
|
80
|
+
let url;
|
|
81
|
+
try {
|
|
82
|
+
url = new URL(source);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "folderToken URL 无效。");
|
|
86
|
+
}
|
|
87
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
88
|
+
const host = url.hostname.toLowerCase();
|
|
89
|
+
if (url.protocol !== "https:" || url.port !== "" || (!host.endsWith(".feishu.cn") && !host.endsWith(".larksuite.com"))
|
|
90
|
+
|| parts.length !== 3 || parts[0] !== "drive" || parts[1] !== "folder"
|
|
91
|
+
|| url.search !== "" || url.hash !== "" || url.username !== "" || url.password !== "") {
|
|
92
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "folderToken URL 无效。");
|
|
93
|
+
}
|
|
94
|
+
return plainToken(parts[2], "folderToken");
|
|
95
|
+
}
|
|
96
|
+
return plainToken(source, "folderToken");
|
|
97
|
+
}
|
|
98
|
+
function wikiNode(value) {
|
|
99
|
+
const source = decoded(value, "wikiNode");
|
|
100
|
+
if (source.includes("://")) {
|
|
101
|
+
const target = documentTarget(source);
|
|
102
|
+
if (target.kind !== "wiki")
|
|
103
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "wikiNode URL 无效。");
|
|
104
|
+
return target.documentToken;
|
|
105
|
+
}
|
|
106
|
+
return plainToken(source, "wikiNode");
|
|
107
|
+
}
|
|
108
|
+
function documentTarget(value) {
|
|
109
|
+
try {
|
|
110
|
+
return validateFeishuDocumentTarget(value);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "文档或 wiki 目标无效。");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function wikiSpace(value) {
|
|
117
|
+
const result = decoded(value, "wikiSpace");
|
|
118
|
+
if (!spacePattern.test(result))
|
|
119
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "wikiSpace 无效。");
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
export function validateKnowledgePublishTarget(value) {
|
|
123
|
+
const source = record(value);
|
|
124
|
+
const normalizedTitle = title(source.title);
|
|
125
|
+
const normalizedMarkdown = markdown(source.markdown);
|
|
126
|
+
const createKeys = ["folderToken", "wikiNode", "wikiSpace"].filter((key) => source[key] !== undefined);
|
|
127
|
+
if (source.documentToken !== undefined) {
|
|
128
|
+
if (createKeys.length !== 0)
|
|
129
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "更新文档不能同时指定创建目标。");
|
|
130
|
+
const target = documentTarget(source.documentToken);
|
|
131
|
+
if (target.kind !== "token")
|
|
132
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "更新必须指定已解析的文档 token。");
|
|
133
|
+
return { operation: "update", documentToken: target.documentToken, title: normalizedTitle, markdown: normalizedMarkdown, stableId: `feishu:${target.documentToken}` };
|
|
134
|
+
}
|
|
135
|
+
if (createKeys.length !== 1)
|
|
136
|
+
return fail("WSSPEC_KNOWLEDGE_TARGET_INVALID", "创建文档必须在 folderToken、wikiNode、wikiSpace 中精确选择一个。");
|
|
137
|
+
const key = createKeys[0];
|
|
138
|
+
const targetToken = key === "folderToken" ? folderToken(source[key]) : key === "wikiNode" ? wikiNode(source[key]) : wikiSpace(source[key]);
|
|
139
|
+
const targetFlag = key === "folderToken" ? "--folder-token" : key === "wikiNode" ? "--wiki-node" : "--wiki-space";
|
|
140
|
+
return { operation: "create", targetFlag, targetToken, title: normalizedTitle, markdown: normalizedMarkdown, stableId: `feishu-target:${targetToken}` };
|
|
141
|
+
}
|
|
142
|
+
export function validateKnowledgeBinding(value, target) {
|
|
143
|
+
const binding = parseExternalBinding(value);
|
|
144
|
+
if (binding === undefined || binding.target !== "knowledge" || binding.stableId !== target.stableId
|
|
145
|
+
|| binding.expectedPublishedContentDigest !== sha256(target.markdown)) {
|
|
146
|
+
return fail("WSSPEC_KNOWLEDGE_BINDING_INVALID", "知识发布必须绑定当前严格 ExternalBinding。");
|
|
147
|
+
}
|
|
148
|
+
return binding;
|
|
149
|
+
}
|
|
150
|
+
export function mapKnowledgeError(error, readBack) {
|
|
151
|
+
if (error instanceof KnowledgePublishError)
|
|
152
|
+
throw error;
|
|
153
|
+
if (readBack)
|
|
154
|
+
return fail("WSSPEC_KNOWLEDGE_READBACK_FAILED", "知识发布写入后的回读失败。");
|
|
155
|
+
return fail("WSSPEC_KNOWLEDGE_WRITE_FAILED", "知识发布写入失败。");
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=knowledge-publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-publish.js","sourceRoot":"","sources":["../../../src/registry/connectors/knowledge-publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RequirementSourceInput } from "../../protocol/application.js";
|
|
2
|
+
export declare const MAX_REQUIREMENT_BYTES = 1048576;
|
|
3
|
+
export declare const MAX_REQUIREMENT_CHARACTERS = 262144;
|
|
4
|
+
export interface CapturedLocalRequirement {
|
|
5
|
+
type: "prompt" | "file";
|
|
6
|
+
origin: string;
|
|
7
|
+
text: string;
|
|
8
|
+
contentDigest: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class LocalRequirementError extends Error {
|
|
11
|
+
readonly code: `WSSPEC_${string}`;
|
|
12
|
+
constructor(code: `WSSPEC_${string}`, message: string);
|
|
13
|
+
}
|
|
14
|
+
export declare function canonicalRequirementText(text: string): string;
|
|
15
|
+
export declare function readLocalRequirementFile(repositoryRoot: string, candidate: string): Promise<{
|
|
16
|
+
path: string;
|
|
17
|
+
text: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function captureLocalRequirement(root: string, source: RequirementSourceInput): Promise<CapturedLocalRequirement>;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { sha256 } from "../../domain/digests.js";
|
|
5
|
+
export const MAX_REQUIREMENT_BYTES = 1_048_576;
|
|
6
|
+
export const MAX_REQUIREMENT_CHARACTERS = 262_144;
|
|
7
|
+
export class LocalRequirementError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
constructor(code, message) {
|
|
10
|
+
super(`${code}: ${message}`);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = "LocalRequirementError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function fail(code, message) {
|
|
16
|
+
throw new LocalRequirementError(code, message);
|
|
17
|
+
}
|
|
18
|
+
function sameIdentity(left, right) {
|
|
19
|
+
return left.dev === right.dev
|
|
20
|
+
&& left.ino === right.ino
|
|
21
|
+
&& left.size === right.size
|
|
22
|
+
&& left.mtimeNs === right.mtimeNs
|
|
23
|
+
&& left.ctimeNs === right.ctimeNs
|
|
24
|
+
&& left.nlink === right.nlink;
|
|
25
|
+
}
|
|
26
|
+
function boundedText(text) {
|
|
27
|
+
if (Buffer.byteLength(text, "utf8") > MAX_REQUIREMENT_BYTES) {
|
|
28
|
+
return fail("WSSPEC_SOURCE_TOO_LARGE", "需求来源超过 1 MiB 字节上限。");
|
|
29
|
+
}
|
|
30
|
+
const canonical = (text.startsWith("\ufeff") ? text.slice(1) : text)
|
|
31
|
+
.replace(/\r\n?/gu, "\n")
|
|
32
|
+
.normalize("NFC");
|
|
33
|
+
if (Buffer.byteLength(canonical, "utf8") > MAX_REQUIREMENT_BYTES
|
|
34
|
+
|| [...canonical].length > MAX_REQUIREMENT_CHARACTERS) {
|
|
35
|
+
return fail("WSSPEC_SOURCE_TOO_LARGE", "需求来源超过字节或 Unicode 字符上限。");
|
|
36
|
+
}
|
|
37
|
+
if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/u.test(canonical)) {
|
|
38
|
+
return fail("WSSPEC_SOURCE_BINARY", "需求来源包含 NUL 或二进制控制字符。");
|
|
39
|
+
}
|
|
40
|
+
if (canonical.trim() === "")
|
|
41
|
+
return fail("WSSPEC_SOURCE_EMPTY", "需求来源不能为空。");
|
|
42
|
+
return canonical;
|
|
43
|
+
}
|
|
44
|
+
export function canonicalRequirementText(text) {
|
|
45
|
+
return boundedText(text);
|
|
46
|
+
}
|
|
47
|
+
function canonicalRelativePath(candidate) {
|
|
48
|
+
if (candidate === "" || path.isAbsolute(candidate) || candidate.includes("\\")
|
|
49
|
+
|| path.posix.normalize(candidate) !== candidate
|
|
50
|
+
|| candidate.split("/").some((part) => part === "" || part === "." || part === "..")) {
|
|
51
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求文件路径必须是规范的仓库相对 POSIX 路径。");
|
|
52
|
+
}
|
|
53
|
+
if (![".md", ".txt"].includes(path.posix.extname(candidate))) {
|
|
54
|
+
return fail("WSSPEC_SOURCE_TYPE_UNSUPPORTED", "只支持仓库内 .md 或 .txt 需求文件。");
|
|
55
|
+
}
|
|
56
|
+
return { accessPath: candidate, stablePath: candidate.normalize("NFC") };
|
|
57
|
+
}
|
|
58
|
+
function contained(root, target) {
|
|
59
|
+
const relative = path.relative(root, target);
|
|
60
|
+
return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
61
|
+
}
|
|
62
|
+
async function assertNoSymlinkComponents(root, relative) {
|
|
63
|
+
let current = root;
|
|
64
|
+
const parts = relative.split("/");
|
|
65
|
+
for (const [index, part] of parts.entries()) {
|
|
66
|
+
current = path.join(current, part);
|
|
67
|
+
let target;
|
|
68
|
+
try {
|
|
69
|
+
target = await lstat(current, { bigint: true });
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === "ELOOP") {
|
|
73
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求文件路径不能包含符号链接。");
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
if (target.isSymbolicLink())
|
|
78
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求文件路径不能包含符号链接。");
|
|
79
|
+
if (index < parts.length - 1 && !target.isDirectory()) {
|
|
80
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求文件父路径必须是普通目录。");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
export async function readLocalRequirementFile(repositoryRoot, candidate) {
|
|
86
|
+
const relative = canonicalRelativePath(candidate);
|
|
87
|
+
const root = await realpath(repositoryRoot);
|
|
88
|
+
const filename = await assertNoSymlinkComponents(root, relative.accessPath);
|
|
89
|
+
const before = await lstat(filename, { bigint: true });
|
|
90
|
+
if (!before.isFile())
|
|
91
|
+
return fail("WSSPEC_SOURCE_NOT_REGULAR_FILE", "需求来源必须是普通文件。");
|
|
92
|
+
if (before.nlink !== 1n)
|
|
93
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求来源必须只有一个文件名链接。");
|
|
94
|
+
if (before.size > BigInt(MAX_REQUIREMENT_BYTES)) {
|
|
95
|
+
return fail("WSSPEC_SOURCE_TOO_LARGE", "需求来源超过 1 MiB 字节上限。");
|
|
96
|
+
}
|
|
97
|
+
let handle;
|
|
98
|
+
try {
|
|
99
|
+
handle = await open(filename, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (["ELOOP", "EFTYPE"].includes(error.code ?? "")) {
|
|
103
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求文件在打开前被替换为符号链接。");
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const opened = await handle.stat({ bigint: true });
|
|
109
|
+
if (!opened.isFile())
|
|
110
|
+
return fail("WSSPEC_SOURCE_NOT_REGULAR_FILE", "需求来源必须是普通文件。");
|
|
111
|
+
if (opened.nlink !== 1n)
|
|
112
|
+
return fail("WSSPEC_SOURCE_CHANGED_DURING_READ", "需求文件链接数在打开期间发生变化。");
|
|
113
|
+
if (!sameIdentity(before, opened))
|
|
114
|
+
return fail("WSSPEC_SOURCE_CHANGED_DURING_READ", "需求文件在打开期间被替换。");
|
|
115
|
+
const openedPath = await realpath(filename);
|
|
116
|
+
const openedPathTarget = await lstat(openedPath, { bigint: true });
|
|
117
|
+
if (!contained(root, openedPath) || !sameIdentity(opened, openedPathTarget)) {
|
|
118
|
+
return fail("WSSPEC_SOURCE_PATH_INVALID", "需求文件打开后的真实路径或身份不匹配。");
|
|
119
|
+
}
|
|
120
|
+
if (opened.size > BigInt(MAX_REQUIREMENT_BYTES)) {
|
|
121
|
+
return fail("WSSPEC_SOURCE_TOO_LARGE", "需求来源超过 1 MiB 字节上限。");
|
|
122
|
+
}
|
|
123
|
+
const chunks = [];
|
|
124
|
+
let total = 0;
|
|
125
|
+
let position = 0;
|
|
126
|
+
while (true) {
|
|
127
|
+
const chunk = Buffer.allocUnsafe(Math.min(64 * 1024, MAX_REQUIREMENT_BYTES + 1 - total));
|
|
128
|
+
const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);
|
|
129
|
+
if (bytesRead === 0)
|
|
130
|
+
break;
|
|
131
|
+
chunks.push(chunk.subarray(0, bytesRead));
|
|
132
|
+
total += bytesRead;
|
|
133
|
+
position += bytesRead;
|
|
134
|
+
if (total > MAX_REQUIREMENT_BYTES)
|
|
135
|
+
return fail("WSSPEC_SOURCE_TOO_LARGE", "需求来源超过 1 MiB 字节上限。");
|
|
136
|
+
}
|
|
137
|
+
const after = await handle.stat({ bigint: true });
|
|
138
|
+
if (after.nlink !== 1n || !sameIdentity(opened, after) || BigInt(total) !== opened.size) {
|
|
139
|
+
return fail("WSSPEC_SOURCE_CHANGED_DURING_READ", "需求文件在读取期间发生变化。");
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const finalPath = await realpath(filename);
|
|
143
|
+
const finalTarget = await lstat(finalPath, { bigint: true });
|
|
144
|
+
if (!contained(root, finalPath) || !sameIdentity(after, finalTarget)) {
|
|
145
|
+
return fail("WSSPEC_SOURCE_CHANGED_DURING_READ", "需求文件路径在读取期间被替换。");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
if (error instanceof LocalRequirementError)
|
|
150
|
+
throw error;
|
|
151
|
+
return fail("WSSPEC_SOURCE_CHANGED_DURING_READ", "需求文件路径在读取期间消失或变化。");
|
|
152
|
+
}
|
|
153
|
+
let decoded;
|
|
154
|
+
try {
|
|
155
|
+
decoded = new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks, total));
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return fail("WSSPEC_SOURCE_BINARY", "需求来源不是严格 UTF-8 文本。");
|
|
159
|
+
}
|
|
160
|
+
return { path: relative.stablePath, text: boundedText(decoded) };
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
await handle.close();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export async function captureLocalRequirement(root, source) {
|
|
167
|
+
if (source.type === "prompt") {
|
|
168
|
+
const text = boundedText(source.text);
|
|
169
|
+
return { type: "prompt", origin: "prompt", text, contentDigest: sha256(text) };
|
|
170
|
+
}
|
|
171
|
+
if (source.type === "file") {
|
|
172
|
+
const captured = await readLocalRequirementFile(root, source.path);
|
|
173
|
+
return { type: "file", origin: captured.path, text: captured.text, contentDigest: sha256(captured.text) };
|
|
174
|
+
}
|
|
175
|
+
return fail("WSSPEC_SOURCE_TYPE_UNSUPPORTED", "当前阶段只支持 Prompt 和仓库内 Markdown/TXT 来源。");
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=local-requirement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-requirement.js","sourceRoot":"","sources":["../../../src/registry/connectors/local-requirement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ConnectorManifest } from "./types.js";
|
|
2
|
+
export declare class ConnectorManifestError extends Error {
|
|
3
|
+
readonly code: `WSSPEC_${string}`;
|
|
4
|
+
constructor(code: `WSSPEC_${string}`, message: string);
|
|
5
|
+
}
|
|
6
|
+
export declare function defineConnectorManifest(value: unknown): ConnectorManifest;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { parseSemVer } from "./semver.js";
|
|
2
|
+
const idPattern = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/u;
|
|
3
|
+
const securityClasses = new Set(["external-read", "external-write", "local-write"]);
|
|
4
|
+
const executables = new Set(["git", "gh", "glab", "lark-cli"]);
|
|
5
|
+
const environmentKeys = new Set(["HOME", "XDG_CONFIG_HOME", "GH_CONFIG_DIR", "GLAB_CONFIG_DIR", "LARK_CONFIG_DIR"]);
|
|
6
|
+
const rootKeys = ["argvTemplates", "capabilities", "doctor", "envPolicy", "executable", "id", "maxStdoutBytes", "minimumVersion", "securityClass", "timeoutMs"];
|
|
7
|
+
const auditedDoctorArgv = {
|
|
8
|
+
git: { version: ["--version"] },
|
|
9
|
+
gh: { version: ["--version"], auth: ["auth", "status", "--active"] },
|
|
10
|
+
glab: { version: ["--version"], auth: ["auth", "status"] },
|
|
11
|
+
"lark-cli": { version: ["--version"] },
|
|
12
|
+
};
|
|
13
|
+
export class ConnectorManifestError extends Error {
|
|
14
|
+
code;
|
|
15
|
+
constructor(code, message) {
|
|
16
|
+
super(`${code}: ${message}`);
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.name = "ConnectorManifestError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function invalid() {
|
|
22
|
+
throw new ConnectorManifestError("WSSPEC_CONNECTOR_MANIFEST_INVALID", "Connector Manifest 不符合完整安全合同。");
|
|
23
|
+
}
|
|
24
|
+
function record(value, keys) {
|
|
25
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
26
|
+
return invalid();
|
|
27
|
+
const source = value;
|
|
28
|
+
if (Object.keys(source).sort().join("\0") !== [...keys].sort().join("\0"))
|
|
29
|
+
return invalid();
|
|
30
|
+
return source;
|
|
31
|
+
}
|
|
32
|
+
function stringValue(value, pattern) {
|
|
33
|
+
if (typeof value !== "string" || value === "" || value.includes("\0") || (pattern !== undefined && !pattern.test(value)))
|
|
34
|
+
return invalid();
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function argv(value) {
|
|
38
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
39
|
+
return invalid();
|
|
40
|
+
return value.map((part) => stringValue(part));
|
|
41
|
+
}
|
|
42
|
+
function sameArgv(left, right) {
|
|
43
|
+
return left.length === right.length && left.every((part, index) => part === right[index]);
|
|
44
|
+
}
|
|
45
|
+
function sameNumbers(left, right) {
|
|
46
|
+
return left.length === right.length && left.every((part, index) => Object.is(part, right[index]));
|
|
47
|
+
}
|
|
48
|
+
function exitCodeOutcomes(value) {
|
|
49
|
+
const source = record(value, ["authenticated", "unauthenticated"]);
|
|
50
|
+
if (!Array.isArray(source.authenticated) || source.authenticated.length === 0 || !source.authenticated.every(Number.isSafeInteger)
|
|
51
|
+
|| !Array.isArray(source.unauthenticated) || source.unauthenticated.length === 0 || !source.unauthenticated.every(Number.isSafeInteger))
|
|
52
|
+
return invalid();
|
|
53
|
+
const authenticated = source.authenticated;
|
|
54
|
+
const unauthenticated = source.unauthenticated;
|
|
55
|
+
if (authenticated.some((item) => unauthenticated.includes(item)))
|
|
56
|
+
return invalid();
|
|
57
|
+
return { authenticated: [...authenticated], unauthenticated: [...unauthenticated] };
|
|
58
|
+
}
|
|
59
|
+
function freezeAuth(probe) {
|
|
60
|
+
if (probe.kind === "none")
|
|
61
|
+
return Object.freeze({ kind: "none" });
|
|
62
|
+
if (probe.kind === "unavailable")
|
|
63
|
+
return Object.freeze({ kind: "unavailable", reasonCode: probe.reasonCode });
|
|
64
|
+
return Object.freeze({
|
|
65
|
+
kind: "auth",
|
|
66
|
+
argv: Object.freeze([...probe.argv]),
|
|
67
|
+
parser: Object.freeze({ kind: "exit-code" }),
|
|
68
|
+
outcomes: Object.freeze({
|
|
69
|
+
authenticated: Object.freeze([...probe.outcomes.authenticated]),
|
|
70
|
+
unauthenticated: Object.freeze([...probe.outcomes.unauthenticated]),
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function versionProbe(value, executable) {
|
|
75
|
+
const source = record(value, ["argv", "kind", "parser"]);
|
|
76
|
+
if (source.kind !== "version")
|
|
77
|
+
return invalid();
|
|
78
|
+
const parts = argv(source.argv);
|
|
79
|
+
if (!sameArgv(parts, auditedDoctorArgv[executable].version))
|
|
80
|
+
return invalid();
|
|
81
|
+
const parser = source.parser;
|
|
82
|
+
if (parser?.kind === "text-semver" && Object.keys(parser).length === 1)
|
|
83
|
+
return { kind: "version", argv: parts, parser: { kind: "text-semver" } };
|
|
84
|
+
return invalid();
|
|
85
|
+
}
|
|
86
|
+
function authProbe(value, executable) {
|
|
87
|
+
if (executable === "git") {
|
|
88
|
+
const source = record(value, ["kind"]);
|
|
89
|
+
if (source.kind !== "none")
|
|
90
|
+
return invalid();
|
|
91
|
+
return { kind: "none" };
|
|
92
|
+
}
|
|
93
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)
|
|
94
|
+
&& value.kind === "unavailable") {
|
|
95
|
+
const source = record(value, ["kind", "reasonCode"]);
|
|
96
|
+
if (source.reasonCode !== "WSSPEC_CONNECTOR_AUTH_PROBE_UNAVAILABLE")
|
|
97
|
+
return invalid();
|
|
98
|
+
return { kind: "unavailable", reasonCode: "WSSPEC_CONNECTOR_AUTH_PROBE_UNAVAILABLE" };
|
|
99
|
+
}
|
|
100
|
+
if (executable === "lark-cli")
|
|
101
|
+
return invalid();
|
|
102
|
+
const source = record(value, ["argv", "kind", "outcomes", "parser"]);
|
|
103
|
+
if (source.kind !== "auth")
|
|
104
|
+
return invalid();
|
|
105
|
+
const parts = argv(source.argv);
|
|
106
|
+
const audited = auditedDoctorArgv[executable].auth;
|
|
107
|
+
if (audited === undefined || !sameArgv(parts, audited))
|
|
108
|
+
return invalid();
|
|
109
|
+
const parser = source.parser;
|
|
110
|
+
if (parser?.kind === "exit-code" && Object.keys(parser).length === 1) {
|
|
111
|
+
const outcomes = exitCodeOutcomes(source.outcomes);
|
|
112
|
+
if ((executable !== "gh" && executable !== "glab")
|
|
113
|
+
|| !sameNumbers(outcomes.authenticated, [0]) || !sameNumbers(outcomes.unauthenticated, [1]))
|
|
114
|
+
return invalid();
|
|
115
|
+
return {
|
|
116
|
+
kind: "auth",
|
|
117
|
+
argv: parts,
|
|
118
|
+
parser: { kind: "exit-code" },
|
|
119
|
+
outcomes,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return invalid();
|
|
123
|
+
}
|
|
124
|
+
export function defineConnectorManifest(value) {
|
|
125
|
+
const source = record(value, rootKeys);
|
|
126
|
+
const id = stringValue(source.id, idPattern);
|
|
127
|
+
if (!Array.isArray(source.capabilities) || source.capabilities.length === 0)
|
|
128
|
+
return invalid();
|
|
129
|
+
const capabilities = source.capabilities.map((capability) => stringValue(capability, idPattern));
|
|
130
|
+
if (!securityClasses.has(source.securityClass) || !executables.has(source.executable))
|
|
131
|
+
return invalid();
|
|
132
|
+
const executable = source.executable;
|
|
133
|
+
const minimumVersion = stringValue(source.minimumVersion);
|
|
134
|
+
if (parseSemVer(minimumVersion) === undefined)
|
|
135
|
+
return invalid();
|
|
136
|
+
if (!Number.isSafeInteger(source.timeoutMs) || source.timeoutMs < 1
|
|
137
|
+
|| !Number.isSafeInteger(source.maxStdoutBytes) || source.maxStdoutBytes < 1
|
|
138
|
+
|| !Array.isArray(source.argvTemplates) || source.argvTemplates.length === 0)
|
|
139
|
+
return invalid();
|
|
140
|
+
const argvTemplates = source.argvTemplates.map(argv);
|
|
141
|
+
const doctorSource = record(source.doctor, ["auth", "version"]);
|
|
142
|
+
const doctor = { version: versionProbe(doctorSource.version, executable), auth: authProbe(doctorSource.auth, executable) };
|
|
143
|
+
const envSource = record(source.envPolicy, ["allow"]);
|
|
144
|
+
if (!Array.isArray(envSource.allow) || !envSource.allow.every((name) => typeof name === "string" && environmentKeys.has(name)))
|
|
145
|
+
return invalid();
|
|
146
|
+
const allow = [...new Set(envSource.allow)];
|
|
147
|
+
const manifest = {
|
|
148
|
+
id,
|
|
149
|
+
capabilities: Object.freeze([...new Set(capabilities)]),
|
|
150
|
+
securityClass: source.securityClass,
|
|
151
|
+
executable,
|
|
152
|
+
minimumVersion,
|
|
153
|
+
argvTemplates: Object.freeze(argvTemplates.map((parts) => Object.freeze([...parts]))),
|
|
154
|
+
doctor: Object.freeze({
|
|
155
|
+
version: Object.freeze({ ...doctor.version, argv: Object.freeze([...doctor.version.argv]), parser: Object.freeze({ ...doctor.version.parser }) }),
|
|
156
|
+
auth: freezeAuth(doctor.auth),
|
|
157
|
+
}),
|
|
158
|
+
envPolicy: Object.freeze({ allow: Object.freeze(allow) }),
|
|
159
|
+
timeoutMs: source.timeoutMs,
|
|
160
|
+
maxStdoutBytes: source.maxStdoutBytes,
|
|
161
|
+
};
|
|
162
|
+
return Object.freeze(manifest);
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/registry/connectors/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConnectorManifest } from "./types.js";
|
|
2
|
+
export declare class ConnectorRegistryError extends Error {
|
|
3
|
+
readonly code: `WSSPEC_${string}`;
|
|
4
|
+
constructor(code: `WSSPEC_${string}`, message: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class ConnectorRegistry {
|
|
7
|
+
#private;
|
|
8
|
+
register(input: ConnectorManifest): this;
|
|
9
|
+
resolve(capability: string, provider: string): ConnectorManifest;
|
|
10
|
+
manifests(): readonly ConnectorManifest[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { defineConnectorManifest } from "./manifest.js";
|
|
2
|
+
export class ConnectorRegistryError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(code, message) {
|
|
5
|
+
super(`${code}: ${message}`);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.name = "ConnectorRegistryError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class ConnectorRegistry {
|
|
11
|
+
#providers = new Map();
|
|
12
|
+
register(input) {
|
|
13
|
+
const manifest = defineConnectorManifest(input);
|
|
14
|
+
if (this.#providers.has(manifest.id)) {
|
|
15
|
+
throw new ConnectorRegistryError("WSSPEC_CONNECTOR_PROVIDER_DUPLICATE", `Connector provider ${manifest.id} 已注册。`);
|
|
16
|
+
}
|
|
17
|
+
this.#providers.set(manifest.id, manifest);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
resolve(capability, provider) {
|
|
21
|
+
const manifest = this.#providers.get(provider);
|
|
22
|
+
if (manifest === undefined) {
|
|
23
|
+
throw new ConnectorRegistryError("WSSPEC_CONNECTOR_PROVIDER_NOT_FOUND", `找不到 Connector provider ${provider}。`);
|
|
24
|
+
}
|
|
25
|
+
if (!manifest.capabilities.includes(capability)) {
|
|
26
|
+
throw new ConnectorRegistryError("WSSPEC_CONNECTOR_CAPABILITY_NOT_FOUND", `Connector provider ${provider} 不支持 capability ${capability}。`);
|
|
27
|
+
}
|
|
28
|
+
return manifest;
|
|
29
|
+
}
|
|
30
|
+
manifests() {
|
|
31
|
+
return [...this.#providers.values()];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/registry/connectors/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGxD,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC1B;IAArB,YAAqB,IAAwB,EAAE,OAAe;QAC5D,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QADV,SAAI,GAAJ,IAAI,CAAoB;QAE3C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IACnB,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;IAE3D,QAAQ,CAAC,KAAwB;QAC/B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,sBAAsB,CAAC,qCAAqC,EAAE,sBAAsB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QACpH,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,UAAkB,EAAE,QAAgB;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,sBAAsB,CAAC,qCAAqC,EAAE,0BAA0B,QAAQ,GAAG,CAAC,CAAC;QACjH,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,sBAAsB,CAC9B,uCAAuC,EACvC,sBAAsB,QAAQ,mBAAmB,UAAU,GAAG,CAC/D,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,CAAC;CACF"}
|