@sayoriqwq/effect-harness 0.0.5 → 0.1.1

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 (103) hide show
  1. package/README.md +9 -77
  2. package/diagnostics/effect-routes.md +6 -0
  3. package/diagnostics/index.md +10 -0
  4. package/diagnostics/tsgo-routes.md +5 -0
  5. package/dist/src/eslint.d.ts +57 -0
  6. package/dist/src/eslint.js +42 -0
  7. package/dist/src/eslint.js.map +1 -0
  8. package/dist/src/index.d.ts +2 -8
  9. package/dist/src/index.js +2 -15
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/prelude.d.ts +6 -0
  12. package/dist/src/prelude.js +161 -0
  13. package/dist/src/prelude.js.map +1 -0
  14. package/package.json +18 -17
  15. package/prelude-assets/effect/managed/docs/diagnostics.md +6 -0
  16. package/prelude-assets/effect/managed/docs/editor-policy.md +5 -0
  17. package/prelude-assets/effect/managed/docs/effect-code.md +5 -0
  18. package/prelude-assets/effect/managed/docs/index.md +14 -0
  19. package/prelude-assets/effect/managed/docs/managed-surfaces.md +5 -0
  20. package/prelude-assets/effect/managed/docs/package-config.md +20 -0
  21. package/prelude-assets/effect/managed/docs/quality-policy.md +5 -0
  22. package/prelude-assets/effect/managed/docs/source-identity.md +5 -0
  23. package/prelude-assets/guidance/eslint.md +15 -0
  24. package/HARNESS.md +0 -66
  25. package/dist/bin/effect-harness.d.ts +0 -2
  26. package/dist/bin/effect-harness.js +0 -23
  27. package/dist/bin/effect-harness.js.map +0 -1
  28. package/dist/src/cli/Main.d.ts +0 -7
  29. package/dist/src/cli/Main.js +0 -45
  30. package/dist/src/cli/Main.js.map +0 -1
  31. package/dist/src/harness/Errors.d.ts +0 -24
  32. package/dist/src/harness/Errors.js +0 -26
  33. package/dist/src/harness/Errors.js.map +0 -1
  34. package/dist/src/harness/Guardrails.d.ts +0 -7
  35. package/dist/src/harness/Guardrails.js +0 -50
  36. package/dist/src/harness/Guardrails.js.map +0 -1
  37. package/dist/src/harness/Model.d.ts +0 -52
  38. package/dist/src/harness/Model.js +0 -170
  39. package/dist/src/harness/Model.js.map +0 -1
  40. package/dist/src/harness/ModuleSources.d.ts +0 -5
  41. package/dist/src/harness/ModuleSources.js +0 -47
  42. package/dist/src/harness/ModuleSources.js.map +0 -1
  43. package/dist/src/harness/ProviderDiscovery.d.ts +0 -255
  44. package/dist/src/harness/ProviderDiscovery.js +0 -242
  45. package/dist/src/harness/ProviderDiscovery.js.map +0 -1
  46. package/dist/src/harness/SourcePin.d.ts +0 -4
  47. package/dist/src/harness/SourcePin.js +0 -214
  48. package/dist/src/harness/SourcePin.js.map +0 -1
  49. package/dist/src/harness/verify/JsonFields.d.ts +0 -1
  50. package/dist/src/harness/verify/JsonFields.js +0 -4
  51. package/dist/src/harness/verify/JsonFields.js.map +0 -1
  52. package/dist/src/harness/verify/Pipeline.d.ts +0 -7
  53. package/dist/src/harness/verify/Pipeline.js +0 -55
  54. package/dist/src/harness/verify/Pipeline.js.map +0 -1
  55. package/dist/src/harness/verify/ProviderProfile.d.ts +0 -3
  56. package/dist/src/harness/verify/ProviderProfile.js +0 -732
  57. package/dist/src/harness/verify/ProviderProfile.js.map +0 -1
  58. package/dist/src/harness/verify/ProviderRepository.d.ts +0 -4
  59. package/dist/src/harness/verify/ProviderRepository.js +0 -127
  60. package/dist/src/harness/verify/ProviderRepository.js.map +0 -1
  61. package/dist/src/harness/verify/Tsgo.d.ts +0 -3
  62. package/dist/src/harness/verify/Tsgo.js +0 -166
  63. package/dist/src/harness/verify/Tsgo.js.map +0 -1
  64. package/dist/src/harness/verify/TsgoMetadata.d.ts +0 -4
  65. package/dist/src/harness/verify/TsgoMetadata.js +0 -50
  66. package/dist/src/harness/verify/TsgoMetadata.js.map +0 -1
  67. package/dist/src/harness/verify/TsgoPolicy.d.ts +0 -208
  68. package/dist/src/harness/verify/TsgoPolicy.js +0 -143
  69. package/dist/src/harness/verify/TsgoPolicy.js.map +0 -1
  70. package/dist/src/harness/verify/TsgoSuppressions.d.ts +0 -2
  71. package/dist/src/harness/verify/TsgoSuppressions.js +0 -24
  72. package/dist/src/harness/verify/TsgoSuppressions.js.map +0 -1
  73. package/dist/src/harness/verify/VerifyStage.d.ts +0 -62
  74. package/dist/src/harness/verify/VerifyStage.js +0 -85
  75. package/dist/src/harness/verify/VerifyStage.js.map +0 -1
  76. package/dist/src/platform/Json.d.ts +0 -4
  77. package/dist/src/platform/Json.js +0 -16
  78. package/dist/src/platform/Json.js.map +0 -1
  79. package/dist/src/platform/Process.d.ts +0 -6
  80. package/dist/src/platform/Process.js +0 -35
  81. package/dist/src/platform/Process.js.map +0 -1
  82. package/harness/code.md +0 -83
  83. package/harness/diagnostic-layers.md +0 -94
  84. package/harness/effect-routes.md +0 -50
  85. package/harness/feedback-loop.md +0 -156
  86. package/harness/index.md +0 -83
  87. package/harness/offcial-guide.md +0 -50
  88. package/harness/offcial-migrate.md +0 -220
  89. package/harness/source.md +0 -91
  90. package/harness/tsgo-routes.md +0 -58
  91. package/harness/tsgo.md +0 -241
  92. package/provider/docs/diagnostics.md +0 -48
  93. package/provider/docs/discovery.md +0 -130
  94. package/provider/docs/editor-policy.md +0 -55
  95. package/provider/docs/effect-code.md +0 -41
  96. package/provider/docs/index.md +0 -48
  97. package/provider/docs/managed-surfaces.md +0 -51
  98. package/provider/docs/package-config.md +0 -71
  99. package/provider/docs/quality-policy.md +0 -68
  100. package/provider/docs/source-identity.md +0 -48
  101. package/provider/effect-harness.provider.json +0 -1021
  102. package/provider/index.md +0 -193
  103. package/provider/snippets/agents.md +0 -34
package/README.md CHANGED
@@ -1,83 +1,15 @@
1
1
  # Effect Harness
2
2
 
3
- `effect-harness` Effect v4 beta provider profile、源入口路线包与 target-facing 模板包。
3
+ Effect Harness publishes a Prelude Harness Module for Effect v4 beta targets.
4
4
 
5
- 当前设计分成两层:
6
-
7
- 1. Harness 层:描述 `effect-harness` 本仓自己怎么运转。
8
- 2. Provider 层:描述任意 target 接入 effect-harness 时应该接收的受管能力。
9
-
10
- 本仓是自身 provider contract 的第一个 conforming repository。`pnpm verify` 证明
11
- self-conformance,但本仓不会 self-materialize Prelude target surface。
12
-
13
- 通用外部仓库 pin 流程由 Partita 负责;本仓只承载 Effect/tsgo 源入口实例、Effect 基线、
14
- strict tsgo policy、读取路线、provider profile、docs bundle 和 snippets。
15
-
16
- ## Harness 层
17
-
18
- 这一层只服务 `effect-harness` 自身的维护:
19
-
20
- - `harness/offcial-guide.md`:仓内 guide 唯一真源。
21
- - `harness/offcial-migrate.md`:官方 source access 与 LSP/tsgo 阶段的本仓实现说明。
22
- - `harness/feedback-loop.md`:第二阶段 Codex feedback loop 和统一 verify pipeline。
23
- - `harness/diagnostic-layers.md`:tsgo diagnostics、ESLint 和 harness guardrails 的分层职责。
24
- - `repos/effect/`:已 pin 的官方 Effect 源码,只供 agent 读取参考。
25
- - `repos/effect.subtree.json`:Partita 管理的 GitHub subtree pin 契约,是 Effect 源入口唯一真源。
26
- - `harness/effect-routes.md`:agent 读取 `repos/effect/` 的路线表。
27
- - `repos/tsgo/`:已 pin 的 `Effect-TS/tsgo` 源码,只供 agent 读取参考。
28
- - `repos/tsgo.subtree.json`:Partita 管理的 GitHub subtree pin 契约,是 tsgo 源入口真源。
29
- - `harness/tsgo.md`:strict tsgo ADR、policy、rule map 和 upgrade loop。
30
- - `harness/tsgo-routes.md`:agent 读取 `repos/tsgo/` 的路线表。
31
- - `src/`:本仓最小验证器,只验证 provider 仓自身边界。
32
-
33
- ## Provider 层
34
-
35
- 这一层不是本仓直接散落脚本来维护目标项目,而是提供结构化 provider profile 和 target-facing
36
- 模板:
37
-
38
- - delivery modes:区分 internal harness、provider artifact reference 和 exported harness。
39
- - self-conformance:声明本仓只验证自己符合 exported harness,不生成 `.prelude/**`。
40
- - provider contract:`provider/effect-harness.provider.json` 声明 package/config contributions、
41
- docs bundle、snippets、source identity 和 self-conformance。
42
- - provider profile:声明 target 应该接收的 managed surfaces。
43
- - provider record:记录接入的 `effect-harness` profile、artifact 与 source identity。
44
- - provider discovery:通过 `effect-harness provider-discover` 输出 machine-readable provider envelope。
45
- - package 基线:维护 `effect`、`@effect/platform-node`、`@effect/tsgo`、
46
- `@effect/language-service` 等版本约束。
47
- - `tsconfig.json` 指针:维护 strict `@effect/language-service` 插件。
48
- - 诊断路径:目标项目以 `tsgo --noEmit` 作为主要 Effect 诊断路径,warning 和 suggestion 也参与
49
- hard gate。
50
- - docs bundle:维护 target 可读的 Effect 编码、诊断和 source identity 文档。
51
- - snippets:维护 target 可引用的 agent instruction snippet。
52
-
53
- 目标项目不接收 `repos/effect/`、`repos/tsgo/`、subtree contracts、`.codex/skills`、目标 runtime
54
- 模板、反馈入口、`.effect-harness.json` 或 effect-harness 管理的 `AGENTS.md` 管理块。
55
-
56
- `effect-harness` 本仓也不接收 `.prelude/**`。这些路径只属于 Prelude 在真实 target 中的
57
- materialization 和 maintain lifecycle。
58
-
59
- ## 职责边界
60
-
61
- - Partita:通用外部源入口 pin/status/update/verify。
62
- - effect-harness:Effect/tsgo 源入口实例、路线表、baseline、provider profile、受管模板、本仓验证。
63
- - Prelude:消费 provider profile,并维护 target lifecycle、provider record、目标项目落地生成、
64
- drift/verify/maintain。
65
-
66
- ## 验证命令
67
-
68
- ```bash
69
- pnpm install
70
- pnpm verify
5
+ ```ts
6
+ import effectHarnessEslintConfig from '@sayoriqwq/effect-harness/eslint'
7
+ import { harnessModule } from '@sayoriqwq/effect-harness/prelude'
71
8
  ```
72
9
 
73
- 完成态只认 `pnpm verify`。该命令由 Effect pipeline 组织,按 `source-pins`、
74
- `harness-contract`、`tsgo-diagnostics`、`tests`、`lint`、`knip` 顺序 fail-fast 执行。
10
+ `harnessModule` plans a complete `effect/managed/**` documentation tree, a
11
+ bounded root agent-routing block, TypeScript/editor configuration, direct
12
+ package requirements, checks, and target-state Issues. Planning is read-only.
75
13
 
76
- Effect 程序逻辑,或修改 source route、tsgo policy、provider profile、verify pipeline、
77
- harness 边界或 provider 边界前,先读
78
- [harness/feedback-loop.md](./harness/feedback-loop.md)。更新 source entries 前先读
79
- [harness/source.md](./harness/source.md)。agent 需要读取 pinned Effect 源码时先读
80
- [harness/effect-routes.md](./harness/effect-routes.md)。agent 需要调整 strict tsgo policy 或读取
81
- tsgo source 时,先读 [harness/tsgo.md](./harness/tsgo.md) 和
82
- [harness/tsgo-routes.md](./harness/tsgo-routes.md)。修改 provider contribution、docs bundle 或
83
- snippets 前先读 [provider/index.md](./provider/index.md)。
14
+ `effect/feedback/**` is target-owned. Pinned Effect and tsgo sources are
15
+ Artifact-internal diagnostics and are not normal target assets.
@@ -0,0 +1,6 @@
1
+ # Effect source route
2
+
3
+ For an exceptional Effect API diagnosis, read `../repos/effect/LLMS.md` first,
4
+ then inspect the relevant package under `../repos/effect/packages/`. These
5
+ files are Artifact-internal references; normal target code imports installed
6
+ packages instead.
@@ -0,0 +1,10 @@
1
+ # Artifact-internal source diagnostics
2
+
3
+ This directory routes exceptional diagnosis into the pinned Effect and tsgo
4
+ source trees shipped inside this npm Artifact. It is not part of the normal
5
+ `effect/managed/**` Target bundle.
6
+
7
+ - [Effect source route](./effect-routes.md)
8
+ - [tsgo source route](./tsgo-routes.md)
9
+ - `../repos/effect.subtree.json` and `../repos/tsgo.subtree.json` identify
10
+ the exact pinned source entries.
@@ -0,0 +1,5 @@
1
+ # tsgo source route
2
+
3
+ For an exceptional diagnostic backend question, read `../repos/tsgo/README.md`
4
+ and inspect `../repos/tsgo/_packages/tsgo/`. The source tree is shipped only
5
+ for Artifact diagnosis and is never a normal target projection.
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Composable Effect guardrails for a target-owned ESLint flat config.
3
+ *
4
+ * Targets import this value from `@sayoriqwq/effect-harness/eslint`; Prelude
5
+ * intentionally never rewrites executable config files.
6
+ */
7
+ declare const effectHarnessEslintConfig: readonly [{
8
+ readonly name: "effect-harness/guardrails";
9
+ readonly rules: {
10
+ readonly 'no-restricted-imports': readonly ["error", {
11
+ readonly paths: readonly [{
12
+ readonly name: "node:test";
13
+ readonly message: "Use @effect/vitest for Effect test entries.";
14
+ }, {
15
+ readonly name: "@effect/cli";
16
+ readonly message: "Use effect/unstable/cli for Effect v4 beta.";
17
+ }];
18
+ readonly patterns: readonly [{
19
+ readonly group: readonly ["@effect/cli/*"];
20
+ readonly message: "Use effect/unstable/cli for Effect v4 beta.";
21
+ }, {
22
+ readonly group: readonly ["repos/effect/**", "**/repos/effect/**"];
23
+ readonly message: "Import installed packages, never pinned source trees.";
24
+ }, {
25
+ readonly group: readonly ["repos/tsgo/**", "**/repos/tsgo/**"];
26
+ readonly message: "Use tsgo through its installed package.";
27
+ }];
28
+ }];
29
+ readonly 'no-restricted-syntax': readonly ["error", {
30
+ readonly selector: "MemberExpression[object.name=\"Context\"][property.name=\"Tag\"]";
31
+ readonly message: "Use Context.Service for Effect v4 services.";
32
+ }, {
33
+ readonly selector: "MemberExpression[object.name=\"Effect\"][property.name=/^(catchAllCause|ignore|serviceOption)$/]";
34
+ readonly message: "Use the Effect-native safer pattern.";
35
+ }];
36
+ };
37
+ }, {
38
+ readonly name: "effect-harness/tests";
39
+ readonly files: readonly ["tests/**/*.test.{js,mjs,ts}"];
40
+ readonly rules: {
41
+ readonly 'no-restricted-imports': readonly ["error", {
42
+ readonly paths: readonly [{
43
+ readonly name: "node:test";
44
+ readonly message: "Use @effect/vitest.";
45
+ }, {
46
+ readonly name: "vitest";
47
+ readonly importNames: readonly ["describe", "it", "test"];
48
+ readonly message: "Use @effect/vitest Effect entries.";
49
+ }];
50
+ }];
51
+ readonly 'no-restricted-syntax': readonly ["error", {
52
+ readonly selector: "CallExpression[callee.name=\"it\"]";
53
+ readonly message: "Use it.effect, it.live, or layer from @effect/vitest.";
54
+ }];
55
+ };
56
+ }];
57
+ export default effectHarnessEslintConfig;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Composable Effect guardrails for a target-owned ESLint flat config.
3
+ *
4
+ * Targets import this value from `@sayoriqwq/effect-harness/eslint`; Prelude
5
+ * intentionally never rewrites executable config files.
6
+ */
7
+ const effectHarnessEslintConfig = [
8
+ {
9
+ name: 'effect-harness/guardrails',
10
+ rules: {
11
+ 'no-restricted-imports': [
12
+ 'error',
13
+ {
14
+ paths: [
15
+ { name: 'node:test', message: 'Use @effect/vitest for Effect test entries.' },
16
+ { name: '@effect/cli', message: 'Use effect/unstable/cli for Effect v4 beta.' },
17
+ ],
18
+ patterns: [
19
+ { group: ['@effect/cli/*'], message: 'Use effect/unstable/cli for Effect v4 beta.' },
20
+ { group: ['repos/effect/**', '**/repos/effect/**'], message: 'Import installed packages, never pinned source trees.' },
21
+ { group: ['repos/tsgo/**', '**/repos/tsgo/**'], message: 'Use tsgo through its installed package.' },
22
+ ],
23
+ },
24
+ ],
25
+ 'no-restricted-syntax': [
26
+ 'error',
27
+ { selector: 'MemberExpression[object.name="Context"][property.name="Tag"]', message: 'Use Context.Service for Effect v4 services.' },
28
+ { selector: 'MemberExpression[object.name="Effect"][property.name=/^(catchAllCause|ignore|serviceOption)$/]', message: 'Use the Effect-native safer pattern.' },
29
+ ],
30
+ },
31
+ },
32
+ {
33
+ name: 'effect-harness/tests',
34
+ files: ['tests/**/*.test.{js,mjs,ts}'],
35
+ rules: {
36
+ 'no-restricted-imports': ['error', { paths: [{ name: 'node:test', message: 'Use @effect/vitest.' }, { name: 'vitest', importNames: ['describe', 'it', 'test'], message: 'Use @effect/vitest Effect entries.' }] }],
37
+ 'no-restricted-syntax': ['error', { selector: 'CallExpression[callee.name="it"]', message: 'Use it.effect, it.live, or layer from @effect/vitest.' }],
38
+ },
39
+ },
40
+ ];
41
+ export default effectHarnessEslintConfig;
42
+ //# sourceMappingURL=eslint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/eslint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,yBAAyB,GAAG;IAChC;QACE,IAAI,EAAE,2BAA2B;QACjC,KAAK,EAAE;YACL,uBAAuB,EAAE;gBACvB,OAAO;gBACP;oBACE,KAAK,EAAE;wBACL,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,6CAA6C,EAAE;wBAC7E,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,6CAA6C,EAAE;qBAChF;oBACD,QAAQ,EAAE;wBACR,EAAE,KAAK,EAAE,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,6CAA6C,EAAE;wBACpF,EAAE,KAAK,EAAE,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,EAAE,OAAO,EAAE,uDAAuD,EAAE;wBACtH,EAAE,KAAK,EAAE,CAAC,eAAe,EAAE,kBAAkB,CAAC,EAAE,OAAO,EAAE,yCAAyC,EAAE;qBACrG;iBACF;aACF;YACD,sBAAsB,EAAE;gBACtB,OAAO;gBACP,EAAE,QAAQ,EAAE,8DAA8D,EAAE,OAAO,EAAE,6CAA6C,EAAE;gBACpI,EAAE,QAAQ,EAAE,gGAAgG,EAAE,OAAO,EAAE,sCAAsC,EAAE;aAChK;SACF;KACF;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,CAAC,6BAA6B,CAAC;QACtC,KAAK,EAAE;YACL,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC,EAAE,CAAC;YAClN,sBAAsB,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,kCAAkC,EAAE,OAAO,EAAE,uDAAuD,EAAE,CAAC;SACtJ;KACF;CACO,CAAA;AAEV,eAAe,yBAAyB,CAAA","sourcesContent":["/**\n * Composable Effect guardrails for a target-owned ESLint flat config.\n *\n * Targets import this value from `@sayoriqwq/effect-harness/eslint`; Prelude\n * intentionally never rewrites executable config files.\n */\nconst effectHarnessEslintConfig = [\n {\n name: 'effect-harness/guardrails',\n rules: {\n 'no-restricted-imports': [\n 'error',\n {\n paths: [\n { name: 'node:test', message: 'Use @effect/vitest for Effect test entries.' },\n { name: '@effect/cli', message: 'Use effect/unstable/cli for Effect v4 beta.' },\n ],\n patterns: [\n { group: ['@effect/cli/*'], message: 'Use effect/unstable/cli for Effect v4 beta.' },\n { group: ['repos/effect/**', '**/repos/effect/**'], message: 'Import installed packages, never pinned source trees.' },\n { group: ['repos/tsgo/**', '**/repos/tsgo/**'], message: 'Use tsgo through its installed package.' },\n ],\n },\n ],\n 'no-restricted-syntax': [\n 'error',\n { selector: 'MemberExpression[object.name=\"Context\"][property.name=\"Tag\"]', message: 'Use Context.Service for Effect v4 services.' },\n { selector: 'MemberExpression[object.name=\"Effect\"][property.name=/^(catchAllCause|ignore|serviceOption)$/]', message: 'Use the Effect-native safer pattern.' },\n ],\n },\n },\n {\n name: 'effect-harness/tests',\n files: ['tests/**/*.test.{js,mjs,ts}'],\n rules: {\n 'no-restricted-imports': ['error', { paths: [{ name: 'node:test', message: 'Use @effect/vitest.' }, { name: 'vitest', importNames: ['describe', 'it', 'test'], message: 'Use @effect/vitest Effect entries.' }] }],\n 'no-restricted-syntax': ['error', { selector: 'CallExpression[callee.name=\"it\"]', message: 'Use it.effect, it.live, or layer from @effect/vitest.' }],\n },\n },\n] as const\n\nexport default effectHarnessEslintConfig\n"]}
@@ -1,8 +1,2 @@
1
- import type { ProviderDiscovery, ProviderDiscoveryFailure, ProviderDiscoveryFailureInput } from './harness/ProviderDiscovery.ts';
2
- import { classifyProviderDiscoveryFailure, discoverProvider, resolvePackageArtifactRoot } from './harness/ProviderDiscovery.ts';
3
- export type { ProviderDiscovery, ProviderDiscoveryFailure, ProviderDiscoveryFailureInput, };
4
- export { classifyProviderDiscoveryFailure, discoverProvider, resolvePackageArtifactRoot, };
5
- export interface DiscoverProviderArtifactOptions {
6
- readonly artifactRoot?: string;
7
- }
8
- export declare function discoverProviderArtifact(options?: DiscoverProviderArtifactOptions): Promise<ProviderDiscovery>;
1
+ /** The Harness Module is deliberately available only through `./prelude`. */
2
+ export {};
package/dist/src/index.js CHANGED
@@ -1,16 +1,3 @@
1
- import { fileURLToPath } from 'node:url';
2
- import * as NodeServices from '@effect/platform-node/NodeServices';
3
- import { Effect, Layer } from 'effect';
4
- import { classifyProviderDiscoveryFailure, discoverProvider, resolvePackageArtifactRoot, } from "./harness/ProviderDiscovery.js";
5
- export { classifyProviderDiscoveryFailure, discoverProvider, resolvePackageArtifactRoot, };
6
- export function discoverProviderArtifact(options = {}) {
7
- const artifactRoot = options.artifactRoot ?? resolvePackageArtifactRoot(fileURLToPath(import.meta.url));
8
- return runWithNodeServices(discoverProvider(artifactRoot));
9
- }
10
- function runWithNodeServices(effect) {
11
- return Effect.runPromise(Effect.scoped(Effect.gen(function* () {
12
- const context = yield* Layer.build(NodeServices.layer);
13
- return yield* Effect.promise(() => Effect.runPromiseWith(context)(effect));
14
- })));
15
- }
1
+ /** The Harness Module is deliberately available only through `./prelude`. */
2
+ export {};
16
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,KAAK,YAAY,MAAM,oCAAoC,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EACL,gCAAgC,EAChC,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,gCAAgC,CAAA;AAQvC,OAAO,EACL,gCAAgC,EAChC,gBAAgB,EAChB,0BAA0B,GAC3B,CAAA;AAMD,MAAM,UAAU,wBAAwB,CACtC,UAA2C,EAAE;IAE7C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,0BAA0B,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACvG,OAAO,mBAAmB,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAAsD;IAEtD,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QACtD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAC,CAAC,CAAA;AACN,CAAC","sourcesContent":["import type {\n ProviderDiscovery,\n ProviderDiscoveryFailure,\n ProviderDiscoveryFailureInput,\n} from './harness/ProviderDiscovery.ts'\nimport { fileURLToPath } from 'node:url'\nimport * as NodeServices from '@effect/platform-node/NodeServices'\nimport { Effect, Layer } from 'effect'\nimport {\n classifyProviderDiscoveryFailure,\n discoverProvider,\n resolvePackageArtifactRoot,\n} from './harness/ProviderDiscovery.ts'\n\nexport type {\n ProviderDiscovery,\n ProviderDiscoveryFailure,\n ProviderDiscoveryFailureInput,\n}\n\nexport {\n classifyProviderDiscoveryFailure,\n discoverProvider,\n resolvePackageArtifactRoot,\n}\n\nexport interface DiscoverProviderArtifactOptions {\n readonly artifactRoot?: string\n}\n\nexport function discoverProviderArtifact(\n options: DiscoverProviderArtifactOptions = {},\n): Promise<ProviderDiscovery> {\n const artifactRoot = options.artifactRoot ?? resolvePackageArtifactRoot(fileURLToPath(import.meta.url))\n return runWithNodeServices(discoverProvider(artifactRoot))\n}\n\nfunction runWithNodeServices<A, E>(\n effect: Effect.Effect<A, E, NodeServices.NodeServices>,\n): Promise<A> {\n return Effect.runPromise(Effect.scoped(Effect.gen(function* () {\n const context = yield* Layer.build(NodeServices.layer)\n return yield* Effect.promise(() => Effect.runPromiseWith(context)(effect))\n })))\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,EAAE,CAAA","sourcesContent":["/** The Harness Module is deliberately available only through `./prelude`. */\nexport {}\n"]}
@@ -0,0 +1,6 @@
1
+ export declare const harnessModule: import("@sayoriqwq/prelude-contract").HarnessModule<import("effect/Schema").Struct.ReadonlySide<{
2
+ readonly _tag: import("effect/Schema").tag<"ObservationError">;
3
+ readonly operation: import("effect/Schema").Literals<readonly ["readBytes", "readText", "readDirectory", "readPackageManifest"]>;
4
+ readonly path: import("effect/Schema").String;
5
+ readonly message: import("effect/Schema").String;
6
+ }, "Type">>;
@@ -0,0 +1,161 @@
1
+ import { defineHarnessModule, MODULE_PROTOCOL_V1, PRELUDE_V1_SUPPORTED_FEATURES, } from '@sayoriqwq/prelude-contract';
2
+ import { Effect } from 'effect';
3
+ import * as TypeScript from 'typescript';
4
+ const effectLanguageServicePlugin = {
5
+ name: '@effect/language-service',
6
+ diagnostics: true,
7
+ includeSuggestionsInTsc: true,
8
+ ignoreEffectSuggestionsInTscExitCode: false,
9
+ ignoreEffectWarningsInTscExitCode: false,
10
+ ignoreEffectErrorsInTscExitCode: false,
11
+ };
12
+ const routingBlock = `## Effect Harness\n\nFor Effect application, test, package, TypeScript, editor, or lint changes, read \`effect/managed/docs/index.md\` first. For ESLint or package-config repair, read \`effect/managed/docs/package-config.md\`; Antfu v9 integrations use its \`antfu().append(...effectHarness)\` form. Keep \`effect/feedback/**\` target-owned. Use installed Effect packages; never import pinned source diagnostics.\n`;
13
+ function eslintIntegrationIssue(content) {
14
+ if (typeof content === 'string') {
15
+ if (hasEffectHarnessEslintComposition(content)) {
16
+ return [];
17
+ }
18
+ }
19
+ return [{
20
+ id: 'effect.eslint.integration',
21
+ summary: 'Target ESLint config does not compose Effect Harness guardrails',
22
+ detail: 'The target-owned eslint.config.mjs must import and include @sayoriqwq/effect-harness/eslint.',
23
+ evidence: content === undefined ? 'eslint.config.mjs is absent.' : 'eslint.config.mjs does not reference the stable Effect Harness ESLint export.',
24
+ guidance: 'prelude-assets/guidance/eslint.md',
25
+ }];
26
+ }
27
+ function hasEffectHarnessEslintComposition(content) {
28
+ const source = TypeScript.createSourceFile('eslint.config.mjs', content, TypeScript.ScriptTarget.Latest, false, TypeScript.ScriptKind.JS);
29
+ let antfuBinding = '';
30
+ for (const statement of source.statements) {
31
+ if (TypeScript.isImportDeclaration(statement)
32
+ && TypeScript.isStringLiteral(statement.moduleSpecifier)
33
+ && statement.moduleSpecifier.text === '@antfu/eslint-config') {
34
+ antfuBinding = statement.importClause?.name?.text ?? '';
35
+ }
36
+ }
37
+ for (const statement of source.statements) {
38
+ if (!TypeScript.isImportDeclaration(statement)
39
+ || !TypeScript.isStringLiteral(statement.moduleSpecifier)
40
+ || statement.moduleSpecifier.text !== '@sayoriqwq/effect-harness/eslint') {
41
+ continue;
42
+ }
43
+ const binding = statement.importClause?.name?.text ?? '';
44
+ if (binding.length > 0 && composesEslintBinding(source, binding, antfuBinding)) {
45
+ return true;
46
+ }
47
+ }
48
+ return false;
49
+ }
50
+ function composesEslintBinding(source, binding, antfuBinding) {
51
+ return source.statements.some((statement) => {
52
+ if (TypeScript.isExportAssignment(statement) === false)
53
+ return false;
54
+ if (statement.isExportEquals === true)
55
+ return false;
56
+ if (TypeScript.isArrayLiteralExpression(statement.expression)) {
57
+ const spreadsEffectConfig = statement.expression.elements.some(element => TypeScript.isSpreadElement(element)
58
+ && TypeScript.isIdentifier(element.expression)
59
+ && element.expression.text === binding);
60
+ return spreadsEffectConfig && !spreadsAntfuCall(statement.expression, antfuBinding);
61
+ }
62
+ return appendsEffectConfigToAntfu(statement.expression, binding, antfuBinding);
63
+ });
64
+ }
65
+ function spreadsAntfuCall(expression, antfuBinding) {
66
+ return antfuBinding.length > 0 && expression.elements.some(element => TypeScript.isSpreadElement(element)
67
+ && TypeScript.isCallExpression(element.expression)
68
+ && TypeScript.isIdentifier(element.expression.expression)
69
+ && element.expression.expression.text === antfuBinding);
70
+ }
71
+ function appendsEffectConfigToAntfu(expression, effectBinding, antfuBinding) {
72
+ if (antfuBinding.length === 0 || !TypeScript.isCallExpression(expression))
73
+ return false;
74
+ const append = expression.expression;
75
+ if (!TypeScript.isPropertyAccessExpression(append) || append.name.text !== 'append')
76
+ return false;
77
+ if (!TypeScript.isCallExpression(append.expression)
78
+ || !TypeScript.isIdentifier(append.expression.expression)
79
+ || append.expression.expression.text !== antfuBinding) {
80
+ return false;
81
+ }
82
+ return expression.arguments.some(argument => TypeScript.isSpreadElement(argument)
83
+ && TypeScript.isIdentifier(argument.expression)
84
+ && argument.expression.text === effectBinding);
85
+ }
86
+ export const harnessModule = defineHarnessModule({
87
+ descriptor: {
88
+ harnessId: 'effect-harness',
89
+ protocolVersion: MODULE_PROTOCOL_V1,
90
+ requiredFeatures: PRELUDE_V1_SUPPORTED_FEATURES,
91
+ },
92
+ plan: context => Effect.gen(function* () {
93
+ const eslintConfig = yield* context.target.readText('eslint.config.mjs');
94
+ return {
95
+ outputs: [
96
+ {
97
+ kind: 'ManagedTree',
98
+ id: 'effect.managed',
99
+ sourceRoot: 'prelude-assets/effect/managed',
100
+ targetRoot: 'effect/managed',
101
+ },
102
+ {
103
+ kind: 'ManagedBlock',
104
+ id: 'effect.agent-routing',
105
+ path: 'AGENTS.md',
106
+ blockId: 'effect-harness-routing',
107
+ content: routingBlock,
108
+ },
109
+ {
110
+ kind: 'JsonKeyedItem',
111
+ id: 'effect.tsconfig.language-service',
112
+ path: 'tsconfig.json',
113
+ collectionPointer: '/compilerOptions/plugins',
114
+ keyField: 'name',
115
+ keyValue: '@effect/language-service',
116
+ item: effectLanguageServicePlugin,
117
+ },
118
+ {
119
+ kind: 'JsonValue',
120
+ id: 'effect.vscode.auto-import-exclude',
121
+ path: '.vscode/settings.json',
122
+ pointer: '/typescript.preferences.autoImportFileExcludePatterns',
123
+ value: ['repos/**'],
124
+ },
125
+ {
126
+ kind: 'JsonValue',
127
+ id: 'effect.vscode.javascript-auto-import-exclude',
128
+ path: '.vscode/settings.json',
129
+ pointer: '/javascript.preferences.autoImportFileExcludePatterns',
130
+ value: ['repos/**'],
131
+ },
132
+ {
133
+ kind: 'JsonValue',
134
+ id: 'effect.zed.auto-import-exclude',
135
+ path: '.zed/settings.json',
136
+ pointer: '/lsp/typescript-language-server/initialization_options/preferences/autoImportFileExcludePatterns',
137
+ value: ['repos/**'],
138
+ },
139
+ ],
140
+ requirements: [
141
+ { id: 'effect.runtime', packageRoot: context.integration.packageRoot, packageName: 'effect', range: '4.0.0-beta.92', section: 'dependencies' },
142
+ { id: 'effect.platform-node', packageRoot: context.integration.packageRoot, packageName: '@effect/platform-node', range: '4.0.0-beta.92', section: 'dependencies' },
143
+ { id: 'effect.vitest', packageRoot: context.integration.packageRoot, packageName: '@effect/vitest', range: '4.0.0-beta.92', section: 'devDependencies' },
144
+ { id: 'effect.tsgo', packageRoot: context.integration.packageRoot, packageName: '@effect/tsgo', range: '0.15.0', section: 'devDependencies' },
145
+ { id: 'effect.language-service', packageRoot: context.integration.packageRoot, packageName: '@effect/language-service', range: '0.86.2', section: 'devDependencies' },
146
+ { id: 'effect.native-typescript', packageRoot: context.integration.packageRoot, packageName: '@typescript/native-preview', range: '7.0.0-dev.20260630.1', section: 'devDependencies' },
147
+ { id: 'effect.eslint', packageRoot: context.integration.packageRoot, packageName: 'eslint', range: '^10.3.0', section: 'devDependencies' },
148
+ { id: 'effect.antfu-eslint-config', packageRoot: context.integration.packageRoot, packageName: '@antfu/eslint-config', range: '^9.0.0', section: 'devDependencies' },
149
+ { id: 'effect.vitest-runner', packageRoot: context.integration.packageRoot, packageName: 'vitest', range: '^4.1.8', section: 'devDependencies' },
150
+ { id: 'effect.typescript', packageRoot: context.integration.packageRoot, packageName: 'typescript', range: '^6.0.3', section: 'devDependencies' },
151
+ ],
152
+ checks: [
153
+ { id: 'effect.typecheck', summary: 'Run strict Effect diagnostics', packageRoot: context.integration.packageRoot, argv: ['pnpm', 'typecheck'] },
154
+ { id: 'effect.lint', summary: 'Run Effect lint guardrails', packageRoot: context.integration.packageRoot, argv: ['pnpm', 'lint', '--max-warnings', '0'] },
155
+ { id: 'effect.verify', summary: 'Run Effect domain verification', packageRoot: context.integration.packageRoot, argv: ['pnpm', 'verify'] },
156
+ ],
157
+ issues: eslintIntegrationIssue(eslintConfig),
158
+ };
159
+ }),
160
+ });
161
+ //# sourceMappingURL=prelude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prelude.js","sourceRoot":"","sources":["../../src/prelude.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,YAAY,CAAA;AAExC,MAAM,2BAA2B,GAAG;IAClC,IAAI,EAAE,0BAA0B;IAChC,WAAW,EAAE,IAAI;IACjB,uBAAuB,EAAE,IAAI;IAC7B,oCAAoC,EAAE,KAAK;IAC3C,iCAAiC,EAAE,KAAK;IACxC,+BAA+B,EAAE,KAAK;CACvC,CAAA;AAED,MAAM,YAAY,GAAG,gaAAga,CAAA;AAErb,SAAS,sBAAsB,CAAC,OAA2B;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,IAAI,iCAAiC,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED,OAAO,CAAC;YACN,EAAE,EAAE,2BAA2B;YAC/B,OAAO,EAAE,iEAAiE;YAC1E,MAAM,EAAE,8FAA8F;YACtG,QAAQ,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,+EAA+E;YAClJ,QAAQ,EAAE,mCAAmC;SAC9C,CAAU,CAAA;AACb,CAAC;AAED,SAAS,iCAAiC,CAAC,OAAe;IACxD,MAAM,MAAM,GAAG,UAAU,CAAC,gBAAgB,CACxC,mBAAmB,EACnB,OAAO,EACP,UAAU,CAAC,YAAY,CAAC,MAAM,EAC9B,KAAK,EACL,UAAU,CAAC,UAAU,CAAC,EAAE,CACzB,CAAA;IAED,IAAI,YAAY,GAAG,EAAE,CAAA;IACrB,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,IACE,UAAU,CAAC,mBAAmB,CAAC,SAAS,CAAC;eACtC,UAAU,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC;eACrD,SAAS,CAAC,eAAe,CAAC,IAAI,KAAK,sBAAsB,EAC5D,CAAC;YACD,YAAY,GAAG,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAA;QACzD,CAAC;IACH,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,IACE,CAAC,UAAU,CAAC,mBAAmB,CAAC,SAAS,CAAC;eACvC,CAAC,UAAU,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC;eACtD,SAAS,CAAC,eAAe,CAAC,IAAI,KAAK,kCAAkC,EACxE,CAAC;YACD,SAAQ;QACV,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAA;QACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;YAC/E,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAA6B,EAC7B,OAAe,EACf,YAAoB;IAEpB,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QAC1C,IAAI,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,KAAK,KAAK;YACpD,OAAO,KAAK,CAAA;QAEd,IAAI,SAAS,CAAC,cAAc,KAAK,IAAI;YACnC,OAAO,KAAK,CAAA;QAEd,IAAI,UAAU,CAAC,wBAAwB,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9D,MAAM,mBAAmB,GAAG,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACvE,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC;mBAChC,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;mBAC3C,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;YACzC,OAAO,mBAAmB,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;QACrF,CAAC;QAED,OAAO,0BAA0B,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;IAChF,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,UAA6C,EAAE,YAAoB;IAC3F,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACnE,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC;WAChC,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC;WAC/C,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;WACtD,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,KAAK,YAAY,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,0BAA0B,CACjC,UAAiC,EACjC,aAAqB,EACrB,YAAoB;IAEpB,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAAU,CAAC;QACvE,OAAO,KAAK,CAAA;IAEd,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAA;IACpC,IAAI,CAAC,UAAU,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;QACjF,OAAO,KAAK,CAAA;IAEd,IACE,CAAC,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC;WAC5C,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;WACtD,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,KAAK,YAAY,EACrD,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAC1C,UAAU,CAAC,eAAe,CAAC,QAAQ,CAAC;WACjC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC;WAC5C,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC;IAC/C,UAAU,EAAE;QACV,SAAS,EAAE,gBAAgB;QAC3B,eAAe,EAAE,kBAAkB;QACnC,gBAAgB,EAAE,6BAA6B;KAChD;IACD,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnC,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAA;QACxE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,aAAsB;oBAC5B,EAAE,EAAE,gBAAgB;oBACpB,UAAU,EAAE,+BAA+B;oBAC3C,UAAU,EAAE,gBAAgB;iBAC7B;gBACD;oBACE,IAAI,EAAE,cAAuB;oBAC7B,EAAE,EAAE,sBAAsB;oBAC1B,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,wBAAwB;oBACjC,OAAO,EAAE,YAAY;iBACtB;gBACD;oBACE,IAAI,EAAE,eAAwB;oBAC9B,EAAE,EAAE,kCAAkC;oBACtC,IAAI,EAAE,eAAe;oBACrB,iBAAiB,EAAE,0BAA0B;oBAC7C,QAAQ,EAAE,MAAM;oBAChB,QAAQ,EAAE,0BAA0B;oBACpC,IAAI,EAAE,2BAA2B;iBAClC;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,EAAE,EAAE,mCAAmC;oBACvC,IAAI,EAAE,uBAAuB;oBAC7B,OAAO,EAAE,uDAAuD;oBAChE,KAAK,EAAE,CAAC,UAAU,CAAC;iBACpB;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,EAAE,EAAE,8CAA8C;oBAClD,IAAI,EAAE,uBAAuB;oBAC7B,OAAO,EAAE,uDAAuD;oBAChE,KAAK,EAAE,CAAC,UAAU,CAAC;iBACpB;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,EAAE,EAAE,gCAAgC;oBACpC,IAAI,EAAE,oBAAoB;oBAC1B,OAAO,EAAE,kGAAkG;oBAC3G,KAAK,EAAE,CAAC,UAAU,CAAC;iBACpB;aACF;YACD,YAAY,EAAE;gBACZ,EAAE,EAAE,EAAE,gBAAgB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,cAAuB,EAAE;gBACvJ,EAAE,EAAE,EAAE,sBAAsB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,uBAAuB,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,cAAuB,EAAE;gBAC5K,EAAE,EAAE,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBACjK,EAAE,EAAE,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBACtJ,EAAE,EAAE,EAAE,yBAAyB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBAC9K,EAAE,EAAE,EAAE,0BAA0B,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,4BAA4B,EAAE,KAAK,EAAE,sBAAsB,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBAC/L,EAAE,EAAE,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBACnJ,EAAE,EAAE,EAAE,4BAA4B,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBAC7K,EAAE,EAAE,EAAE,sBAAsB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAA0B,EAAE;gBACzJ,EAAE,EAAE,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAA0B,EAAE;aAC3J;YACD,MAAM,EAAE;gBACN,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,+BAA+B,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE;gBAC/I,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,CAAC,EAAE;gBACzJ,EAAE,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,gCAAgC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;aAC3I;YACD,MAAM,EAAE,sBAAsB,CAAC,YAAY,CAAC;SAC7C,CAAA;IACH,CAAC,CAAC;CACH,CAAC,CAAA","sourcesContent":["import {\n defineHarnessModule,\n MODULE_PROTOCOL_V1,\n PRELUDE_V1_SUPPORTED_FEATURES,\n} from '@sayoriqwq/prelude-contract'\nimport { Effect } from 'effect'\nimport * as TypeScript from 'typescript'\n\nconst effectLanguageServicePlugin = {\n name: '@effect/language-service',\n diagnostics: true,\n includeSuggestionsInTsc: true,\n ignoreEffectSuggestionsInTscExitCode: false,\n ignoreEffectWarningsInTscExitCode: false,\n ignoreEffectErrorsInTscExitCode: false,\n}\n\nconst routingBlock = `## Effect Harness\\n\\nFor Effect application, test, package, TypeScript, editor, or lint changes, read \\`effect/managed/docs/index.md\\` first. For ESLint or package-config repair, read \\`effect/managed/docs/package-config.md\\`; Antfu v9 integrations use its \\`antfu().append(...effectHarness)\\` form. Keep \\`effect/feedback/**\\` target-owned. Use installed Effect packages; never import pinned source diagnostics.\\n`\n\nfunction eslintIntegrationIssue(content: string | undefined) {\n if (typeof content === 'string') {\n if (hasEffectHarnessEslintComposition(content)) {\n return []\n }\n }\n\n return [{\n id: 'effect.eslint.integration',\n summary: 'Target ESLint config does not compose Effect Harness guardrails',\n detail: 'The target-owned eslint.config.mjs must import and include @sayoriqwq/effect-harness/eslint.',\n evidence: content === undefined ? 'eslint.config.mjs is absent.' : 'eslint.config.mjs does not reference the stable Effect Harness ESLint export.',\n guidance: 'prelude-assets/guidance/eslint.md',\n }] as const\n}\n\nfunction hasEffectHarnessEslintComposition(content: string): boolean {\n const source = TypeScript.createSourceFile(\n 'eslint.config.mjs',\n content,\n TypeScript.ScriptTarget.Latest,\n false,\n TypeScript.ScriptKind.JS,\n )\n\n let antfuBinding = ''\n for (const statement of source.statements) {\n if (\n TypeScript.isImportDeclaration(statement)\n && TypeScript.isStringLiteral(statement.moduleSpecifier)\n && statement.moduleSpecifier.text === '@antfu/eslint-config'\n ) {\n antfuBinding = statement.importClause?.name?.text ?? ''\n }\n }\n\n for (const statement of source.statements) {\n if (\n !TypeScript.isImportDeclaration(statement)\n || !TypeScript.isStringLiteral(statement.moduleSpecifier)\n || statement.moduleSpecifier.text !== '@sayoriqwq/effect-harness/eslint'\n ) {\n continue\n }\n\n const binding = statement.importClause?.name?.text ?? ''\n if (binding.length > 0 && composesEslintBinding(source, binding, antfuBinding)) {\n return true\n }\n }\n\n return false\n}\n\nfunction composesEslintBinding(\n source: TypeScript.SourceFile,\n binding: string,\n antfuBinding: string,\n): boolean {\n return source.statements.some((statement) => {\n if (TypeScript.isExportAssignment(statement) === false)\n return false\n\n if (statement.isExportEquals === true)\n return false\n\n if (TypeScript.isArrayLiteralExpression(statement.expression)) {\n const spreadsEffectConfig = statement.expression.elements.some(element =>\n TypeScript.isSpreadElement(element)\n && TypeScript.isIdentifier(element.expression)\n && element.expression.text === binding)\n return spreadsEffectConfig && !spreadsAntfuCall(statement.expression, antfuBinding)\n }\n\n return appendsEffectConfigToAntfu(statement.expression, binding, antfuBinding)\n })\n}\n\nfunction spreadsAntfuCall(expression: TypeScript.ArrayLiteralExpression, antfuBinding: string): boolean {\n return antfuBinding.length > 0 && expression.elements.some(element =>\n TypeScript.isSpreadElement(element)\n && TypeScript.isCallExpression(element.expression)\n && TypeScript.isIdentifier(element.expression.expression)\n && element.expression.expression.text === antfuBinding)\n}\n\nfunction appendsEffectConfigToAntfu(\n expression: TypeScript.Expression,\n effectBinding: string,\n antfuBinding: string,\n): boolean {\n if (antfuBinding.length === 0 || !TypeScript.isCallExpression(expression))\n return false\n\n const append = expression.expression\n if (!TypeScript.isPropertyAccessExpression(append) || append.name.text !== 'append')\n return false\n\n if (\n !TypeScript.isCallExpression(append.expression)\n || !TypeScript.isIdentifier(append.expression.expression)\n || append.expression.expression.text !== antfuBinding\n ) {\n return false\n }\n\n return expression.arguments.some(argument =>\n TypeScript.isSpreadElement(argument)\n && TypeScript.isIdentifier(argument.expression)\n && argument.expression.text === effectBinding)\n}\n\nexport const harnessModule = defineHarnessModule({\n descriptor: {\n harnessId: 'effect-harness',\n protocolVersion: MODULE_PROTOCOL_V1,\n requiredFeatures: PRELUDE_V1_SUPPORTED_FEATURES,\n },\n plan: context => Effect.gen(function* () {\n const eslintConfig = yield* context.target.readText('eslint.config.mjs')\n return {\n outputs: [\n {\n kind: 'ManagedTree' as const,\n id: 'effect.managed',\n sourceRoot: 'prelude-assets/effect/managed',\n targetRoot: 'effect/managed',\n },\n {\n kind: 'ManagedBlock' as const,\n id: 'effect.agent-routing',\n path: 'AGENTS.md',\n blockId: 'effect-harness-routing',\n content: routingBlock,\n },\n {\n kind: 'JsonKeyedItem' as const,\n id: 'effect.tsconfig.language-service',\n path: 'tsconfig.json',\n collectionPointer: '/compilerOptions/plugins',\n keyField: 'name',\n keyValue: '@effect/language-service',\n item: effectLanguageServicePlugin,\n },\n {\n kind: 'JsonValue' as const,\n id: 'effect.vscode.auto-import-exclude',\n path: '.vscode/settings.json',\n pointer: '/typescript.preferences.autoImportFileExcludePatterns',\n value: ['repos/**'],\n },\n {\n kind: 'JsonValue' as const,\n id: 'effect.vscode.javascript-auto-import-exclude',\n path: '.vscode/settings.json',\n pointer: '/javascript.preferences.autoImportFileExcludePatterns',\n value: ['repos/**'],\n },\n {\n kind: 'JsonValue' as const,\n id: 'effect.zed.auto-import-exclude',\n path: '.zed/settings.json',\n pointer: '/lsp/typescript-language-server/initialization_options/preferences/autoImportFileExcludePatterns',\n value: ['repos/**'],\n },\n ],\n requirements: [\n { id: 'effect.runtime', packageRoot: context.integration.packageRoot, packageName: 'effect', range: '4.0.0-beta.92', section: 'dependencies' as const },\n { id: 'effect.platform-node', packageRoot: context.integration.packageRoot, packageName: '@effect/platform-node', range: '4.0.0-beta.92', section: 'dependencies' as const },\n { id: 'effect.vitest', packageRoot: context.integration.packageRoot, packageName: '@effect/vitest', range: '4.0.0-beta.92', section: 'devDependencies' as const },\n { id: 'effect.tsgo', packageRoot: context.integration.packageRoot, packageName: '@effect/tsgo', range: '0.15.0', section: 'devDependencies' as const },\n { id: 'effect.language-service', packageRoot: context.integration.packageRoot, packageName: '@effect/language-service', range: '0.86.2', section: 'devDependencies' as const },\n { id: 'effect.native-typescript', packageRoot: context.integration.packageRoot, packageName: '@typescript/native-preview', range: '7.0.0-dev.20260630.1', section: 'devDependencies' as const },\n { id: 'effect.eslint', packageRoot: context.integration.packageRoot, packageName: 'eslint', range: '^10.3.0', section: 'devDependencies' as const },\n { id: 'effect.antfu-eslint-config', packageRoot: context.integration.packageRoot, packageName: '@antfu/eslint-config', range: '^9.0.0', section: 'devDependencies' as const },\n { id: 'effect.vitest-runner', packageRoot: context.integration.packageRoot, packageName: 'vitest', range: '^4.1.8', section: 'devDependencies' as const },\n { id: 'effect.typescript', packageRoot: context.integration.packageRoot, packageName: 'typescript', range: '^6.0.3', section: 'devDependencies' as const },\n ],\n checks: [\n { id: 'effect.typecheck', summary: 'Run strict Effect diagnostics', packageRoot: context.integration.packageRoot, argv: ['pnpm', 'typecheck'] },\n { id: 'effect.lint', summary: 'Run Effect lint guardrails', packageRoot: context.integration.packageRoot, argv: ['pnpm', 'lint', '--max-warnings', '0'] },\n { id: 'effect.verify', summary: 'Run Effect domain verification', packageRoot: context.integration.packageRoot, argv: ['pnpm', 'verify'] },\n ],\n issues: eslintIntegrationIssue(eslintConfig),\n }\n }),\n})\n"]}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@sayoriqwq/effect-harness",
3
3
  "type": "module",
4
- "version": "0.0.5",
4
+ "version": "0.1.1",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "access": "public",
8
8
  "registry": "https://registry.npmjs.org/"
9
9
  },
10
- "description": "Effect v4 beta provider profile and source route package.",
10
+ "description": "Effect v4 beta Prelude Harness Module.",
11
11
  "license": "MIT",
12
12
  "repository": {
13
13
  "type": "git",
@@ -17,21 +17,25 @@
17
17
  ".": {
18
18
  "types": "./dist/src/index.d.ts",
19
19
  "import": "./dist/src/index.js"
20
+ },
21
+ "./prelude": {
22
+ "types": "./dist/src/prelude.d.ts",
23
+ "import": "./dist/src/prelude.js"
24
+ },
25
+ "./eslint": {
26
+ "types": "./dist/src/eslint.d.ts",
27
+ "import": "./dist/src/eslint.js"
20
28
  }
21
29
  },
22
30
  "main": "dist/src/index.js",
23
31
  "types": "dist/src/index.d.ts",
24
- "bin": {
25
- "effect-harness": "dist/bin/effect-harness.js"
26
- },
27
32
  "files": [
28
- "HARNESS.md",
29
- "README.md",
33
+ "diagnostics",
30
34
  "dist",
31
- "harness",
32
- "provider",
33
- "repos",
35
+ "prelude-assets",
36
+ "repos/effect",
34
37
  "repos/effect.subtree.json",
38
+ "repos/tsgo",
35
39
  "repos/tsgo.subtree.json"
36
40
  ],
37
41
  "engines": {
@@ -39,6 +43,7 @@
39
43
  },
40
44
  "dependencies": {
41
45
  "@effect/platform-node": "4.0.0-beta.92",
46
+ "@sayoriqwq/prelude-contract": "0.1.0",
42
47
  "effect": "4.0.0-beta.92",
43
48
  "typescript": "^6.0.3"
44
49
  },
@@ -55,17 +60,13 @@
55
60
  },
56
61
  "scripts": {
57
62
  "build": "tsc --project tsconfig.build.json",
58
- "dev": "pnpm build && node dist/bin/effect-harness.js --help",
59
- "effect:verify": "node bin/effect-harness.ts provider-verify --harness .",
63
+ "dev": "pnpm build",
60
64
  "knip": "knip",
61
65
  "lint": "eslint",
62
66
  "lint:fix": "eslint --fix",
63
- "source:status": "npx --yes @sayoriqwq/partita pin status --root . --contract repos/effect.subtree.json --name effect --prefix repos/effect && npx --yes @sayoriqwq/partita pin status --root . --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo",
64
- "source:update": "npx --yes @sayoriqwq/partita pin update --root . --contract repos/effect.subtree.json --name effect --prefix repos/effect --dry-run && npx --yes @sayoriqwq/partita pin update --root . --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo --dry-run",
65
- "source:verify": "npx --yes @sayoriqwq/partita pin verify --root . --contract repos/effect.subtree.json --name effect --prefix repos/effect && npx --yes @sayoriqwq/partita pin verify --root . --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo",
66
- "test": "vitest run tests/*.test.ts",
67
+ "test": "pnpm build && vitest run tests/*.test.ts",
67
68
  "typecheck": "tsgo --noEmit",
68
69
  "typecheck:tsc": "tsc --noEmit",
69
- "verify": "node bin/effect-harness.ts verify --harness ."
70
+ "verify": "pnpm typecheck && pnpm test && pnpm lint && pnpm knip"
70
71
  }
71
72
  }
@@ -0,0 +1,6 @@
1
+ # Diagnostics
2
+
3
+ Run `effect-tsgo patch` to prepare the backend and `tsgo --noEmit` for primary
4
+ Effect diagnostics. The language-service plugin treats errors, warnings,
5
+ suggestions, and messages as a zero-tolerance gate. Do not suppress or weaken
6
+ the configured policy to evade diagnostics.
@@ -0,0 +1,5 @@
1
+ # Editor policy
2
+
3
+ The declared VS Code and Zed values exclude `repos/**` from TypeScript and
4
+ JavaScript auto-imports. They protect Artifact-internal source diagnostics and
5
+ do not create target source trees.
@@ -0,0 +1,5 @@
1
+ # Effect code baseline
2
+
3
+ Use installed `effect`, `@effect/platform-node`, and `@effect/vitest` packages.
4
+ Do not import pinned source diagnostics. Prefer Effect v4 APIs, `Context.Service`,
5
+ and Effect-aware test entries.
@@ -0,0 +1,14 @@
1
+ # Effect managed guidance
2
+
3
+ This directory is the complete Effect Harness managed documentation bundle.
4
+ It is directly maintained by the Artifact and does not require a sibling
5
+ source checkout.
6
+
7
+ - Read [effect-code.md](./effect-code.md) before changing Effect code or tests.
8
+ - Read [diagnostics.md](./diagnostics.md) before changing packages or TypeScript.
9
+ - Read [editor-policy.md](./editor-policy.md) before changing editor settings.
10
+ - Read [package-config.md](./package-config.md) before configuration work.
11
+ - Read [quality-policy.md](./quality-policy.md) before verification work.
12
+
13
+ Pinned Effect and tsgo repositories are Artifact-internal source diagnostics.
14
+ They are never projected here. `effect/feedback/**` is target-owned.
@@ -0,0 +1,5 @@
1
+ # Managed surfaces
2
+
3
+ Effect Harness owns the complete `effect/managed/**` tree and one bounded root
4
+ routing block. `effect/feedback/**` remains target-owned through plan, apply,
5
+ and upgrade.
@@ -0,0 +1,20 @@
1
+ # Package and TypeScript configuration
2
+
3
+ Direct requirements cover the Effect runtime, Node platform, Effect Vitest,
4
+ tsgo, language service, native TypeScript backend, ESLint, Antfu config, and
5
+ Vitest. The named language-service plugin is structurally merged by its name.
6
+
7
+ ## Antfu v9 ESLint composition
8
+
9
+ `@antfu/eslint-config` v9 returns a `FlatConfigComposer`, not an iterable
10
+ array. Compose the stable Effect Harness export through `append`:
11
+
12
+ ```js
13
+ import antfu from '@antfu/eslint-config'
14
+ import effectHarness from '@sayoriqwq/effect-harness/eslint'
15
+
16
+ export default antfu().append(...effectHarness)
17
+ ```
18
+
19
+ Do not use `export default [...antfu(), ...effectHarness]`; it fails before
20
+ ESLint can lint because the Antfu composer is not iterable.