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.
Files changed (353) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +79 -0
  3. package/dist/adapters/cli/output.d.ts +15 -0
  4. package/dist/adapters/cli/output.js +21 -0
  5. package/dist/adapters/cli/output.js.map +1 -0
  6. package/dist/adapters/cli/workflow.d.ts +25 -0
  7. package/dist/adapters/cli/workflow.js +131 -0
  8. package/dist/adapters/cli/workflow.js.map +1 -0
  9. package/dist/adapters/connectors/git-native.d.ts +23 -0
  10. package/dist/adapters/connectors/git-native.js +521 -0
  11. package/dist/adapters/connectors/git-native.js.map +1 -0
  12. package/dist/adapters/connectors/github-cli.d.ts +23 -0
  13. package/dist/adapters/connectors/github-cli.js +213 -0
  14. package/dist/adapters/connectors/github-cli.js.map +1 -0
  15. package/dist/adapters/connectors/gitlab-cli.d.ts +23 -0
  16. package/dist/adapters/connectors/gitlab-cli.js +199 -0
  17. package/dist/adapters/connectors/gitlab-cli.js.map +1 -0
  18. package/dist/adapters/connectors/lark-cli.d.ts +24 -0
  19. package/dist/adapters/connectors/lark-cli.js +296 -0
  20. package/dist/adapters/connectors/lark-cli.js.map +1 -0
  21. package/dist/adapters/process/redaction.d.ts +2 -0
  22. package/dist/adapters/process/redaction.js +51 -0
  23. package/dist/adapters/process/redaction.js.map +1 -0
  24. package/dist/adapters/process/spawn-json.d.ts +37 -0
  25. package/dist/adapters/process/spawn-json.js +312 -0
  26. package/dist/adapters/process/spawn-json.js.map +1 -0
  27. package/dist/adapters/skills/claude.d.ts +1 -0
  28. package/dist/adapters/skills/claude.js +3 -0
  29. package/dist/adapters/skills/claude.js.map +1 -0
  30. package/dist/adapters/skills/codex.d.ts +1 -0
  31. package/dist/adapters/skills/codex.js +3 -0
  32. package/dist/adapters/skills/codex.js.map +1 -0
  33. package/dist/adapters/skills/cursor.d.ts +1 -0
  34. package/dist/adapters/skills/cursor.js +3 -0
  35. package/dist/adapters/skills/cursor.js.map +1 -0
  36. package/dist/adapters/skills/generic.d.ts +1 -0
  37. package/dist/adapters/skills/generic.js +2 -0
  38. package/dist/adapters/skills/generic.js.map +1 -0
  39. package/dist/adapters/skills/install.d.ts +28 -0
  40. package/dist/adapters/skills/install.js +571 -0
  41. package/dist/adapters/skills/install.js.map +1 -0
  42. package/dist/application/acquire.d.ts +60 -0
  43. package/dist/application/acquire.js +964 -0
  44. package/dist/application/acquire.js.map +1 -0
  45. package/dist/application/application.d.ts +21 -0
  46. package/dist/application/application.js +31 -0
  47. package/dist/application/application.js.map +1 -0
  48. package/dist/application/artifact-reader.d.ts +1 -0
  49. package/dist/application/artifact-reader.js +150 -0
  50. package/dist/application/artifact-reader.js.map +1 -0
  51. package/dist/application/artifact-writer.d.ts +1 -0
  52. package/dist/application/artifact-writer.js +268 -0
  53. package/dist/application/artifact-writer.js.map +1 -0
  54. package/dist/application/artifact.d.ts +28 -0
  55. package/dist/application/artifact.js +523 -0
  56. package/dist/application/artifact.js.map +1 -0
  57. package/dist/application/decide.d.ts +12 -0
  58. package/dist/application/decide.js +168 -0
  59. package/dist/application/decide.js.map +1 -0
  60. package/dist/application/doctor-connectors.d.ts +34 -0
  61. package/dist/application/doctor-connectors.js +99 -0
  62. package/dist/application/doctor-connectors.js.map +1 -0
  63. package/dist/application/external-action.d.ts +164 -0
  64. package/dist/application/external-action.js +670 -0
  65. package/dist/application/external-action.js.map +1 -0
  66. package/dist/application/initial-stages.d.ts +3 -0
  67. package/dist/application/initial-stages.js +7 -0
  68. package/dist/application/initial-stages.js.map +1 -0
  69. package/dist/application/inspect.d.ts +2 -0
  70. package/dist/application/inspect.js +31 -0
  71. package/dist/application/inspect.js.map +1 -0
  72. package/dist/application/profile.d.ts +32 -0
  73. package/dist/application/profile.js +70 -0
  74. package/dist/application/profile.js.map +1 -0
  75. package/dist/application/snapshot.d.ts +75 -0
  76. package/dist/application/snapshot.js +338 -0
  77. package/dist/application/snapshot.js.map +1 -0
  78. package/dist/application/start.d.ts +43 -0
  79. package/dist/application/start.js +360 -0
  80. package/dist/application/start.js.map +1 -0
  81. package/dist/application/state.d.ts +17 -0
  82. package/dist/application/state.js +94 -0
  83. package/dist/application/state.js.map +1 -0
  84. package/dist/application/submit.d.ts +18 -0
  85. package/dist/application/submit.js +1090 -0
  86. package/dist/application/submit.js.map +1 -0
  87. package/dist/cli/commands/core.d.ts +2 -0
  88. package/dist/cli/commands/core.js +205 -0
  89. package/dist/cli/commands/core.js.map +1 -0
  90. package/dist/cli/commands/public-contract.d.ts +12 -0
  91. package/dist/cli/commands/public-contract.js +47 -0
  92. package/dist/cli/commands/public-contract.js.map +1 -0
  93. package/dist/cli/main.d.ts +2 -0
  94. package/dist/cli/main.js +23 -0
  95. package/dist/cli/main.js.map +1 -0
  96. package/dist/domain/artifacts.d.ts +52 -0
  97. package/dist/domain/artifacts.js +241 -0
  98. package/dist/domain/artifacts.js.map +1 -0
  99. package/dist/domain/digests.d.ts +11 -0
  100. package/dist/domain/digests.js +106 -0
  101. package/dist/domain/digests.js.map +1 -0
  102. package/dist/domain/external-receipt.d.ts +48 -0
  103. package/dist/domain/external-receipt.js +138 -0
  104. package/dist/domain/external-receipt.js.map +1 -0
  105. package/dist/domain/ids.d.ts +7 -0
  106. package/dist/domain/ids.js +5 -0
  107. package/dist/domain/ids.js.map +1 -0
  108. package/dist/domain/repository-path.d.ts +3 -0
  109. package/dist/domain/repository-path.js +87 -0
  110. package/dist/domain/repository-path.js.map +1 -0
  111. package/dist/domain/states.d.ts +38 -0
  112. package/dist/domain/states.js +69 -0
  113. package/dist/domain/states.js.map +1 -0
  114. package/dist/domain/work-package-identity.d.ts +2 -0
  115. package/dist/domain/work-package-identity.js +10 -0
  116. package/dist/domain/work-package-identity.js.map +1 -0
  117. package/dist/domain/workflow.d.ts +58 -0
  118. package/dist/domain/workflow.js +2 -0
  119. package/dist/domain/workflow.js.map +1 -0
  120. package/dist/engine/actor-roles.d.ts +15 -0
  121. package/dist/engine/actor-roles.js +53 -0
  122. package/dist/engine/actor-roles.js.map +1 -0
  123. package/dist/engine/approvals.d.ts +44 -0
  124. package/dist/engine/approvals.js +239 -0
  125. package/dist/engine/approvals.js.map +1 -0
  126. package/dist/engine/archive.d.ts +24 -0
  127. package/dist/engine/archive.js +442 -0
  128. package/dist/engine/archive.js.map +1 -0
  129. package/dist/engine/compiler.d.ts +25 -0
  130. package/dist/engine/compiler.js +828 -0
  131. package/dist/engine/compiler.js.map +1 -0
  132. package/dist/engine/control/condition.d.ts +10 -0
  133. package/dist/engine/control/condition.js +49 -0
  134. package/dist/engine/control/condition.js.map +1 -0
  135. package/dist/engine/control/loop.d.ts +23 -0
  136. package/dist/engine/control/loop.js +96 -0
  137. package/dist/engine/control/loop.js.map +1 -0
  138. package/dist/engine/control/retry.d.ts +15 -0
  139. package/dist/engine/control/retry.js +54 -0
  140. package/dist/engine/control/retry.js.map +1 -0
  141. package/dist/engine/docs-integrity.d.ts +13 -0
  142. package/dist/engine/docs-integrity.js +34 -0
  143. package/dist/engine/docs-integrity.js.map +1 -0
  144. package/dist/engine/expressions/ast.d.ts +18 -0
  145. package/dist/engine/expressions/ast.js +9 -0
  146. package/dist/engine/expressions/ast.js.map +1 -0
  147. package/dist/engine/expressions/evaluate.d.ts +7 -0
  148. package/dist/engine/expressions/evaluate.js +47 -0
  149. package/dist/engine/expressions/evaluate.js.map +1 -0
  150. package/dist/engine/expressions/parser.d.ts +2 -0
  151. package/dist/engine/expressions/parser.js +173 -0
  152. package/dist/engine/expressions/parser.js.map +1 -0
  153. package/dist/engine/external-effects/authorization.d.ts +146 -0
  154. package/dist/engine/external-effects/authorization.js +222 -0
  155. package/dist/engine/external-effects/authorization.js.map +1 -0
  156. package/dist/engine/external-effects/idempotency.d.ts +14 -0
  157. package/dist/engine/external-effects/idempotency.js +26 -0
  158. package/dist/engine/external-effects/idempotency.js.map +1 -0
  159. package/dist/engine/external-effects/reconciliation.d.ts +11 -0
  160. package/dist/engine/external-effects/reconciliation.js +18 -0
  161. package/dist/engine/external-effects/reconciliation.js.map +1 -0
  162. package/dist/engine/results.d.ts +14 -0
  163. package/dist/engine/results.js +88 -0
  164. package/dist/engine/results.js.map +1 -0
  165. package/dist/engine/scheduler.d.ts +60 -0
  166. package/dist/engine/scheduler.js +225 -0
  167. package/dist/engine/scheduler.js.map +1 -0
  168. package/dist/engine/tdd/green-gate.d.ts +6 -0
  169. package/dist/engine/tdd/green-gate.js +72 -0
  170. package/dist/engine/tdd/green-gate.js.map +1 -0
  171. package/dist/engine/tdd/red-gate.d.ts +30 -0
  172. package/dist/engine/tdd/red-gate.js +531 -0
  173. package/dist/engine/tdd/red-gate.js.map +1 -0
  174. package/dist/engine/tdd/types.d.ts +89 -0
  175. package/dist/engine/tdd/types.js +38 -0
  176. package/dist/engine/tdd/types.js.map +1 -0
  177. package/dist/engine/verification.d.ts +56 -0
  178. package/dist/engine/verification.js +196 -0
  179. package/dist/engine/verification.js.map +1 -0
  180. package/dist/policy/profile.d.ts +24 -0
  181. package/dist/policy/profile.js +23 -0
  182. package/dist/policy/profile.js.map +1 -0
  183. package/dist/policy/risk.d.ts +33 -0
  184. package/dist/policy/risk.js +138 -0
  185. package/dist/policy/risk.js.map +1 -0
  186. package/dist/protocol/application.d.ts +196 -0
  187. package/dist/protocol/application.js +2 -0
  188. package/dist/protocol/application.js.map +1 -0
  189. package/dist/protocol/public-contract.d.ts +81 -0
  190. package/dist/protocol/public-contract.js +231 -0
  191. package/dist/protocol/public-contract.js.map +1 -0
  192. package/dist/protocol/work-package.d.ts +55 -0
  193. package/dist/protocol/work-package.js +2 -0
  194. package/dist/protocol/work-package.js.map +1 -0
  195. package/dist/registry/connectors/external-executor.d.ts +4 -0
  196. package/dist/registry/connectors/external-executor.js +249 -0
  197. package/dist/registry/connectors/external-executor.js.map +1 -0
  198. package/dist/registry/connectors/feishu-document.d.ts +21 -0
  199. package/dist/registry/connectors/feishu-document.js +197 -0
  200. package/dist/registry/connectors/feishu-document.js.map +1 -0
  201. package/dist/registry/connectors/git-commit.d.ts +32 -0
  202. package/dist/registry/connectors/git-commit.js +122 -0
  203. package/dist/registry/connectors/git-commit.js.map +1 -0
  204. package/dist/registry/connectors/issue.d.ts +68 -0
  205. package/dist/registry/connectors/issue.js +301 -0
  206. package/dist/registry/connectors/issue.js.map +1 -0
  207. package/dist/registry/connectors/knowledge-publish.d.ts +30 -0
  208. package/dist/registry/connectors/knowledge-publish.js +157 -0
  209. package/dist/registry/connectors/knowledge-publish.js.map +1 -0
  210. package/dist/registry/connectors/local-requirement.d.ts +19 -0
  211. package/dist/registry/connectors/local-requirement.js +177 -0
  212. package/dist/registry/connectors/local-requirement.js.map +1 -0
  213. package/dist/registry/connectors/manifest.d.ts +6 -0
  214. package/dist/registry/connectors/manifest.js +164 -0
  215. package/dist/registry/connectors/manifest.js.map +1 -0
  216. package/dist/registry/connectors/registry.d.ts +11 -0
  217. package/dist/registry/connectors/registry.js +34 -0
  218. package/dist/registry/connectors/registry.js.map +1 -0
  219. package/dist/registry/connectors/requirement-source.d.ts +46 -0
  220. package/dist/registry/connectors/requirement-source.js +513 -0
  221. package/dist/registry/connectors/requirement-source.js.map +1 -0
  222. package/dist/registry/connectors/runtime.d.ts +38 -0
  223. package/dist/registry/connectors/runtime.js +127 -0
  224. package/dist/registry/connectors/runtime.js.map +1 -0
  225. package/dist/registry/connectors/secret-detector.d.ts +19 -0
  226. package/dist/registry/connectors/secret-detector.js +85 -0
  227. package/dist/registry/connectors/secret-detector.js.map +1 -0
  228. package/dist/registry/connectors/semver.d.ts +8 -0
  229. package/dist/registry/connectors/semver.js +57 -0
  230. package/dist/registry/connectors/semver.js.map +1 -0
  231. package/dist/registry/connectors/types.d.ts +45 -0
  232. package/dist/registry/connectors/types.js +2 -0
  233. package/dist/registry/connectors/types.js.map +1 -0
  234. package/dist/registry/executors/registry.d.ts +15 -0
  235. package/dist/registry/executors/registry.js +68 -0
  236. package/dist/registry/executors/registry.js.map +1 -0
  237. package/dist/registry/executors/types.d.ts +19 -0
  238. package/dist/registry/executors/types.js +2 -0
  239. package/dist/registry/executors/types.js.map +1 -0
  240. package/dist/registry/skills/lock.d.ts +3 -0
  241. package/dist/registry/skills/lock.js +278 -0
  242. package/dist/registry/skills/lock.js.map +1 -0
  243. package/dist/registry/skills/resolver.d.ts +16 -0
  244. package/dist/registry/skills/resolver.js +353 -0
  245. package/dist/registry/skills/resolver.js.map +1 -0
  246. package/dist/registry/skills/types.d.ts +75 -0
  247. package/dist/registry/skills/types.js +9 -0
  248. package/dist/registry/skills/types.js.map +1 -0
  249. package/dist/resources/catalog.d.ts +20 -0
  250. package/dist/resources/catalog.js +111 -0
  251. package/dist/resources/catalog.js.map +1 -0
  252. package/dist/schemas/definitions.d.ts +5 -0
  253. package/dist/schemas/definitions.js +958 -0
  254. package/dist/schemas/definitions.js.map +1 -0
  255. package/dist/schemas/generate.d.ts +1 -0
  256. package/dist/schemas/generate.js +26 -0
  257. package/dist/schemas/generate.js.map +1 -0
  258. package/dist/schemas/index.d.ts +11 -0
  259. package/dist/schemas/index.js +54 -0
  260. package/dist/schemas/index.js.map +1 -0
  261. package/dist/storage/control-plane.d.ts +136 -0
  262. package/dist/storage/control-plane.js +688 -0
  263. package/dist/storage/control-plane.js.map +1 -0
  264. package/dist/storage/events.d.ts +36 -0
  265. package/dist/storage/events.js +185 -0
  266. package/dist/storage/events.js.map +1 -0
  267. package/dist/storage/external-action-payload.d.ts +33 -0
  268. package/dist/storage/external-action-payload.js +190 -0
  269. package/dist/storage/external-action-payload.js.map +1 -0
  270. package/dist/storage/files.d.ts +13 -0
  271. package/dist/storage/files.js +45 -0
  272. package/dist/storage/files.js.map +1 -0
  273. package/dist/storage/git.d.ts +4 -0
  274. package/dist/storage/git.js +21 -0
  275. package/dist/storage/git.js.map +1 -0
  276. package/dist/storage/project-config.d.ts +11 -0
  277. package/dist/storage/project-config.js +60 -0
  278. package/dist/storage/project-config.js.map +1 -0
  279. package/dist/storage/repository.d.ts +14 -0
  280. package/dist/storage/repository.js +151 -0
  281. package/dist/storage/repository.js.map +1 -0
  282. package/dist/storage/work-items.d.ts +77 -0
  283. package/dist/storage/work-items.js +373 -0
  284. package/dist/storage/work-items.js.map +1 -0
  285. package/dist/storage/workflow-trust.d.ts +38 -0
  286. package/dist/storage/workflow-trust.js +310 -0
  287. package/dist/storage/workflow-trust.js.map +1 -0
  288. package/dist/workflow-package/loader.d.ts +12 -0
  289. package/dist/workflow-package/loader.js +249 -0
  290. package/dist/workflow-package/loader.js.map +1 -0
  291. package/dist/workflow-package/lock.d.ts +6 -0
  292. package/dist/workflow-package/lock.js +12 -0
  293. package/dist/workflow-package/lock.js.map +1 -0
  294. package/dist/workflow-package/path-boundary.d.ts +5 -0
  295. package/dist/workflow-package/path-boundary.js +38 -0
  296. package/dist/workflow-package/path-boundary.js.map +1 -0
  297. package/dist/workflow-package/trust.d.ts +27 -0
  298. package/dist/workflow-package/trust.js +61 -0
  299. package/dist/workflow-package/trust.js.map +1 -0
  300. package/dist/workflow-package/types.d.ts +176 -0
  301. package/dist/workflow-package/types.js +9 -0
  302. package/dist/workflow-package/types.js.map +1 -0
  303. package/dist/workflow-package/workflow-v1.d.ts +3 -0
  304. package/dist/workflow-package/workflow-v1.js +274 -0
  305. package/dist/workflow-package/workflow-v1.js.map +1 -0
  306. package/package.json +40 -0
  307. package/resources/catalog.yaml +37 -0
  308. package/resources/connectors/github-cli.yaml +24 -0
  309. package/resources/connectors/gitlab-cli.yaml +24 -0
  310. package/resources/connectors/lark-cli.yaml +28 -0
  311. package/resources/skills/bug-fixing/SKILL.md +16 -0
  312. package/resources/skills/code-review/SKILL.md +16 -0
  313. package/resources/skills/documentation-editing/SKILL.md +16 -0
  314. package/resources/skills/documentation-exploration/SKILL.md +16 -0
  315. package/resources/skills/documentation-review/SKILL.md +16 -0
  316. package/resources/skills/requirement-exploration/SKILL.md +16 -0
  317. package/resources/skills/solution-design/SKILL.md +16 -0
  318. package/resources/skills/task-planning/SKILL.md +16 -0
  319. package/resources/skills/tdd-implementation/SKILL.md +16 -0
  320. package/resources/workflows/documentation-delivery/manifest.yaml +8 -0
  321. package/resources/workflows/documentation-delivery/profiles/governed.yaml +23 -0
  322. package/resources/workflows/documentation-delivery/profiles/quick.yaml +23 -0
  323. package/resources/workflows/documentation-delivery/profiles/standard.yaml +21 -0
  324. package/resources/workflows/documentation-delivery/workflow.yaml +109 -0
  325. package/resources/workflows/feature-delivery/manifest.yaml +8 -0
  326. package/resources/workflows/feature-delivery/profiles/governed.yaml +27 -0
  327. package/resources/workflows/feature-delivery/profiles/quick.yaml +25 -0
  328. package/resources/workflows/feature-delivery/profiles/standard.yaml +26 -0
  329. package/resources/workflows/feature-delivery/workflow.yaml +150 -0
  330. package/schemas/builtin-agent-action-v1.schema.json +509 -0
  331. package/schemas/builtin-application-acquire-input-v1.schema.json +25 -0
  332. package/schemas/builtin-application-artifact-create-input-v1.schema.json +49 -0
  333. package/schemas/builtin-application-decision-input-v1.schema.json +284 -0
  334. package/schemas/builtin-application-inspect-input-v1.schema.json +20 -0
  335. package/schemas/builtin-application-project-config-snapshot-v1.schema.json +289 -0
  336. package/schemas/builtin-application-project-config-v1.schema.json +293 -0
  337. package/schemas/builtin-application-start-input-v1.schema.json +92 -0
  338. package/schemas/builtin-application-submit-input-v1.schema.json +145 -0
  339. package/schemas/builtin-artifact-v1.schema.json +48 -0
  340. package/schemas/builtin-evidence-v1.schema.json +65 -0
  341. package/schemas/builtin-external-action-grant-v1.schema.json +298 -0
  342. package/schemas/builtin-external-action-request-v1.schema.json +288 -0
  343. package/schemas/builtin-external-binding-v1.schema.json +59 -0
  344. package/schemas/builtin-external-receipt-v1.schema.json +109 -0
  345. package/schemas/builtin-external-write-receipt-v1.schema.json +253 -0
  346. package/schemas/builtin-source-artifact-v1.schema.json +293 -0
  347. package/schemas/builtin-submit-result-v1.schema.json +111 -0
  348. package/schemas/builtin-tdd-cycle-evidence-v1.schema.json +119 -0
  349. package/schemas/builtin-tdd-node-test-report-v1.schema.json +103 -0
  350. package/schemas/builtin-tdd-trusted-evidence-v1.schema.json +184 -0
  351. package/schemas/builtin-work-item-v1.schema.json +201 -0
  352. package/schemas/builtin-work-package-v1.schema.json +254 -0
  353. 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"}