devcontour-harness 0.1.0-alpha.5 → 0.1.0-alpha.7
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 +42 -2
- package/docs/compatibility-versions.md +56 -0
- package/docs/compatibility.md +2 -2
- package/docs/connectors.md +323 -0
- package/docs/contracts.md +33 -5
- package/docs/integrations/hindsight.md +148 -0
- package/docs/quickstart.md +1 -1
- package/docs/release-notes/0.1.0-alpha.6.md +238 -0
- package/docs/release-notes/0.1.0-alpha.7.md +71 -0
- package/docs/review-probes.md +199 -0
- package/docs/review-protocol.md +251 -0
- package/docs/toolchains.md +167 -0
- package/docs/turbo-starter.md +269 -0
- package/docs/upgrade.md +77 -24
- package/examples/README.md +1 -0
- package/examples/toolchains/README.md +32 -0
- package/examples/toolchains/go/bad/label/label.go +9 -0
- package/examples/toolchains/go/good/label/label.go +9 -0
- package/examples/toolchains/go/policy.json +79 -0
- package/examples/toolchains/go/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/go/repo/_gitignore +1 -0
- package/examples/toolchains/go/repo/go.mod +5 -0
- package/examples/toolchains/go/repo/go.sum +2 -0
- package/examples/toolchains/go/repo/label/label.go +9 -0
- package/examples/toolchains/go/repo/label/label_test.go +27 -0
- package/examples/toolchains/go/repo/label/version.go +9 -0
- package/examples/toolchains/go/task.json +25 -0
- package/examples/toolchains/mixed-go/bad/backend/label/label.go +9 -0
- package/examples/toolchains/mixed-go/bad/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-go/good/backend/label/label.go +9 -0
- package/examples/toolchains/mixed-go/good/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-go/policy.json +126 -0
- package/examples/toolchains/mixed-go/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/mixed-go/repo/_gitignore +6 -0
- package/examples/toolchains/mixed-go/repo/backend/go.mod +3 -0
- package/examples/toolchains/mixed-go/repo/backend/label/label.go +9 -0
- package/examples/toolchains/mixed-go/repo/backend/label/label_test.go +30 -0
- package/examples/toolchains/mixed-go/repo/contract/check.mjs +17 -0
- package/examples/toolchains/mixed-go/repo/contract/label.json +9 -0
- package/examples/toolchains/mixed-go/repo/frontend/package.json +15 -0
- package/examples/toolchains/mixed-go/repo/frontend/pnpm-lock.yaml +22 -0
- package/examples/toolchains/mixed-go/repo/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-go/repo/frontend/test/label.test.js +11 -0
- package/examples/toolchains/mixed-go/task.json +25 -0
- package/examples/toolchains/mixed-python/bad/backend/src/fx_backend/__init__.py +6 -0
- package/examples/toolchains/mixed-python/bad/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-python/good/backend/src/fx_backend/__init__.py +6 -0
- package/examples/toolchains/mixed-python/good/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-python/policy.json +121 -0
- package/examples/toolchains/mixed-python/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/mixed-python/repo/_gitignore +6 -0
- package/examples/toolchains/mixed-python/repo/backend/.python-version +1 -0
- package/examples/toolchains/mixed-python/repo/backend/pyproject.toml +19 -0
- package/examples/toolchains/mixed-python/repo/backend/src/fx_backend/__init__.py +6 -0
- package/examples/toolchains/mixed-python/repo/backend/tests/test_label.py +11 -0
- package/examples/toolchains/mixed-python/repo/backend/uv.lock +108 -0
- package/examples/toolchains/mixed-python/repo/contract/check.mjs +17 -0
- package/examples/toolchains/mixed-python/repo/contract/label.json +9 -0
- package/examples/toolchains/mixed-python/repo/frontend/package.json +15 -0
- package/examples/toolchains/mixed-python/repo/frontend/pnpm-lock.yaml +22 -0
- package/examples/toolchains/mixed-python/repo/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-python/repo/frontend/test/label.test.js +11 -0
- package/examples/toolchains/mixed-python/task.json +25 -0
- package/examples/toolchains/npm/bad/src/label.js +4 -0
- package/examples/toolchains/npm/good/src/label.js +4 -0
- package/examples/toolchains/npm/policy.json +82 -0
- package/examples/toolchains/npm/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/npm/repo/_gitignore +4 -0
- package/examples/toolchains/npm/repo/package-lock.json +22 -0
- package/examples/toolchains/npm/repo/package.json +13 -0
- package/examples/toolchains/npm/repo/src/label.js +4 -0
- package/examples/toolchains/npm/repo/test/label.test.js +13 -0
- package/examples/toolchains/npm/task.json +25 -0
- package/examples/toolchains/pnpm/bad/packages/label/src/label.js +4 -0
- package/examples/toolchains/pnpm/good/packages/label/src/label.js +4 -0
- package/examples/toolchains/pnpm/policy.json +85 -0
- package/examples/toolchains/pnpm/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/pnpm/repo/_gitignore +4 -0
- package/examples/toolchains/pnpm/repo/package.json +10 -0
- package/examples/toolchains/pnpm/repo/packages/checker/check.mjs +5 -0
- package/examples/toolchains/pnpm/repo/packages/checker/package.json +9 -0
- package/examples/toolchains/pnpm/repo/packages/label/package.json +14 -0
- package/examples/toolchains/pnpm/repo/packages/label/src/label.js +4 -0
- package/examples/toolchains/pnpm/repo/packages/label/test/label.test.js +13 -0
- package/examples/toolchains/pnpm/repo/pnpm-lock.yaml +29 -0
- package/examples/toolchains/pnpm/repo/pnpm-workspace.yaml +2 -0
- package/examples/toolchains/pnpm/task.json +25 -0
- package/examples/toolchains/python/bad/src/fx_label/__init__.py +6 -0
- package/examples/toolchains/python/good/src/fx_label/__init__.py +6 -0
- package/examples/toolchains/python/policy.json +80 -0
- package/examples/toolchains/python/repo/.python-version +1 -0
- package/examples/toolchains/python/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/python/repo/_gitignore +5 -0
- package/examples/toolchains/python/repo/pyproject.toml +19 -0
- package/examples/toolchains/python/repo/src/fx_label/__init__.py +6 -0
- package/examples/toolchains/python/repo/tests/test_label.py +13 -0
- package/examples/toolchains/python/repo/uv.lock +108 -0
- package/examples/toolchains/python/task.json +25 -0
- package/examples/toolchains/turbo/bad/packages/label/src/label.js +4 -0
- package/examples/toolchains/turbo/good/packages/label/src/label.js +4 -0
- package/examples/toolchains/turbo/policy.json +110 -0
- package/examples/toolchains/turbo/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/turbo/repo/_gitignore +4 -0
- package/examples/toolchains/turbo/repo/package.json +13 -0
- package/examples/toolchains/turbo/repo/packages/checker/check.mjs +5 -0
- package/examples/toolchains/turbo/repo/packages/checker/package.json +9 -0
- package/examples/toolchains/turbo/repo/packages/label/package.json +14 -0
- package/examples/toolchains/turbo/repo/packages/label/src/label.js +4 -0
- package/examples/toolchains/turbo/repo/packages/label/test/label.test.js +13 -0
- package/examples/toolchains/turbo/repo/pnpm-lock.yaml +94 -0
- package/examples/toolchains/turbo/repo/pnpm-workspace.yaml +2 -0
- package/examples/toolchains/turbo/repo/turbo.json +7 -0
- package/examples/toolchains/turbo/task.json +25 -0
- package/examples/turbo-starter/README.md +16 -0
- package/examples/turbo-starter/changes/issued-at-consumer-only.patch +12 -0
- package/examples/turbo-starter/changes/issued-at.patch +130 -0
- package/examples/turbo-starter/cleanup.mjs +58 -0
- package/examples/turbo-starter/graph.json +32 -0
- package/examples/turbo-starter/harness/acceptance/db-isolation.test.mjs +97 -0
- package/examples/turbo-starter/harness/acceptance/env-probe.test.mjs +75 -0
- package/examples/turbo-starter/harness/acceptance/generation.test.mjs +54 -0
- package/examples/turbo-starter/harness/acceptance/issued-at.test.mjs +43 -0
- package/examples/turbo-starter/harness/acceptance/lifecycle-probe.test.mjs +47 -0
- package/examples/turbo-starter/harness/compose-bridge.mjs +593 -0
- package/examples/turbo-starter/harness/compose.acceptance.yml +23 -0
- package/examples/turbo-starter/harness/env/backend.env.template +7 -0
- package/examples/turbo-starter/harness/env/compose.env.template +6 -0
- package/examples/turbo-starter/policy.json +109 -0
- package/examples/turbo-starter/policy.lifecycle.json +114 -0
- package/examples/turbo-starter/setup.mjs +352 -0
- package/lib/agents/cli-adapter.js +10 -1
- package/lib/agents/inspect.d.ts +56 -2
- package/lib/agents/inspect.js +264 -14
- package/lib/agents/review-probe.d.ts +229 -7
- package/lib/agents/review-probe.js +830 -72
- package/lib/agents/schemas.d.ts +3 -1
- package/lib/agents/schemas.js +7 -3
- package/lib/cli.js +167 -7
- package/lib/contracts/cli.d.ts +820 -11
- package/lib/contracts/cli.js +243 -4
- package/lib/contracts/errors.d.ts +3 -1
- package/lib/contracts/errors.js +2 -0
- package/lib/contracts/events.d.ts +37 -5
- package/lib/contracts/events.js +9 -0
- package/lib/contracts/execution.d.ts +389 -15
- package/lib/contracts/execution.js +76 -4
- package/lib/contracts/failure.js +5 -0
- package/lib/contracts/index.d.ts +1 -0
- package/lib/contracts/index.js +1 -0
- package/lib/contracts/policy.d.ts +15 -0
- package/lib/contracts/policy.js +10 -0
- package/lib/contracts/ports.d.ts +50 -0
- package/lib/contracts/profiles.d.ts +14 -0
- package/lib/contracts/profiles.js +4 -0
- package/lib/contracts/published.d.ts +279 -8
- package/lib/contracts/result.d.ts +171 -0
- package/lib/contracts/result.js +39 -1
- package/lib/contracts/review.d.ts +231 -0
- package/lib/contracts/review.js +326 -2
- package/lib/contracts/toolchain.d.ts +96 -0
- package/lib/contracts/toolchain.js +89 -0
- package/lib/control/doctor.d.ts +16 -1
- package/lib/control/doctor.js +45 -3
- package/lib/control/harness.d.ts +52 -6
- package/lib/control/harness.js +28 -1
- package/lib/control/recovery.d.ts +3 -1
- package/lib/control/review.js +23 -11
- package/lib/engine/budget.d.ts +3 -3
- package/lib/engine/classify.js +1 -0
- package/lib/engine/engine.d.ts +67 -17
- package/lib/engine/prompt.d.ts +29 -1
- package/lib/engine/prompt.js +57 -0
- package/lib/engine/property-recovery.js +2 -0
- package/lib/engine/result.js +52 -0
- package/lib/engine/reuse.js +6 -1
- package/lib/engine/runner.d.ts +25 -0
- package/lib/engine/runner.js +500 -123
- package/lib/environment/lifecycle.js +6 -0
- package/lib/environment/live-calls.js +3 -2
- package/lib/environment/os-tools.d.ts +16 -0
- package/lib/environment/os-tools.js +35 -0
- package/lib/environment/process.d.ts +8 -0
- package/lib/environment/process.js +13 -6
- package/lib/integrations/connector/commands.d.ts +358 -0
- package/lib/integrations/connector/commands.js +428 -0
- package/lib/integrations/connector/config.d.ts +215 -0
- package/lib/integrations/connector/config.js +214 -0
- package/lib/integrations/connector/delivery.d.ts +107 -0
- package/lib/integrations/connector/delivery.js +591 -0
- package/lib/integrations/connector/fake.d.ts +291 -0
- package/lib/integrations/connector/fake.js +786 -0
- package/lib/integrations/connector/history.d.ts +124 -0
- package/lib/integrations/connector/history.js +497 -0
- package/lib/integrations/connector/index.d.ts +16 -0
- package/lib/integrations/connector/index.js +16 -0
- package/lib/integrations/connector/redact.d.ts +19 -0
- package/lib/integrations/connector/redact.js +91 -0
- package/lib/integrations/connector/registry.d.ts +15 -0
- package/lib/integrations/connector/registry.js +43 -0
- package/lib/integrations/connector/snapshot.d.ts +131 -0
- package/lib/integrations/connector/snapshot.js +422 -0
- package/lib/integrations/connector/source.d.ts +37 -0
- package/lib/integrations/connector/source.js +73 -0
- package/lib/integrations/connector/steps.d.ts +71 -0
- package/lib/integrations/connector/steps.js +188 -0
- package/lib/integrations/connector/store.d.ts +140 -0
- package/lib/integrations/connector/store.js +277 -0
- package/lib/integrations/connector/summary.d.ts +38 -0
- package/lib/integrations/connector/summary.js +59 -0
- package/lib/integrations/connector/testing-worker.d.ts +1 -0
- package/lib/integrations/connector/testing-worker.js +81 -0
- package/lib/integrations/connector/testing.d.ts +205 -0
- package/lib/integrations/connector/testing.js +1615 -0
- package/lib/integrations/connector/transport.d.ts +240 -0
- package/lib/integrations/connector/transport.js +28 -0
- package/lib/integrations/memory/context.d.ts +120 -0
- package/lib/integrations/memory/context.js +239 -0
- package/lib/integrations/memory/index.d.ts +8 -0
- package/lib/integrations/memory/index.js +8 -0
- package/lib/integrations/memory/provider.d.ts +79 -0
- package/lib/integrations/memory/provider.js +22 -0
- package/lib/integrations/memory/sink.d.ts +56 -0
- package/lib/integrations/memory/sink.js +116 -0
- package/lib/integrations/memory/testing.d.ts +44 -0
- package/lib/integrations/memory/testing.js +61 -0
- package/lib/integrations/relay-v1/index.d.ts +122 -0
- package/lib/integrations/relay-v1/index.js +860 -0
- package/lib/integrations/relay-v2/index.d.ts +145 -0
- package/lib/integrations/relay-v2/index.js +752 -0
- package/lib/integrations/relay-v2/process.d.ts +32 -0
- package/lib/integrations/relay-v2/process.js +112 -0
- package/lib/integrations/relay-v2/protocol.d.ts +172 -0
- package/lib/integrations/relay-v2/protocol.js +142 -0
- package/lib/profiles/resolve.d.ts +5 -1
- package/lib/profiles/resolve.js +31 -0
- package/lib/storage/document.d.ts +116 -16
- package/lib/toolchains/index.d.ts +9 -0
- package/lib/toolchains/index.js +9 -0
- package/lib/toolchains/inspect.d.ts +105 -0
- package/lib/toolchains/inspect.js +831 -0
- package/lib/toolchains/manifests.d.ts +67 -0
- package/lib/toolchains/manifests.js +238 -0
- package/lib/toolchains/probe.d.ts +28 -0
- package/lib/toolchains/probe.js +54 -0
- package/lib/toolchains/recipes.d.ts +33 -0
- package/lib/toolchains/recipes.js +51 -0
- package/lib/verification/acceptance.d.ts +16 -0
- package/lib/verification/acceptance.js +16 -0
- package/lib/verification/gates.d.ts +38 -0
- package/lib/verification/gates.js +108 -26
- package/package.json +22 -1
- package/profiles/go-gotestsum.json +21 -0
- package/profiles/npm-ci.json +22 -0
- package/profiles/pnpm-frozen.json +24 -0
- package/profiles/python-uv.json +26 -0
- package/schemas/execution-document.schema.json +345 -4
- package/schemas/execution-policy.schema.json +48 -0
- package/schemas/result-envelope.schema.json +213 -1
- package/schemas/run-event.schema.json +93 -0
- package/schemas/run-result.schema.json +207 -0
- package/schemas/stack-profile.schema.json +43 -0
- package/templates/controller-mode/AGENTS.controller.md +58 -0
- package/templates/controller-mode/README.md +44 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { redactor, type Redactor } from '../../environment/redaction.ts';
|
|
2
|
+
import { type RelayTransport } from './transport.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Маскирование известных секретов в диагностике коннектора.
|
|
5
|
+
*
|
|
6
|
+
* Ошибка транспорта (HTTP body, stderr CLI) может дословно содержать значение
|
|
7
|
+
* секрета. Обёртка маскирует сообщение каждой ошибки транспорта до того, как
|
|
8
|
+
* она попадёт в отчёт `source-check`, `source-status`, сохранённые причины
|
|
9
|
+
* шагов/операций, `lastError` доставки или вывод CLI. Данные успешных ответов
|
|
10
|
+
* не меняются: это содержимое задач, которое закрепляется по digest.
|
|
11
|
+
*/
|
|
12
|
+
/** Значения секретов: `secrets`-карты политики (на любом уровне) из окружения controller. */
|
|
13
|
+
export declare function policySecrets(policy: unknown, env?: NodeJS.ProcessEnv): string[];
|
|
14
|
+
/** Значения настроек provider, по имени похожие на секрет (например, `relay.env.RELAY_TOKEN`). */
|
|
15
|
+
export declare function settingsSecrets(settings: unknown): string[];
|
|
16
|
+
export declare function maskError(error: unknown, redact: Redactor): unknown;
|
|
17
|
+
/** Транспорт, ошибки которого замаскированы `redact`. Повторная обёртка не создаётся. */
|
|
18
|
+
export declare function redactingTransport(inner: RelayTransport, redact: Redactor): RelayTransport;
|
|
19
|
+
export { redactor };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { HarnessError } from "../../contracts/index.js";
|
|
2
|
+
import { redactor } from "../../environment/redaction.js";
|
|
3
|
+
import { TransportError } from "./transport.js";
|
|
4
|
+
/**
|
|
5
|
+
* Маскирование известных секретов в диагностике коннектора.
|
|
6
|
+
*
|
|
7
|
+
* Ошибка транспорта (HTTP body, stderr CLI) может дословно содержать значение
|
|
8
|
+
* секрета. Обёртка маскирует сообщение каждой ошибки транспорта до того, как
|
|
9
|
+
* она попадёт в отчёт `source-check`, `source-status`, сохранённые причины
|
|
10
|
+
* шагов/операций, `lastError` доставки или вывод CLI. Данные успешных ответов
|
|
11
|
+
* не меняются: это содержимое задач, которое закрепляется по digest.
|
|
12
|
+
*/
|
|
13
|
+
/** Значения секретов: `secrets`-карты политики (на любом уровне) из окружения controller. */
|
|
14
|
+
export function policySecrets(policy, env = process.env) {
|
|
15
|
+
const out = new Set();
|
|
16
|
+
const walk = (value) => {
|
|
17
|
+
if (!value || typeof value !== 'object')
|
|
18
|
+
return;
|
|
19
|
+
if (Array.isArray(value))
|
|
20
|
+
return value.forEach(walk);
|
|
21
|
+
for (const [key, v] of Object.entries(value)) {
|
|
22
|
+
if (key === 'secrets' && v && typeof v === 'object' && !Array.isArray(v))
|
|
23
|
+
for (const name of Object.values(v))
|
|
24
|
+
if (typeof name === 'string' && env[name])
|
|
25
|
+
out.add(env[name]);
|
|
26
|
+
walk(v);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
walk(policy);
|
|
30
|
+
return [...out];
|
|
31
|
+
}
|
|
32
|
+
const SECRET_NAME = /(TOKEN|SECRET|PASSWORD|PASSWD|API_?KEY|CREDENTIAL|AUTH)/i;
|
|
33
|
+
/** Значения настроек provider, по имени похожие на секрет (например, `relay.env.RELAY_TOKEN`). */
|
|
34
|
+
export function settingsSecrets(settings) {
|
|
35
|
+
const out = [];
|
|
36
|
+
const walk = (value) => {
|
|
37
|
+
if (!value || typeof value !== 'object')
|
|
38
|
+
return;
|
|
39
|
+
for (const [key, v] of Object.entries(value)) {
|
|
40
|
+
if (typeof v === 'string' && SECRET_NAME.test(key) && v.length >= 4)
|
|
41
|
+
out.push(v);
|
|
42
|
+
else
|
|
43
|
+
walk(v);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
walk(settings);
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
export function maskError(error, redact) {
|
|
50
|
+
if (error instanceof TransportError)
|
|
51
|
+
return new TransportError(error.kind, error.operation, redact(error.message), error.details);
|
|
52
|
+
if (error instanceof HarnessError)
|
|
53
|
+
return new HarnessError(error.code, redact(error.message), error.issues.map((i) => ({ path: i.path, message: redact(i.message) })));
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
const safe = new Error(redact(error.message));
|
|
56
|
+
safe.name = error.name;
|
|
57
|
+
return safe;
|
|
58
|
+
}
|
|
59
|
+
return typeof error === 'string' ? redact(error) : error;
|
|
60
|
+
}
|
|
61
|
+
const marked = Symbol('redacting-transport');
|
|
62
|
+
/** Транспорт, ошибки которого замаскированы `redact`. Повторная обёртка не создаётся. */
|
|
63
|
+
export function redactingTransport(inner, redact) {
|
|
64
|
+
if (inner[marked] || !redact.secrets?.length)
|
|
65
|
+
return inner;
|
|
66
|
+
const wrapped = new Proxy(inner, {
|
|
67
|
+
get(target, prop, receiver) {
|
|
68
|
+
if (prop === marked)
|
|
69
|
+
return true;
|
|
70
|
+
const value = Reflect.get(target, prop, receiver);
|
|
71
|
+
if (typeof value !== 'function')
|
|
72
|
+
return value;
|
|
73
|
+
return (...args) => {
|
|
74
|
+
let out;
|
|
75
|
+
try {
|
|
76
|
+
out = value.apply(target, args);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw maskError(error, redact);
|
|
80
|
+
}
|
|
81
|
+
return out instanceof Promise
|
|
82
|
+
? out.catch((error) => {
|
|
83
|
+
throw maskError(error, redact);
|
|
84
|
+
})
|
|
85
|
+
: out;
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
return wrapped;
|
|
90
|
+
}
|
|
91
|
+
export { redactor };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type LoadedConfig } from './config.ts';
|
|
2
|
+
import type { RelayTransport } from './transport.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Реестр транспортов по явному provider. Модуль адаптера загружается только
|
|
5
|
+
* для выбранного provider (opt-in): core и файловый сценарий не загружают
|
|
6
|
+
* Relay-адаптеры и не требуют их окружения.
|
|
7
|
+
*
|
|
8
|
+
* Договор адаптера: модуль `src/integrations/<adapter>/index.ts` экспортирует
|
|
9
|
+
* `createTransport(settings, options?)`, где `settings` — объект `relay` из
|
|
10
|
+
* конфигурации коннектора, дополненный `projectId` и `actor` верхнего уровня
|
|
11
|
+
* (и для relay-v2-cli — абсолютными путями `binary`/`config`, разрешёнными от
|
|
12
|
+
* каталога файла конфигурации). Неверные настройки — `INVALID_INPUT`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function settingsFor(loaded: LoadedConfig): Record<string, unknown>;
|
|
15
|
+
export declare function createTransportFor(loaded: LoadedConfig): Promise<RelayTransport>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { HarnessError } from "../../contracts/index.js";
|
|
2
|
+
import { resolveFrom } from "./config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Реестр транспортов по явному provider. Модуль адаптера загружается только
|
|
5
|
+
* для выбранного provider (opt-in): core и файловый сценарий не загружают
|
|
6
|
+
* Relay-адаптеры и не требуют их окружения.
|
|
7
|
+
*
|
|
8
|
+
* Договор адаптера: модуль `src/integrations/<adapter>/index.ts` экспортирует
|
|
9
|
+
* `createTransport(settings, options?)`, где `settings` — объект `relay` из
|
|
10
|
+
* конфигурации коннектора, дополненный `projectId` и `actor` верхнего уровня
|
|
11
|
+
* (и для relay-v2-cli — абсолютными путями `binary`/`config`, разрешёнными от
|
|
12
|
+
* каталога файла конфигурации). Неверные настройки — `INVALID_INPUT`.
|
|
13
|
+
*/
|
|
14
|
+
export function settingsFor(loaded) {
|
|
15
|
+
const { config, baseDir } = loaded;
|
|
16
|
+
const relay = { ...config.relay };
|
|
17
|
+
for (const key of ['projectId', 'actor'])
|
|
18
|
+
if (key in relay && relay[key] !== config[key])
|
|
19
|
+
throw new HarnessError('INVALID_INPUT', `source.relay.${key} не совпадает с ${key} конфигурации коннектора`);
|
|
20
|
+
const settings = {
|
|
21
|
+
...relay,
|
|
22
|
+
projectId: config.projectId,
|
|
23
|
+
actor: config.actor,
|
|
24
|
+
};
|
|
25
|
+
if (config.provider === 'relay-v2-cli') {
|
|
26
|
+
settings.binary = resolveFrom(baseDir, config.relay.binary);
|
|
27
|
+
settings.config = resolveFrom(baseDir, config.relay.config);
|
|
28
|
+
}
|
|
29
|
+
return settings;
|
|
30
|
+
}
|
|
31
|
+
export async function createTransportFor(loaded) {
|
|
32
|
+
const settings = settingsFor(loaded);
|
|
33
|
+
switch (loaded.config.provider) {
|
|
34
|
+
case 'relay-v1-http': {
|
|
35
|
+
const adapter = await import("../relay-v1/index.js");
|
|
36
|
+
return adapter.createTransport(settings);
|
|
37
|
+
}
|
|
38
|
+
case 'relay-v2-cli': {
|
|
39
|
+
const adapter = await import("../relay-v2/index.js");
|
|
40
|
+
return adapter.createTransport(settings);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { HarnessError, type ContextSnapshot, type WorkGraph } from '../../contracts/index.ts';
|
|
2
|
+
import { type ConnectorConfig, type TaskMapping } from './config.ts';
|
|
3
|
+
import type { ReceiptRecord } from './store.ts';
|
|
4
|
+
import { type CriterionRecord, type RelayTransport, type TaskRead, type TransportIdentity } from './transport.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Снимок задач backend: чтение без смешения редакций, semantic digest,
|
|
7
|
+
* WorkGraph, ContextSnapshot и manifest.
|
|
8
|
+
*
|
|
9
|
+
* Semantic digest — то, к чему привязано согласование (`SourceRef.revision`):
|
|
10
|
+
* текст требований, определения критериев (без отметок выполнения),
|
|
11
|
+
* зависимости, подзадачи, значимые документы и digest mapping. Колонка, свой
|
|
12
|
+
* in-progress, комментарии, история и отметки критериев в него не входят:
|
|
13
|
+
* они не меняют постановку. CAS-ревизии, токены согласованности чтения и
|
|
14
|
+
* идентичность сборки backend хранятся только в manifest — не в поле Git SHA
|
|
15
|
+
* и не в графе.
|
|
16
|
+
*/
|
|
17
|
+
export interface SnapshotProblem {
|
|
18
|
+
code: 'TASK_DONE' | 'TASK_CANCELLED' | 'COLUMN_NOT_ELIGIBLE' | 'DEPENDENCY_UNFINISHED' | 'DEPENDENCY_UNPROVEN' | 'LIMIT_EXCEEDED' | 'DOCUMENT_MISSING' | 'MAPPING_INVALID';
|
|
19
|
+
taskId: string;
|
|
20
|
+
key: string;
|
|
21
|
+
message: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DocumentManifest {
|
|
24
|
+
id: string;
|
|
25
|
+
key: string;
|
|
26
|
+
name: string;
|
|
27
|
+
revision: number;
|
|
28
|
+
bytes: number;
|
|
29
|
+
required: boolean;
|
|
30
|
+
included: 'full' | 'truncated' | 'omitted';
|
|
31
|
+
includedBytes: number;
|
|
32
|
+
reason?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface TaskManifest {
|
|
35
|
+
ref: string;
|
|
36
|
+
id: string;
|
|
37
|
+
key: string;
|
|
38
|
+
identity: string;
|
|
39
|
+
orderId: string;
|
|
40
|
+
semanticDigest: string;
|
|
41
|
+
/** CAS-ревизия backend на момент чтения (не Git SHA). */
|
|
42
|
+
casRevision: number;
|
|
43
|
+
column: string;
|
|
44
|
+
consistency: {
|
|
45
|
+
before: string;
|
|
46
|
+
after: string;
|
|
47
|
+
};
|
|
48
|
+
criteria: {
|
|
49
|
+
id: string;
|
|
50
|
+
title: string;
|
|
51
|
+
mapped: boolean;
|
|
52
|
+
completed: boolean;
|
|
53
|
+
}[];
|
|
54
|
+
dependencies: {
|
|
55
|
+
id: string;
|
|
56
|
+
key: string;
|
|
57
|
+
column: string;
|
|
58
|
+
finished: boolean;
|
|
59
|
+
inGraph: boolean;
|
|
60
|
+
}[];
|
|
61
|
+
children: {
|
|
62
|
+
id: string;
|
|
63
|
+
key: string;
|
|
64
|
+
column: string;
|
|
65
|
+
finished: boolean;
|
|
66
|
+
}[];
|
|
67
|
+
documents: DocumentManifest[];
|
|
68
|
+
}
|
|
69
|
+
export interface SnapshotManifest {
|
|
70
|
+
version: 1;
|
|
71
|
+
provider: string;
|
|
72
|
+
projectId: string;
|
|
73
|
+
connector: string;
|
|
74
|
+
build: Record<string, string>;
|
|
75
|
+
capabilities: string[];
|
|
76
|
+
graphId: string;
|
|
77
|
+
graphDigest: string;
|
|
78
|
+
contextDigest: string;
|
|
79
|
+
/** Semantic digest набора задач — `graph.source.revision`. */
|
|
80
|
+
revision: string;
|
|
81
|
+
readAt: string;
|
|
82
|
+
rounds: number;
|
|
83
|
+
limits: ConnectorConfig['limits'];
|
|
84
|
+
tasks: TaskManifest[];
|
|
85
|
+
truncated: string[];
|
|
86
|
+
problems: SnapshotProblem[];
|
|
87
|
+
}
|
|
88
|
+
export interface BuiltSnapshot {
|
|
89
|
+
graph: WorkGraph;
|
|
90
|
+
context: ContextSnapshot;
|
|
91
|
+
manifest: SnapshotManifest;
|
|
92
|
+
revision: string;
|
|
93
|
+
problems: SnapshotProblem[];
|
|
94
|
+
}
|
|
95
|
+
/** Безопасная причина отказа транспорта при чтении: сеть/CLI — не пустой список. */
|
|
96
|
+
export declare function readFailure(error: unknown, what: string): HarnessError;
|
|
97
|
+
/** Проверка подключения: provider и projectId backend обязаны совпасть с настроенными. */
|
|
98
|
+
export declare function checkIdentity(transport: RelayTransport, config: ConnectorConfig, signal?: AbortSignal): Promise<TransportIdentity>;
|
|
99
|
+
/**
|
|
100
|
+
* Полное согласованное чтение набора задач. Раунд — чтение всех задач; у
|
|
101
|
+
* каждой `consistency.before === after`. Снимок принимается, когда два
|
|
102
|
+
* последовательных раунда совпали токенами и содержимым: между ними ничего
|
|
103
|
+
* не менялось, и граф не собирается из разных редакций. Изменения —
|
|
104
|
+
* ограниченный повтор (`rereads`), затем явный отказ. Ошибка чтения —
|
|
105
|
+
* отказ, а не пустой результат.
|
|
106
|
+
*/
|
|
107
|
+
export declare function readStable(transport: RelayTransport, refs: string[], rereads: number, signal?: AbortSignal): Promise<{
|
|
108
|
+
reads: TaskRead[];
|
|
109
|
+
rounds: number;
|
|
110
|
+
}>;
|
|
111
|
+
export declare const matchCriterion: (criteria: CriterionRecord[], m: TaskMapping["criteria"][number]) => CriterionRecord[];
|
|
112
|
+
/** Semantic digest задачи: смысл постановки без операционных полей. */
|
|
113
|
+
export declare function semanticDigest(config: ConnectorConfig, mapping: TaskMapping, read: TaskRead): string;
|
|
114
|
+
/** Прочитанная задача и её доверенные предпосылки → граф, контекст и manifest. */
|
|
115
|
+
export declare function buildSnapshot(input: {
|
|
116
|
+
config: ConnectorConfig;
|
|
117
|
+
identity: TransportIdentity;
|
|
118
|
+
reads: TaskRead[];
|
|
119
|
+
rounds: number;
|
|
120
|
+
/** Доверенный receipt этого коннектора для задачи-зависимости вне графа. */
|
|
121
|
+
receiptOf: (orderId: string) => ReceiptRecord | undefined;
|
|
122
|
+
}): BuiltSnapshot;
|
|
123
|
+
/** Прочитать, собрать и проверить идентичность: общий путь `source-snapshot` и `run --source`. */
|
|
124
|
+
export declare function takeSnapshot(input: {
|
|
125
|
+
config: ConnectorConfig;
|
|
126
|
+
transport: RelayTransport;
|
|
127
|
+
receiptOf: (orderId: string) => ReceiptRecord | undefined;
|
|
128
|
+
signal?: AbortSignal;
|
|
129
|
+
}): Promise<BuiltSnapshot>;
|
|
130
|
+
/** Отказ по eligibility/limits: причина и предел в сообщении, без запуска. */
|
|
131
|
+
export declare function assertEligible(snapshot: BuiltSnapshot): void;
|