@sayoriqwq/effect-harness 0.0.4 → 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.
- package/README.md +9 -77
- package/diagnostics/effect-routes.md +6 -0
- package/diagnostics/index.md +10 -0
- package/diagnostics/tsgo-routes.md +5 -0
- package/dist/src/eslint.d.ts +57 -0
- package/dist/src/eslint.js +42 -0
- package/dist/src/eslint.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/prelude.d.ts +6 -0
- package/dist/src/prelude.js +161 -0
- package/dist/src/prelude.js.map +1 -0
- package/package.json +25 -17
- package/prelude-assets/effect/managed/docs/diagnostics.md +6 -0
- package/prelude-assets/effect/managed/docs/editor-policy.md +5 -0
- package/prelude-assets/effect/managed/docs/effect-code.md +5 -0
- package/prelude-assets/effect/managed/docs/index.md +14 -0
- package/prelude-assets/effect/managed/docs/managed-surfaces.md +5 -0
- package/prelude-assets/effect/managed/docs/package-config.md +20 -0
- package/prelude-assets/effect/managed/docs/quality-policy.md +5 -0
- package/prelude-assets/effect/managed/docs/source-identity.md +5 -0
- package/prelude-assets/guidance/eslint.md +15 -0
- package/repos/effect.subtree.json +2 -2
- package/repos/tsgo.subtree.json +2 -2
- package/HARNESS.md +0 -66
- package/dist/bin/effect-harness.d.ts +0 -2
- package/dist/bin/effect-harness.js +0 -34
- package/dist/bin/effect-harness.js.map +0 -1
- package/dist/src/cli/Main.d.ts +0 -7
- package/dist/src/cli/Main.js +0 -45
- package/dist/src/cli/Main.js.map +0 -1
- package/dist/src/harness/Errors.d.ts +0 -24
- package/dist/src/harness/Errors.js +0 -26
- package/dist/src/harness/Errors.js.map +0 -1
- package/dist/src/harness/Guardrails.d.ts +0 -7
- package/dist/src/harness/Guardrails.js +0 -50
- package/dist/src/harness/Guardrails.js.map +0 -1
- package/dist/src/harness/Model.d.ts +0 -52
- package/dist/src/harness/Model.js +0 -170
- package/dist/src/harness/Model.js.map +0 -1
- package/dist/src/harness/ModuleSources.d.ts +0 -5
- package/dist/src/harness/ModuleSources.js +0 -47
- package/dist/src/harness/ModuleSources.js.map +0 -1
- package/dist/src/harness/ProviderDiscovery.d.ts +0 -172
- package/dist/src/harness/ProviderDiscovery.js +0 -157
- package/dist/src/harness/ProviderDiscovery.js.map +0 -1
- package/dist/src/harness/SourcePin.d.ts +0 -4
- package/dist/src/harness/SourcePin.js +0 -214
- package/dist/src/harness/SourcePin.js.map +0 -1
- package/dist/src/harness/verify/JsonFields.d.ts +0 -1
- package/dist/src/harness/verify/JsonFields.js +0 -4
- package/dist/src/harness/verify/JsonFields.js.map +0 -1
- package/dist/src/harness/verify/Pipeline.d.ts +0 -7
- package/dist/src/harness/verify/Pipeline.js +0 -55
- package/dist/src/harness/verify/Pipeline.js.map +0 -1
- package/dist/src/harness/verify/ProviderProfile.d.ts +0 -3
- package/dist/src/harness/verify/ProviderProfile.js +0 -726
- package/dist/src/harness/verify/ProviderProfile.js.map +0 -1
- package/dist/src/harness/verify/ProviderRepository.d.ts +0 -4
- package/dist/src/harness/verify/ProviderRepository.js +0 -127
- package/dist/src/harness/verify/ProviderRepository.js.map +0 -1
- package/dist/src/harness/verify/Tsgo.d.ts +0 -3
- package/dist/src/harness/verify/Tsgo.js +0 -166
- package/dist/src/harness/verify/Tsgo.js.map +0 -1
- package/dist/src/harness/verify/TsgoMetadata.d.ts +0 -4
- package/dist/src/harness/verify/TsgoMetadata.js +0 -50
- package/dist/src/harness/verify/TsgoMetadata.js.map +0 -1
- package/dist/src/harness/verify/TsgoPolicy.d.ts +0 -208
- package/dist/src/harness/verify/TsgoPolicy.js +0 -143
- package/dist/src/harness/verify/TsgoPolicy.js.map +0 -1
- package/dist/src/harness/verify/TsgoSuppressions.d.ts +0 -2
- package/dist/src/harness/verify/TsgoSuppressions.js +0 -24
- package/dist/src/harness/verify/TsgoSuppressions.js.map +0 -1
- package/dist/src/harness/verify/VerifyStage.d.ts +0 -62
- package/dist/src/harness/verify/VerifyStage.js +0 -85
- package/dist/src/harness/verify/VerifyStage.js.map +0 -1
- package/dist/src/platform/Json.d.ts +0 -4
- package/dist/src/platform/Json.js +0 -16
- package/dist/src/platform/Json.js.map +0 -1
- package/dist/src/platform/Process.d.ts +0 -6
- package/dist/src/platform/Process.js +0 -35
- package/dist/src/platform/Process.js.map +0 -1
- package/harness/code.md +0 -83
- package/harness/diagnostic-layers.md +0 -94
- package/harness/effect-routes.md +0 -50
- package/harness/feedback-loop.md +0 -156
- package/harness/index.md +0 -83
- package/harness/offcial-guide.md +0 -50
- package/harness/offcial-migrate.md +0 -220
- package/harness/source.md +0 -91
- package/harness/tsgo-routes.md +0 -58
- package/harness/tsgo.md +0 -241
- package/provider/docs/diagnostics.md +0 -48
- package/provider/docs/discovery.md +0 -104
- package/provider/docs/editor-policy.md +0 -55
- package/provider/docs/effect-code.md +0 -41
- package/provider/docs/index.md +0 -48
- package/provider/docs/managed-surfaces.md +0 -51
- package/provider/docs/package-config.md +0 -71
- package/provider/docs/quality-policy.md +0 -68
- package/provider/docs/source-identity.md +0 -48
- package/provider/effect-harness.provider.json +0 -1020
- package/provider/index.md +0 -189
- package/provider/snippets/agents.md +0 -34
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"llmDocument": "repos/effect/LLMS.md"
|
|
19
19
|
},
|
|
20
20
|
"commands": {
|
|
21
|
-
"update": "partita pin update --contract repos/effect.subtree.json --name effect --prefix repos/effect --dry-run",
|
|
22
|
-
"verify": "partita pin verify --contract repos/effect.subtree.json --name effect --prefix repos/effect"
|
|
21
|
+
"update": "npx --yes @sayoriqwq/partita pin update --contract repos/effect.subtree.json --name effect --prefix repos/effect --dry-run",
|
|
22
|
+
"verify": "npx --yes @sayoriqwq/partita pin verify --contract repos/effect.subtree.json --name effect --prefix repos/effect"
|
|
23
23
|
},
|
|
24
24
|
"agent": {
|
|
25
25
|
"route": "harness/effect-routes.md"
|
package/repos/tsgo.subtree.json
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"llmDocument": "repos/tsgo/README.md"
|
|
19
19
|
},
|
|
20
20
|
"commands": {
|
|
21
|
-
"update": "partita pin update --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo --dry-run",
|
|
22
|
-
"verify": "partita pin verify --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo"
|
|
21
|
+
"update": "npx --yes @sayoriqwq/partita pin update --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo --dry-run",
|
|
22
|
+
"verify": "npx --yes @sayoriqwq/partita pin verify --contract repos/tsgo.subtree.json --name tsgo --prefix repos/tsgo"
|
|
23
23
|
},
|
|
24
24
|
"agent": {
|
|
25
25
|
"route": "harness/tsgo-routes.md"
|
package/HARNESS.md
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# Effect Harness 路线
|
|
2
|
-
|
|
3
|
-
本仓不是通用 pin 框架,也不是目标项目的第二套 maintain 系统。当前职责是维护 Effect/tsgo
|
|
4
|
-
源入口实例、读取路线、Effect 基线、strict tsgo policy、provider profile 和 target-facing 模板。
|
|
5
|
-
|
|
6
|
-
本仓采用 self-conformance 模型。`effect-harness` 是自身 provider contract 的第一个
|
|
7
|
-
conforming repository,完成态由 `pnpm verify` 证明。
|
|
8
|
-
|
|
9
|
-
self-conformance 不等于 self-materialization。本仓 MUST NOT 生成 `.prelude/**`、
|
|
10
|
-
`.prelude/providers/effect-harness/**` 或任何 Prelude target lifecycle state。
|
|
11
|
-
|
|
12
|
-
## 两层结构
|
|
13
|
-
|
|
14
|
-
| 层级 | 目的 | 本仓负责什么 | 不负责什么 |
|
|
15
|
-
| --- | --- | --- | --- |
|
|
16
|
-
| Harness 层 | 指导 `effect-harness` 本仓自己怎么运转 | 官方 guide、第一阶段实现说明、Effect/tsgo 源入口实例、路线表、strict policy、最小验证器 | 通用 pin 实现、目标项目落地生成 |
|
|
17
|
-
| Provider 层 | 声明任意 target 如何接入 effect-harness | 通过 provider profile 声明目标项目应接收的基线、诊断入口、source identities、docs bundle 和 snippets | 直接写目标 runtime、`.codex`、`.effect-harness.json`、目标 `AGENTS.md` 管理块 |
|
|
18
|
-
|
|
19
|
-
## Delivery Modes
|
|
20
|
-
|
|
21
|
-
| Mode | 含义 | 是否 target-local |
|
|
22
|
-
| --- | --- | --- |
|
|
23
|
-
| internal harness | 本仓维护和验证自身使用的文档、源码、测试和 verifier。 | 否 |
|
|
24
|
-
| provider artifact reference | 随 provider artifact 保留的 pinned source、route 和 source contract reference。 | 否 |
|
|
25
|
-
| exported harness | Prelude 后续可以投递并维护到 target 的 package、config、docs、snippets 和 provider record 能力。 | 是 |
|
|
26
|
-
|
|
27
|
-
## 真源
|
|
28
|
-
|
|
29
|
-
- `harness/offcial-guide.md`:仓内 guide 唯一真源。
|
|
30
|
-
- `harness/offcial-migrate.md`:官方 source access 与 LSP/tsgo 阶段的 harness 与 provider 实现说明。
|
|
31
|
-
- `harness/feedback-loop.md`:第二阶段 Codex feedback loop 和统一 verify pipeline。
|
|
32
|
-
- `harness/diagnostic-layers.md`:tsgo diagnostics、ESLint 和 harness guardrails 的分层职责。
|
|
33
|
-
- `harness/code.md`:本仓 TypeScript code surface 的职责和非职责。
|
|
34
|
-
- `repos/effect.subtree.json`:Partita 管理的 GitHub subtree pin 契约,是 Effect 源入口唯一真源。
|
|
35
|
-
- `repos/tsgo.subtree.json`:Partita 管理的 GitHub subtree pin 契约,是 tsgo 源入口真源。
|
|
36
|
-
- `repos/effect/LLMS.md`:pinned 上游 Effect LLM guide。
|
|
37
|
-
- `harness/effect-routes.md`:agent 读取 `repos/effect/` 的路线表。
|
|
38
|
-
- `harness/tsgo.md`:strict tsgo ADR、policy、rule map 和 upgrade loop。
|
|
39
|
-
- `harness/tsgo-routes.md`:agent 读取 `repos/tsgo/` 的路线表。
|
|
40
|
-
- `provider/index.md`:provider contract、capability 和 target surface 入口。
|
|
41
|
-
- `provider/effect-harness.provider.json`:provider profile,也是 package 基线和 managed template 真源。
|
|
42
|
-
- `provider/docs/**`:target-facing docs bundle source。
|
|
43
|
-
- `provider/snippets/**`:target-facing snippets source。
|
|
44
|
-
|
|
45
|
-
## 职责分配
|
|
46
|
-
|
|
47
|
-
- Partita 负责通用源入口 pin 流程。
|
|
48
|
-
- effect-harness 负责 Effect/tsgo 具体源入口实例、provider profile、docs bundle 和 snippets。
|
|
49
|
-
- Prelude 负责消费 provider profile,并维护 target provider record、drift、verify 和 maintain。
|
|
50
|
-
|
|
51
|
-
## 已移除表面
|
|
52
|
-
|
|
53
|
-
新基线不包含仓内 Codex skills、目标 runtime 模板、反馈入口、目标
|
|
54
|
-
`AGENTS.md` 管理块,也不保留 `.effect-harness.json` 独立状态。
|
|
55
|
-
|
|
56
|
-
## 验证
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
pnpm verify
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
完成态只认 `pnpm verify`。该命令由 Effect pipeline 组织,按 `source-pins`、
|
|
63
|
-
`harness-contract`、`tsgo-diagnostics`、`tests`、`lint`、`knip` 顺序 fail-fast 执行。
|
|
64
|
-
`pnpm source:status`、`pnpm source:update` 和局部 verify scripts 只作为排错入口。
|
|
65
|
-
|
|
66
|
-
目标项目由 Prelude provider maintain/verify;effect-harness 不直接向目标项目投影 runtime 资产。
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import process from 'node:process';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import * as NodeRuntime from '@effect/platform-node/NodeRuntime';
|
|
5
|
-
import * as NodeServices from '@effect/platform-node/NodeServices';
|
|
6
|
-
import { Effect, Layer } from 'effect';
|
|
7
|
-
import { runCli } from "../src/cli/Main.js";
|
|
8
|
-
import { errorMessage } from "../src/harness/Errors.js";
|
|
9
|
-
const harnessRoot = resolveHarnessRoot(fileURLToPath(import.meta.url));
|
|
10
|
-
NodeRuntime.runMain(runCli({
|
|
11
|
-
harnessRoot,
|
|
12
|
-
version: '0.0.0',
|
|
13
|
-
}).pipe(withNodeServices));
|
|
14
|
-
function resolveHarnessRoot(entrypoint) {
|
|
15
|
-
const marker = '/dist/bin/';
|
|
16
|
-
const index = entrypoint.indexOf(marker);
|
|
17
|
-
if (index >= 0) {
|
|
18
|
-
return entrypoint.slice(0, index);
|
|
19
|
-
}
|
|
20
|
-
const sourceBinIndex = entrypoint.lastIndexOf('/bin/');
|
|
21
|
-
if (sourceBinIndex >= 0) {
|
|
22
|
-
return entrypoint.slice(0, sourceBinIndex);
|
|
23
|
-
}
|
|
24
|
-
return process.cwd();
|
|
25
|
-
}
|
|
26
|
-
function withNodeServices(effect) {
|
|
27
|
-
return Effect.scoped(Effect.gen(function* () {
|
|
28
|
-
const context = yield* Layer.build(NodeServices.layer);
|
|
29
|
-
return yield* Effect.promise(() => Effect.runPromiseWith(context)(effect.pipe(Effect.catch((error) => Effect.andThen(Effect.logError(errorMessage(error)), Effect.sync(() => {
|
|
30
|
-
process.exitCode = 1;
|
|
31
|
-
}))))));
|
|
32
|
-
}));
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=effect-harness.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"effect-harness.js","sourceRoot":"","sources":["../../bin/effect-harness.ts"],"names":[],"mappings":";AAEA,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,KAAK,WAAW,MAAM,mCAAmC,CAAA;AAChE,OAAO,KAAK,YAAY,MAAM,oCAAoC,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD,MAAM,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAEtE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;IACzB,WAAW;IACX,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAE1B,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,MAAM,MAAM,GAAG,YAAY,CAAA;IAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACnC,CAAC;IACD,MAAM,cAAc,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACtD,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;IAC5C,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAA;AACtB,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAyD;IAEzD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACvC,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,IAAI,CAC3E,MAAM,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAC9B,MAAM,CAAC,OAAO,CACZ,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EACpC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;QACtB,CAAC,CAAC,CACH,CAAC,CACL,CAAC,CAAC,CAAA;IACL,CAAC,CAAC,CAAC,CAAA;AACL,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport process from 'node:process'\nimport { fileURLToPath } from 'node:url'\nimport * as NodeRuntime from '@effect/platform-node/NodeRuntime'\nimport * as NodeServices from '@effect/platform-node/NodeServices'\nimport { Effect, Layer } from 'effect'\nimport { runCli } from '../src/cli/Main.ts'\nimport { errorMessage } from '../src/harness/Errors.ts'\n\nconst harnessRoot = resolveHarnessRoot(fileURLToPath(import.meta.url))\n\nNodeRuntime.runMain(runCli({\n harnessRoot,\n version: '0.0.0',\n}).pipe(withNodeServices))\n\nfunction resolveHarnessRoot(entrypoint: string) {\n const marker = '/dist/bin/'\n const index = entrypoint.indexOf(marker)\n if (index >= 0) {\n return entrypoint.slice(0, index)\n }\n const sourceBinIndex = entrypoint.lastIndexOf('/bin/')\n if (sourceBinIndex >= 0) {\n return entrypoint.slice(0, sourceBinIndex)\n }\n return process.cwd()\n}\n\nfunction withNodeServices<E>(\n effect: Effect.Effect<void, E, NodeServices.NodeServices>,\n): Effect.Effect<void, never> {\n return Effect.scoped(Effect.gen(function* () {\n const context = yield* Layer.build(NodeServices.layer)\n return yield* Effect.promise(() => Effect.runPromiseWith(context)(effect.pipe(\n Effect.catch((error: unknown) =>\n Effect.andThen(\n Effect.logError(errorMessage(error)),\n Effect.sync(() => {\n process.exitCode = 1\n }),\n )),\n )))\n }))\n}\n"]}
|
package/dist/src/cli/Main.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Effect, Schema } from 'effect';
|
|
2
|
-
import * as Command from 'effect/unstable/cli/Command';
|
|
3
|
-
export interface CliConfig {
|
|
4
|
-
readonly harnessRoot: string;
|
|
5
|
-
readonly version: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function runCli(config: CliConfig): Effect.Effect<void, import("../harness/Errors.ts").HarnessError | import("../harness/Errors.ts").ProcessError | Schema.SchemaError | import("effect/PlatformError").PlatformError | import("../harness/verify/VerifyStage.ts").VerifyStageFailed | import("effect/unstable/cli/CliError").CliError, Command.Environment>;
|
package/dist/src/cli/Main.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import process from 'node:process';
|
|
2
|
-
import { Console, Effect, Path, Schema } from 'effect';
|
|
3
|
-
import * as Command from 'effect/unstable/cli/Command';
|
|
4
|
-
import * as Flag from 'effect/unstable/cli/Flag';
|
|
5
|
-
import { discoverProvider } from "../harness/ProviderDiscovery.js";
|
|
6
|
-
const resolveFromCwd = Effect.fnUntraced(function* (value) {
|
|
7
|
-
const path = yield* Path.Path;
|
|
8
|
-
return path.resolve(process.cwd(), value);
|
|
9
|
-
});
|
|
10
|
-
function harnessFlag(defaultRoot) {
|
|
11
|
-
return Flag.path('harness').pipe(Flag.withDescription('Effect harness repository root'), Flag.withDefault(defaultRoot), Flag.mapEffect(resolveFromCwd));
|
|
12
|
-
}
|
|
13
|
-
function makeCli(config) {
|
|
14
|
-
const harness = harnessFlag(config.harnessRoot);
|
|
15
|
-
const providerVerify = Command.make('provider-verify', {
|
|
16
|
-
harness,
|
|
17
|
-
}, Effect.fnUntraced(function* ({ harness }) {
|
|
18
|
-
const { verifyProviderRepository } = yield* Effect.promise(() => import("../harness/verify/ProviderRepository.js"));
|
|
19
|
-
yield* verifyProviderRepository(harness);
|
|
20
|
-
})).pipe(Command.withDescription('Check the Effect harness provider repository'));
|
|
21
|
-
const providerDiscover = Command.make('provider-discover', {
|
|
22
|
-
harness,
|
|
23
|
-
}, Effect.fnUntraced(function* ({ harness }) {
|
|
24
|
-
const discovery = yield* discoverProvider(harness);
|
|
25
|
-
const discoveryText = yield* Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(discovery);
|
|
26
|
-
yield* Console.log(discoveryText);
|
|
27
|
-
})).pipe(Command.withDescription('Print the machine-readable provider discovery envelope'));
|
|
28
|
-
const sourceVerify = Command.make('source-verify', {
|
|
29
|
-
harness,
|
|
30
|
-
}, Effect.fnUntraced(function* ({ harness }) {
|
|
31
|
-
const { verifySourcePin } = yield* Effect.promise(() => import("../harness/SourcePin.js"));
|
|
32
|
-
yield* verifySourcePin(harness);
|
|
33
|
-
})).pipe(Command.withDescription('Check the pinned official Effect and tsgo source subtrees'));
|
|
34
|
-
const verify = Command.make('verify', {
|
|
35
|
-
harness,
|
|
36
|
-
}, Effect.fnUntraced(function* ({ harness }) {
|
|
37
|
-
const { verifyPipeline } = yield* Effect.promise(() => import("../harness/verify/Pipeline.js"));
|
|
38
|
-
yield* verifyPipeline(harness);
|
|
39
|
-
})).pipe(Command.withDescription('Run the full Effect harness verification pipeline'));
|
|
40
|
-
return Command.make('effect-harness').pipe(Command.withDescription('Effect v4 beta provider CLI'), Command.withSubcommands([verify, providerVerify, providerDiscover, sourceVerify]));
|
|
41
|
-
}
|
|
42
|
-
export function runCli(config) {
|
|
43
|
-
return makeCli(config).pipe(Command.run({ version: config.version }));
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=Main.js.map
|
package/dist/src/cli/Main.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../../../src/cli/Main.ts"],"names":[],"mappings":"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","sourcesContent":["import process from 'node:process'\nimport { Console, Effect, Path, Schema } from 'effect'\nimport * as Command from 'effect/unstable/cli/Command'\nimport * as Flag from 'effect/unstable/cli/Flag'\nimport { discoverProvider } from '../harness/ProviderDiscovery.ts'\n\nexport interface CliConfig {\n readonly harnessRoot: string\n readonly version: string\n}\n\nconst resolveFromCwd = Effect.fnUntraced(function* (value: string) {\n const path = yield* Path.Path\n return path.resolve(process.cwd(), value)\n})\n\nfunction harnessFlag(defaultRoot: string) {\n return Flag.path('harness').pipe(\n Flag.withDescription('Effect harness repository root'),\n Flag.withDefault(defaultRoot),\n Flag.mapEffect(resolveFromCwd),\n )\n}\n\nfunction makeCli(config: CliConfig) {\n const harness = harnessFlag(config.harnessRoot)\n\n const providerVerify = Command.make('provider-verify', {\n harness,\n }, Effect.fnUntraced(function* ({ harness }) {\n const { verifyProviderRepository } = yield* Effect.promise(() => import('../harness/verify/ProviderRepository.ts'))\n yield* verifyProviderRepository(harness)\n })).pipe(\n Command.withDescription('Check the Effect harness provider repository'),\n )\n\n const providerDiscover = Command.make('provider-discover', {\n harness,\n }, Effect.fnUntraced(function* ({ harness }) {\n const discovery = yield* discoverProvider(harness)\n const discoveryText = yield* Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(discovery)\n yield* Console.log(discoveryText)\n })).pipe(\n Command.withDescription('Print the machine-readable provider discovery envelope'),\n )\n\n const sourceVerify = Command.make('source-verify', {\n harness,\n }, Effect.fnUntraced(function* ({ harness }) {\n const { verifySourcePin } = yield* Effect.promise(() => import('../harness/SourcePin.ts'))\n yield* verifySourcePin(harness)\n })).pipe(\n Command.withDescription('Check the pinned official Effect and tsgo source subtrees'),\n )\n\n const verify = Command.make('verify', {\n harness,\n }, Effect.fnUntraced(function* ({ harness }) {\n const { verifyPipeline } = yield* Effect.promise(() => import('../harness/verify/Pipeline.ts'))\n yield* verifyPipeline(harness)\n })).pipe(\n Command.withDescription('Run the full Effect harness verification pipeline'),\n )\n\n return Command.make('effect-harness').pipe(\n Command.withDescription('Effect v4 beta provider CLI'),\n Command.withSubcommands([verify, providerVerify, providerDiscover, sourceVerify]),\n )\n}\n\nexport function runCli(config: CliConfig) {\n return makeCli(config).pipe(\n Command.run({ version: config.version }),\n )\n}\n"]}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
declare const HarnessError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
2
|
-
readonly _tag: "@sayoriqwq/effect-harness/harness/Errors/HarnessError";
|
|
3
|
-
} & Readonly<A>;
|
|
4
|
-
export declare class HarnessError extends HarnessError_base<{
|
|
5
|
-
readonly message: string;
|
|
6
|
-
readonly cause?: unknown;
|
|
7
|
-
}> {
|
|
8
|
-
}
|
|
9
|
-
declare const ProcessError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
10
|
-
readonly _tag: "@sayoriqwq/effect-harness/harness/Errors/ProcessError";
|
|
11
|
-
} & Readonly<A>;
|
|
12
|
-
export declare class ProcessError extends ProcessError_base<{
|
|
13
|
-
readonly args: ReadonlyArray<string>;
|
|
14
|
-
readonly command: string;
|
|
15
|
-
readonly exitCode?: number;
|
|
16
|
-
readonly message: string;
|
|
17
|
-
readonly stderr: string;
|
|
18
|
-
readonly stdout: string;
|
|
19
|
-
readonly cause?: unknown;
|
|
20
|
-
readonly cwd?: string;
|
|
21
|
-
}> {
|
|
22
|
-
}
|
|
23
|
-
export declare function errorMessage(error: unknown): string;
|
|
24
|
-
export {};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Data } from 'effect';
|
|
2
|
-
export class HarnessError extends Data.TaggedError('@sayoriqwq/effect-harness/harness/Errors/HarnessError') {
|
|
3
|
-
}
|
|
4
|
-
export class ProcessError extends Data.TaggedError('@sayoriqwq/effect-harness/harness/Errors/ProcessError') {
|
|
5
|
-
}
|
|
6
|
-
export function errorMessage(error) {
|
|
7
|
-
if (error instanceof ProcessError) {
|
|
8
|
-
const processError = error;
|
|
9
|
-
const lines = [processError.message];
|
|
10
|
-
if (processError.stderr.trim().length > 0) {
|
|
11
|
-
lines.push(`stderr:\n${processError.stderr.trim()}`);
|
|
12
|
-
}
|
|
13
|
-
if (processError.stdout.trim().length > 0) {
|
|
14
|
-
lines.push(`stdout:\n${processError.stdout.trim()}`);
|
|
15
|
-
}
|
|
16
|
-
return lines.join('\n');
|
|
17
|
-
}
|
|
18
|
-
if (typeof error === 'object' && error !== null && 'message' in error) {
|
|
19
|
-
const message = error.message;
|
|
20
|
-
if (typeof message === 'string') {
|
|
21
|
-
return message;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return String(error);
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=Errors.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Errors.js","sourceRoot":"","sources":["../../../src/harness/Errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,MAAM,OAAO,YAAa,SAAQ,IAAI,CAAC,WAAW,CAAC,uDAAuD,CAGxG;CAAG;AAEL,MAAM,OAAO,YAAa,SAAQ,IAAI,CAAC,WAAW,CAAC,uDAAuD,CASxG;CAAG;AAEL,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,KAAK,CAAA;QAC1B,MAAM,KAAK,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QACpC,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACtD,CAAC;QACD,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACtD,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACtE,MAAM,OAAO,GAAI,KAAwC,CAAC,OAAO,CAAA;QACjE,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,OAAO,CAAA;QAChB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC","sourcesContent":["import { Data } from 'effect'\n\nexport class HarnessError extends Data.TaggedError('@sayoriqwq/effect-harness/harness/Errors/HarnessError')<{\n readonly message: string\n readonly cause?: unknown\n}> {}\n\nexport class ProcessError extends Data.TaggedError('@sayoriqwq/effect-harness/harness/Errors/ProcessError')<{\n readonly args: ReadonlyArray<string>\n readonly command: string\n readonly exitCode?: number\n readonly message: string\n readonly stderr: string\n readonly stdout: string\n readonly cause?: unknown\n readonly cwd?: string\n}> {}\n\nexport function errorMessage(error: unknown): string {\n if (error instanceof ProcessError) {\n const processError = error\n const lines = [processError.message]\n if (processError.stderr.trim().length > 0) {\n lines.push(`stderr:\\n${processError.stderr.trim()}`)\n }\n if (processError.stdout.trim().length > 0) {\n lines.push(`stdout:\\n${processError.stdout.trim()}`)\n }\n return lines.join('\\n')\n }\n\n if (typeof error === 'object' && error !== null && 'message' in error) {\n const message = (error as { readonly message?: unknown }).message\n if (typeof message === 'string') {\n return message\n }\n }\n return String(error)\n}\n"]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Effect, FileSystem } from 'effect';
|
|
2
|
-
import { HarnessError } from './Errors.ts';
|
|
3
|
-
export interface GuardrailOptions {
|
|
4
|
-
readonly root: string;
|
|
5
|
-
readonly includes: ReadonlyArray<string>;
|
|
6
|
-
}
|
|
7
|
-
export declare const verifyGuardrails: (options: GuardrailOptions) => Effect.Effect<undefined, HarnessError | import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Console, Effect, FileSystem } from 'effect';
|
|
2
|
-
import { HarnessError } from "./Errors.js";
|
|
3
|
-
import { moduleSources } from "./ModuleSources.js";
|
|
4
|
-
const sourceExtensions = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts'];
|
|
5
|
-
function isSourceFile(file) {
|
|
6
|
-
return sourceExtensions.some(extension => file.endsWith(extension));
|
|
7
|
-
}
|
|
8
|
-
const collectSourceFiles = Effect.fnUntraced(function* (root, includes) {
|
|
9
|
-
const fs = yield* FileSystem.FileSystem;
|
|
10
|
-
const files = [];
|
|
11
|
-
for (const include of includes) {
|
|
12
|
-
const directory = `${root}/${include}`;
|
|
13
|
-
if (!(yield* fs.exists(directory))) {
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
for (const entry of yield* fs.readDirectory(directory, { recursive: true })) {
|
|
17
|
-
const file = `${directory}/${entry}`;
|
|
18
|
-
const stat = yield* fs.stat(file);
|
|
19
|
-
if (stat.type !== 'Directory' && isSourceFile(file)) {
|
|
20
|
-
files.push(file);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return files;
|
|
25
|
-
});
|
|
26
|
-
export const verifyGuardrails = Effect.fnUntraced(function* (options) {
|
|
27
|
-
const fs = yield* FileSystem.FileSystem;
|
|
28
|
-
const violations = [];
|
|
29
|
-
const files = yield* collectSourceFiles(options.root, options.includes);
|
|
30
|
-
for (const file of files) {
|
|
31
|
-
const text = yield* fs.readFileString(file);
|
|
32
|
-
for (const { source } of moduleSources(file, text)) {
|
|
33
|
-
if (source === '@effect/cli' || source.startsWith('@effect/cli/')) {
|
|
34
|
-
violations.push(`${file} imports ${source}; use effect/unstable/cli for this baseline.`);
|
|
35
|
-
}
|
|
36
|
-
if (source.includes('repos/effect') || source.includes('repos/tsgo')) {
|
|
37
|
-
violations.push(`${file} imports ${source}; repos source pins are read-only reference material.`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
if (violations.length > 0) {
|
|
42
|
-
yield* Console.error('Effect provider guardrails failed:');
|
|
43
|
-
for (const violation of violations) {
|
|
44
|
-
yield* Console.error(`- ${violation}`);
|
|
45
|
-
}
|
|
46
|
-
return yield* new HarnessError({ message: 'Effect provider guardrails failed.' });
|
|
47
|
-
}
|
|
48
|
-
yield* Console.log(`Effect provider guardrails passed for ${files.length} files.`);
|
|
49
|
-
});
|
|
50
|
-
//# sourceMappingURL=Guardrails.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Guardrails.js","sourceRoot":"","sources":["../../../src/harness/Guardrails.ts"],"names":[],"mappings":"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","sourcesContent":["import { Console, Effect, FileSystem } from 'effect'\nimport { HarnessError } from './Errors.ts'\nimport { moduleSources } from './ModuleSources.ts'\n\nexport interface GuardrailOptions {\n readonly root: string\n readonly includes: ReadonlyArray<string>\n}\n\nconst sourceExtensions = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts'] as const\n\nfunction isSourceFile(file: string): boolean {\n return sourceExtensions.some(extension => file.endsWith(extension))\n}\n\nconst collectSourceFiles = Effect.fnUntraced(function* (root: string, includes: ReadonlyArray<string>) {\n const fs = yield* FileSystem.FileSystem\n const files: Array<string> = []\n\n for (const include of includes) {\n const directory = `${root}/${include}`\n if (!(yield* fs.exists(directory))) {\n continue\n }\n\n for (const entry of yield* fs.readDirectory(directory, { recursive: true })) {\n const file = `${directory}/${entry}`\n const stat = yield* fs.stat(file)\n if (stat.type !== 'Directory' && isSourceFile(file)) {\n files.push(file)\n }\n }\n }\n\n return files\n})\n\nexport const verifyGuardrails = Effect.fnUntraced(function* (options: GuardrailOptions) {\n const fs = yield* FileSystem.FileSystem\n const violations: Array<string> = []\n const files = yield* collectSourceFiles(options.root, options.includes)\n\n for (const file of files) {\n const text = yield* fs.readFileString(file)\n for (const { source } of moduleSources(file, text)) {\n if (source === '@effect/cli' || source.startsWith('@effect/cli/')) {\n violations.push(`${file} imports ${source}; use effect/unstable/cli for this baseline.`)\n }\n if (source.includes('repos/effect') || source.includes('repos/tsgo')) {\n violations.push(`${file} imports ${source}; repos source pins are read-only reference material.`)\n }\n }\n }\n\n if (violations.length > 0) {\n yield* Console.error('Effect provider guardrails failed:')\n for (const violation of violations) {\n yield* Console.error(`- ${violation}`)\n }\n return yield* new HarnessError({ message: 'Effect provider guardrails failed.' })\n }\n\n yield* Console.log(`Effect provider guardrails passed for ${files.length} files.`)\n})\n"]}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import { HarnessError } from './Errors.ts';
|
|
3
|
-
export interface EffectSubtreeManifest {
|
|
4
|
-
readonly schemaVersion: 1;
|
|
5
|
-
readonly name: string;
|
|
6
|
-
readonly github: {
|
|
7
|
-
readonly repository: string;
|
|
8
|
-
readonly branch: string;
|
|
9
|
-
readonly ref: string;
|
|
10
|
-
};
|
|
11
|
-
readonly local: {
|
|
12
|
-
readonly prefix: string;
|
|
13
|
-
};
|
|
14
|
-
readonly mechanism: 'git-subtree';
|
|
15
|
-
readonly subtree: {
|
|
16
|
-
readonly split: string;
|
|
17
|
-
readonly trailer: string;
|
|
18
|
-
};
|
|
19
|
-
readonly anchor: {
|
|
20
|
-
readonly llmDocument: string;
|
|
21
|
-
};
|
|
22
|
-
readonly agent: {
|
|
23
|
-
readonly route: string;
|
|
24
|
-
};
|
|
25
|
-
readonly commands: {
|
|
26
|
-
readonly update: string;
|
|
27
|
-
readonly verify: string;
|
|
28
|
-
};
|
|
29
|
-
readonly editorPolicy: {
|
|
30
|
-
readonly autoImportExclude: string;
|
|
31
|
-
readonly watcherExclude: string;
|
|
32
|
-
readonly searchExclude: string;
|
|
33
|
-
readonly filesExclude: string;
|
|
34
|
-
};
|
|
35
|
-
readonly ownership: {
|
|
36
|
-
readonly mode: string;
|
|
37
|
-
};
|
|
38
|
-
readonly boundaries: {
|
|
39
|
-
readonly readOnly: boolean;
|
|
40
|
-
readonly importBlock: boolean;
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
export interface PackageJson {
|
|
44
|
-
dependencies?: Record<string, string>;
|
|
45
|
-
devDependencies?: Record<string, string>;
|
|
46
|
-
peerDependencies?: Record<string, string>;
|
|
47
|
-
optionalDependencies?: Record<string, string>;
|
|
48
|
-
readonly [key: string]: unknown;
|
|
49
|
-
}
|
|
50
|
-
export declare function decodeManifest(value: unknown, source: string): Effect.Effect<EffectSubtreeManifest, HarnessError>;
|
|
51
|
-
export declare function decodeProviderPackageBaseline(value: unknown, source: string): Effect.Effect<Record<string, string>, HarnessError>;
|
|
52
|
-
export declare function decodePackageJson(value: unknown, source: string): Effect.Effect<PackageJson, HarnessError>;
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import { HarnessError } from "./Errors.js";
|
|
3
|
-
function isRecord(value) {
|
|
4
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
5
|
-
}
|
|
6
|
-
function stringField(record, key, source) {
|
|
7
|
-
const value = record[key];
|
|
8
|
-
return typeof value === 'string'
|
|
9
|
-
? Effect.succeed(value)
|
|
10
|
-
: Effect.fail(new HarnessError({ message: `${source} must contain string field: ${key}` }));
|
|
11
|
-
}
|
|
12
|
-
function numberField(record, key, source) {
|
|
13
|
-
const value = record[key];
|
|
14
|
-
return typeof value === 'number'
|
|
15
|
-
? Effect.succeed(value)
|
|
16
|
-
: Effect.fail(new HarnessError({ message: `${source} must contain number field: ${key}` }));
|
|
17
|
-
}
|
|
18
|
-
function booleanField(record, key, source) {
|
|
19
|
-
const value = record[key];
|
|
20
|
-
return typeof value === 'boolean'
|
|
21
|
-
? Effect.succeed(value)
|
|
22
|
-
: Effect.fail(new HarnessError({ message: `${source} must contain boolean field: ${key}` }));
|
|
23
|
-
}
|
|
24
|
-
function recordField(record, key, source) {
|
|
25
|
-
const value = record[key];
|
|
26
|
-
return isRecord(value)
|
|
27
|
-
? Effect.succeed(value)
|
|
28
|
-
: Effect.fail(new HarnessError({ message: `${source} must contain object field: ${key}` }));
|
|
29
|
-
}
|
|
30
|
-
function literalStringField(record, key, expected, source) {
|
|
31
|
-
return Effect.gen(function* () {
|
|
32
|
-
const value = yield* stringField(record, key, source);
|
|
33
|
-
if (value !== expected) {
|
|
34
|
-
return yield* new HarnessError({ message: `${source}.${key} must be ${expected}; got ${value}` });
|
|
35
|
-
}
|
|
36
|
-
return expected;
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
function literalNumberField(record, key, expected, source) {
|
|
40
|
-
return Effect.gen(function* () {
|
|
41
|
-
const value = yield* numberField(record, key, source);
|
|
42
|
-
if (value !== expected) {
|
|
43
|
-
return yield* new HarnessError({ message: `${source}.${key} must be ${expected}; got ${String(value)}` });
|
|
44
|
-
}
|
|
45
|
-
return expected;
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
function stringRecordField(record, key, source) {
|
|
49
|
-
const value = record[key];
|
|
50
|
-
if (!isRecord(value)) {
|
|
51
|
-
return Effect.fail(new HarnessError({ message: `${source} must contain object field: ${key}` }));
|
|
52
|
-
}
|
|
53
|
-
const result = {};
|
|
54
|
-
for (const [entryKey, entryValue] of Object.entries(value)) {
|
|
55
|
-
if (typeof entryValue !== 'string') {
|
|
56
|
-
return Effect.fail(new HarnessError({ message: `${source}.${key}.${entryKey} must be a string` }));
|
|
57
|
-
}
|
|
58
|
-
result[entryKey] = entryValue;
|
|
59
|
-
}
|
|
60
|
-
return Effect.succeed(result);
|
|
61
|
-
}
|
|
62
|
-
function optionalStringRecordField(record, key, source) {
|
|
63
|
-
const value = record[key];
|
|
64
|
-
if (value === undefined) {
|
|
65
|
-
return Effect.sync(() => undefined);
|
|
66
|
-
}
|
|
67
|
-
if (!isRecord(value)) {
|
|
68
|
-
return Effect.fail(new HarnessError({ message: `${source}.${key} must be an object when present` }));
|
|
69
|
-
}
|
|
70
|
-
const result = {};
|
|
71
|
-
for (const [entryKey, entryValue] of Object.entries(value)) {
|
|
72
|
-
if (typeof entryValue !== 'string') {
|
|
73
|
-
return Effect.fail(new HarnessError({ message: `${source}.${key}.${entryKey} must be a string` }));
|
|
74
|
-
}
|
|
75
|
-
result[entryKey] = entryValue;
|
|
76
|
-
}
|
|
77
|
-
return Effect.succeed(result);
|
|
78
|
-
}
|
|
79
|
-
export function decodeManifest(value, source) {
|
|
80
|
-
return Effect.gen(function* () {
|
|
81
|
-
if (!isRecord(value)) {
|
|
82
|
-
return yield* new HarnessError({ message: `${source} must be a JSON object` });
|
|
83
|
-
}
|
|
84
|
-
const github = yield* recordField(value, 'github', source);
|
|
85
|
-
const local = yield* recordField(value, 'local', source);
|
|
86
|
-
const subtree = yield* recordField(value, 'subtree', source);
|
|
87
|
-
const anchor = yield* recordField(value, 'anchor', source);
|
|
88
|
-
const agent = yield* recordField(value, 'agent', source);
|
|
89
|
-
const commands = yield* recordField(value, 'commands', source);
|
|
90
|
-
const editorPolicy = yield* recordField(value, 'editorPolicy', source);
|
|
91
|
-
const ownership = yield* recordField(value, 'ownership', source);
|
|
92
|
-
const boundaries = yield* recordField(value, 'boundaries', source);
|
|
93
|
-
return {
|
|
94
|
-
schemaVersion: yield* literalNumberField(value, 'schemaVersion', 1, source),
|
|
95
|
-
name: yield* stringField(value, 'name', source),
|
|
96
|
-
github: {
|
|
97
|
-
repository: yield* stringField(github, 'repository', `${source}.github`),
|
|
98
|
-
branch: yield* stringField(github, 'branch', `${source}.github`),
|
|
99
|
-
ref: yield* stringField(github, 'ref', `${source}.github`),
|
|
100
|
-
},
|
|
101
|
-
local: {
|
|
102
|
-
prefix: yield* stringField(local, 'prefix', `${source}.local`),
|
|
103
|
-
},
|
|
104
|
-
mechanism: yield* literalStringField(value, 'mechanism', 'git-subtree', source),
|
|
105
|
-
subtree: {
|
|
106
|
-
split: yield* stringField(subtree, 'split', `${source}.subtree`),
|
|
107
|
-
trailer: yield* stringField(subtree, 'trailer', `${source}.subtree`),
|
|
108
|
-
},
|
|
109
|
-
anchor: {
|
|
110
|
-
llmDocument: yield* stringField(anchor, 'llmDocument', `${source}.anchor`),
|
|
111
|
-
},
|
|
112
|
-
agent: {
|
|
113
|
-
route: yield* stringField(agent, 'route', `${source}.agent`),
|
|
114
|
-
},
|
|
115
|
-
commands: {
|
|
116
|
-
update: yield* stringField(commands, 'update', `${source}.commands`),
|
|
117
|
-
verify: yield* stringField(commands, 'verify', `${source}.commands`),
|
|
118
|
-
},
|
|
119
|
-
editorPolicy: {
|
|
120
|
-
autoImportExclude: yield* stringField(editorPolicy, 'autoImportExclude', `${source}.editorPolicy`),
|
|
121
|
-
watcherExclude: yield* stringField(editorPolicy, 'watcherExclude', `${source}.editorPolicy`),
|
|
122
|
-
searchExclude: yield* stringField(editorPolicy, 'searchExclude', `${source}.editorPolicy`),
|
|
123
|
-
filesExclude: yield* stringField(editorPolicy, 'filesExclude', `${source}.editorPolicy`),
|
|
124
|
-
},
|
|
125
|
-
ownership: {
|
|
126
|
-
mode: yield* stringField(ownership, 'mode', `${source}.ownership`),
|
|
127
|
-
},
|
|
128
|
-
boundaries: {
|
|
129
|
-
readOnly: yield* booleanField(boundaries, 'readOnly', `${source}.boundaries`),
|
|
130
|
-
importBlock: yield* booleanField(boundaries, 'importBlock', `${source}.boundaries`),
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
export function decodeProviderPackageBaseline(value, source) {
|
|
136
|
-
return Effect.gen(function* () {
|
|
137
|
-
if (!isRecord(value)) {
|
|
138
|
-
return yield* new HarnessError({ message: `${source} must be a JSON object` });
|
|
139
|
-
}
|
|
140
|
-
const profiles = yield* recordField(value, 'profiles', source);
|
|
141
|
-
const profile = yield* recordField(profiles, 'codex-effect-v4', `${source}.profiles`);
|
|
142
|
-
return yield* stringRecordField(profile, 'packageBaseline', `${source}.profiles.codex-effect-v4`);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
export function decodePackageJson(value, source) {
|
|
146
|
-
return Effect.gen(function* () {
|
|
147
|
-
if (!isRecord(value)) {
|
|
148
|
-
return yield* new HarnessError({ message: `${source} must be a JSON object` });
|
|
149
|
-
}
|
|
150
|
-
const packageJson = { ...value };
|
|
151
|
-
const dependencies = yield* optionalStringRecordField(value, 'dependencies', source);
|
|
152
|
-
const devDependencies = yield* optionalStringRecordField(value, 'devDependencies', source);
|
|
153
|
-
const peerDependencies = yield* optionalStringRecordField(value, 'peerDependencies', source);
|
|
154
|
-
const optionalDependencies = yield* optionalStringRecordField(value, 'optionalDependencies', source);
|
|
155
|
-
if (dependencies !== undefined) {
|
|
156
|
-
packageJson.dependencies = dependencies;
|
|
157
|
-
}
|
|
158
|
-
if (devDependencies !== undefined) {
|
|
159
|
-
packageJson.devDependencies = devDependencies;
|
|
160
|
-
}
|
|
161
|
-
if (peerDependencies !== undefined) {
|
|
162
|
-
packageJson.peerDependencies = peerDependencies;
|
|
163
|
-
}
|
|
164
|
-
if (optionalDependencies !== undefined) {
|
|
165
|
-
packageJson.optionalDependencies = optionalDependencies;
|
|
166
|
-
}
|
|
167
|
-
return packageJson;
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
//# sourceMappingURL=Model.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Model.js","sourceRoot":"","sources":["../../../src/harness/Model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAmD1C,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B,EAAE,GAAW,EAAE,MAAc;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,OAAO,KAAK,KAAK,QAAQ;QAC9B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,+BAA+B,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/F,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B,EAAE,GAAW,EAAE,MAAc;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,OAAO,KAAK,KAAK,QAAQ;QAC9B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,+BAA+B,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/F,CAAC;AAED,SAAS,YAAY,CAAC,MAA+B,EAAE,GAAW,EAAE,MAAc;IAChF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,OAAO,KAAK,KAAK,SAAS;QAC/B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,gCAAgC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;AAChG,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B,EAAE,GAAW,EAAE,MAAc;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,QAAQ,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,+BAA+B,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/F,CAAC;AAED,SAAS,kBAAkB,CACzB,MAA+B,EAC/B,GAAW,EACX,QAAW,EACX,MAAc;IAEd,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACrD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,GAAG,YAAY,QAAQ,SAAS,KAAK,EAAE,EAAE,CAAC,CAAA;QACnG,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,MAA+B,EAC/B,GAAW,EACX,QAAW,EACX,MAAc;IAEd,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACrD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,GAAG,YAAY,QAAQ,SAAS,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;QAC3G,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,MAA+B,EAAE,GAAW,EAAE,MAAc;IACrF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,+BAA+B,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAClG,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,GAAG,IAAI,QAAQ,mBAAmB,EAAE,CAAC,CAAC,CAAA;QACpG,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAA;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC/B,CAAC;AAED,SAAS,yBAAyB,CAChC,MAA+B,EAC/B,GAAW,EACX,MAAc;IAEd,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,IAAI,CAAC,GAAuC,EAAE,CAAC,SAAS,CAAC,CAAA;IACzE,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,GAAG,iCAAiC,EAAE,CAAC,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,GAAG,IAAI,QAAQ,mBAAmB,EAAE,CAAC,CAAC,CAAA;QACpG,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAA;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,MAAc;IAC3D,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,wBAAwB,EAAE,CAAC,CAAA;QAChF,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACxD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;QAC9D,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAAA;QACtE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;QAChE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,CAAA;QAElE,OAAO;YACL,aAAa,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC;YAC3E,IAAI,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/C,MAAM,EAAE;gBACN,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,SAAS,CAAC;gBACxE,MAAM,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,SAAS,CAAC;gBAChE,GAAG,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,SAAS,CAAC;aAC3D;YACD,KAAK,EAAE;gBACL,MAAM,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC;aAC/D;YACD,SAAS,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,CAAC;YAC/E,OAAO,EAAE;gBACP,KAAK,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,UAAU,CAAC;gBAChE,OAAO,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,UAAU,CAAC;aACrE;YACD,MAAM,EAAE;gBACN,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,SAAS,CAAC;aAC3E;YACD,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC;aAC7D;YACD,QAAQ,EAAE;gBACR,MAAM,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,CAAC;gBACpE,MAAM,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,CAAC;aACrE;YACD,YAAY,EAAE;gBACZ,iBAAiB,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,mBAAmB,EAAE,GAAG,MAAM,eAAe,CAAC;gBAClG,cAAc,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,MAAM,eAAe,CAAC;gBAC5F,aAAa,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,eAAe,EAAE,GAAG,MAAM,eAAe,CAAC;gBAC1F,YAAY,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,cAAc,EAAE,GAAG,MAAM,eAAe,CAAC;aACzF;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC;aACnE;YACD,UAAU,EAAE;gBACV,QAAQ,EAAE,KAAK,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,aAAa,CAAC;gBAC7E,WAAW,EAAE,KAAK,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,MAAM,aAAa,CAAC;aACpF;SACF,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAc,EAAE,MAAc;IAC1E,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,wBAAwB,EAAE,CAAC,CAAA;QAChF,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;QAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,WAAW,CAAC,CAAA;QACrF,OAAO,KAAK,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,2BAA2B,CAAC,CAAA;IACnG,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,MAAc;IAC9D,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,wBAAwB,EAAE,CAAC,CAAA;QAChF,CAAC;QAED,MAAM,WAAW,GAAgB,EAAE,GAAG,KAAK,EAAE,CAAA;QAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,yBAAyB,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAAA;QACpF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAA;QAC1F,MAAM,gBAAgB,GAAG,KAAK,CAAC,CAAC,yBAAyB,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,CAAC,CAAA;QAC5F,MAAM,oBAAoB,GAAG,KAAK,CAAC,CAAC,yBAAyB,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,CAAC,CAAA;QAEpG,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,WAAW,CAAC,YAAY,GAAG,YAAY,CAAA;QACzC,CAAC;QACD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,WAAW,CAAC,eAAe,GAAG,eAAe,CAAA;QAC/C,CAAC;QACD,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACnC,WAAW,CAAC,gBAAgB,GAAG,gBAAgB,CAAA;QACjD,CAAC;QACD,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;YACvC,WAAW,CAAC,oBAAoB,GAAG,oBAAoB,CAAA;QACzD,CAAC;QAED,OAAO,WAAW,CAAA;IACpB,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { Effect } from 'effect'\nimport { HarnessError } from './Errors.ts'\n\nexport interface EffectSubtreeManifest {\n readonly schemaVersion: 1\n readonly name: string\n readonly github: {\n readonly repository: string\n readonly branch: string\n readonly ref: string\n }\n readonly local: {\n readonly prefix: string\n }\n readonly mechanism: 'git-subtree'\n readonly subtree: {\n readonly split: string\n readonly trailer: string\n }\n readonly anchor: {\n readonly llmDocument: string\n }\n readonly agent: {\n readonly route: string\n }\n readonly commands: {\n readonly update: string\n readonly verify: string\n }\n readonly editorPolicy: {\n readonly autoImportExclude: string\n readonly watcherExclude: string\n readonly searchExclude: string\n readonly filesExclude: string\n }\n readonly ownership: {\n readonly mode: string\n }\n readonly boundaries: {\n readonly readOnly: boolean\n readonly importBlock: boolean\n }\n}\n\nexport interface PackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n readonly [key: string]: unknown\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction stringField(record: Record<string, unknown>, key: string, source: string): Effect.Effect<string, HarnessError> {\n const value = record[key]\n return typeof value === 'string'\n ? Effect.succeed(value)\n : Effect.fail(new HarnessError({ message: `${source} must contain string field: ${key}` }))\n}\n\nfunction numberField(record: Record<string, unknown>, key: string, source: string): Effect.Effect<number, HarnessError> {\n const value = record[key]\n return typeof value === 'number'\n ? Effect.succeed(value)\n : Effect.fail(new HarnessError({ message: `${source} must contain number field: ${key}` }))\n}\n\nfunction booleanField(record: Record<string, unknown>, key: string, source: string): Effect.Effect<boolean, HarnessError> {\n const value = record[key]\n return typeof value === 'boolean'\n ? Effect.succeed(value)\n : Effect.fail(new HarnessError({ message: `${source} must contain boolean field: ${key}` }))\n}\n\nfunction recordField(record: Record<string, unknown>, key: string, source: string): Effect.Effect<Record<string, unknown>, HarnessError> {\n const value = record[key]\n return isRecord(value)\n ? Effect.succeed(value)\n : Effect.fail(new HarnessError({ message: `${source} must contain object field: ${key}` }))\n}\n\nfunction literalStringField<const A extends string>(\n record: Record<string, unknown>,\n key: string,\n expected: A,\n source: string,\n): Effect.Effect<A, HarnessError> {\n return Effect.gen(function* () {\n const value = yield* stringField(record, key, source)\n if (value !== expected) {\n return yield* new HarnessError({ message: `${source}.${key} must be ${expected}; got ${value}` })\n }\n return expected\n })\n}\n\nfunction literalNumberField<const A extends number>(\n record: Record<string, unknown>,\n key: string,\n expected: A,\n source: string,\n): Effect.Effect<A, HarnessError> {\n return Effect.gen(function* () {\n const value = yield* numberField(record, key, source)\n if (value !== expected) {\n return yield* new HarnessError({ message: `${source}.${key} must be ${expected}; got ${String(value)}` })\n }\n return expected\n })\n}\n\nfunction stringRecordField(record: Record<string, unknown>, key: string, source: string): Effect.Effect<Record<string, string>, HarnessError> {\n const value = record[key]\n if (!isRecord(value)) {\n return Effect.fail(new HarnessError({ message: `${source} must contain object field: ${key}` }))\n }\n\n const result: Record<string, string> = {}\n for (const [entryKey, entryValue] of Object.entries(value)) {\n if (typeof entryValue !== 'string') {\n return Effect.fail(new HarnessError({ message: `${source}.${key}.${entryKey} must be a string` }))\n }\n result[entryKey] = entryValue\n }\n return Effect.succeed(result)\n}\n\nfunction optionalStringRecordField(\n record: Record<string, unknown>,\n key: string,\n source: string,\n): Effect.Effect<Record<string, string> | undefined, HarnessError> {\n const value = record[key]\n if (value === undefined) {\n return Effect.sync((): Record<string, string> | undefined => undefined)\n }\n if (!isRecord(value)) {\n return Effect.fail(new HarnessError({ message: `${source}.${key} must be an object when present` }))\n }\n\n const result: Record<string, string> = {}\n for (const [entryKey, entryValue] of Object.entries(value)) {\n if (typeof entryValue !== 'string') {\n return Effect.fail(new HarnessError({ message: `${source}.${key}.${entryKey} must be a string` }))\n }\n result[entryKey] = entryValue\n }\n return Effect.succeed(result)\n}\n\nexport function decodeManifest(value: unknown, source: string): Effect.Effect<EffectSubtreeManifest, HarnessError> {\n return Effect.gen(function* () {\n if (!isRecord(value)) {\n return yield* new HarnessError({ message: `${source} must be a JSON object` })\n }\n\n const github = yield* recordField(value, 'github', source)\n const local = yield* recordField(value, 'local', source)\n const subtree = yield* recordField(value, 'subtree', source)\n const anchor = yield* recordField(value, 'anchor', source)\n const agent = yield* recordField(value, 'agent', source)\n const commands = yield* recordField(value, 'commands', source)\n const editorPolicy = yield* recordField(value, 'editorPolicy', source)\n const ownership = yield* recordField(value, 'ownership', source)\n const boundaries = yield* recordField(value, 'boundaries', source)\n\n return {\n schemaVersion: yield* literalNumberField(value, 'schemaVersion', 1, source),\n name: yield* stringField(value, 'name', source),\n github: {\n repository: yield* stringField(github, 'repository', `${source}.github`),\n branch: yield* stringField(github, 'branch', `${source}.github`),\n ref: yield* stringField(github, 'ref', `${source}.github`),\n },\n local: {\n prefix: yield* stringField(local, 'prefix', `${source}.local`),\n },\n mechanism: yield* literalStringField(value, 'mechanism', 'git-subtree', source),\n subtree: {\n split: yield* stringField(subtree, 'split', `${source}.subtree`),\n trailer: yield* stringField(subtree, 'trailer', `${source}.subtree`),\n },\n anchor: {\n llmDocument: yield* stringField(anchor, 'llmDocument', `${source}.anchor`),\n },\n agent: {\n route: yield* stringField(agent, 'route', `${source}.agent`),\n },\n commands: {\n update: yield* stringField(commands, 'update', `${source}.commands`),\n verify: yield* stringField(commands, 'verify', `${source}.commands`),\n },\n editorPolicy: {\n autoImportExclude: yield* stringField(editorPolicy, 'autoImportExclude', `${source}.editorPolicy`),\n watcherExclude: yield* stringField(editorPolicy, 'watcherExclude', `${source}.editorPolicy`),\n searchExclude: yield* stringField(editorPolicy, 'searchExclude', `${source}.editorPolicy`),\n filesExclude: yield* stringField(editorPolicy, 'filesExclude', `${source}.editorPolicy`),\n },\n ownership: {\n mode: yield* stringField(ownership, 'mode', `${source}.ownership`),\n },\n boundaries: {\n readOnly: yield* booleanField(boundaries, 'readOnly', `${source}.boundaries`),\n importBlock: yield* booleanField(boundaries, 'importBlock', `${source}.boundaries`),\n },\n }\n })\n}\n\nexport function decodeProviderPackageBaseline(value: unknown, source: string): Effect.Effect<Record<string, string>, HarnessError> {\n return Effect.gen(function* () {\n if (!isRecord(value)) {\n return yield* new HarnessError({ message: `${source} must be a JSON object` })\n }\n\n const profiles = yield* recordField(value, 'profiles', source)\n const profile = yield* recordField(profiles, 'codex-effect-v4', `${source}.profiles`)\n return yield* stringRecordField(profile, 'packageBaseline', `${source}.profiles.codex-effect-v4`)\n })\n}\n\nexport function decodePackageJson(value: unknown, source: string): Effect.Effect<PackageJson, HarnessError> {\n return Effect.gen(function* () {\n if (!isRecord(value)) {\n return yield* new HarnessError({ message: `${source} must be a JSON object` })\n }\n\n const packageJson: PackageJson = { ...value }\n const dependencies = yield* optionalStringRecordField(value, 'dependencies', source)\n const devDependencies = yield* optionalStringRecordField(value, 'devDependencies', source)\n const peerDependencies = yield* optionalStringRecordField(value, 'peerDependencies', source)\n const optionalDependencies = yield* optionalStringRecordField(value, 'optionalDependencies', source)\n\n if (dependencies !== undefined) {\n packageJson.dependencies = dependencies\n }\n if (devDependencies !== undefined) {\n packageJson.devDependencies = devDependencies\n }\n if (peerDependencies !== undefined) {\n packageJson.peerDependencies = peerDependencies\n }\n if (optionalDependencies !== undefined) {\n packageJson.optionalDependencies = optionalDependencies\n }\n\n return packageJson\n })\n}\n"]}
|