carthagent 1.0.7 → 1.1.0-beta.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 +140 -83
- package/bin/ctg.mjs +14 -732
- package/docs/beta-rewards-e2e-plan.md +48 -0
- package/docs/beta-rewards-e2e-results.md +84 -0
- package/docs/glyph-review/host-chrome-glyph-compatibility-v4.md +83 -0
- package/docs/glyph-review/test-isolation-v1.md +26 -0
- package/docs/glyph-review/typecheck-base.log +1 -0
- package/docs/glyph-review/typecheck-v4.log +1 -0
- package/docs/glyph-review/unicode-inventory-v4.csv +402 -0
- package/docs/help-dispatch-review.md +69 -0
- package/docs/launch-readiness-live-results.md +65 -0
- package/docs/legacy-cli.md +150 -0
- package/docs/live-theme-plugin-api.md +18 -0
- package/docs/native-cli.md +102 -0
- package/docs/native-compatibility.md +16 -0
- package/docs/native-daily-quests.md +132 -0
- package/docs/native-glyph-pty.md +59 -0
- package/docs/native-manual-testing.md +336 -0
- package/docs/native-slash-acceptance-handoff.md +49 -0
- package/docs/native-terminal-paired-failure-2026-10-17.md +40 -0
- package/docs/native-terminal-performance.md +310 -0
- package/docs/native-terminal-semantics-evidence/README.md +25 -0
- package/docs/native-terminal-semantics-evidence/controlled-host-model-selftest.json +16 -0
- package/docs/native-terminal-semantics-evidence/current-acceptance-status.json +59 -0
- package/docs/native-terminal-semantics-evidence/final-binary-focused-85bb44a.json +154 -0
- package/docs/native-terminal-semantics-evidence/final-binary-full-incomplete-85bb44a.json +160 -0
- package/docs/native-terminal-semantics-evidence/final-binary-layout-85bb44a.json +149 -0
- package/docs/native-terminal-semantics-evidence/final-binary-layout-interactive-85bb44a.json +159 -0
- package/docs/native-terminal-semantics-evidence/final-binary-model-picker-escape-unchanged-85bb44a.json +44 -0
- package/docs/native-terminal-semantics-evidence/final-binary-model-picker-exact-identity-85bb44a.json +47 -0
- package/docs/native-terminal-semantics-evidence/final-binary-model-picker-unchanged-model-incomplete-85bb44a.json +58 -0
- package/docs/native-terminal-semantics-evidence/final-binary-model-selftest.json +16 -0
- package/docs/native-terminal-semantics-evidence/final-binary-picker-cancel-incomplete-85bb44a.json +62 -0
- package/docs/native-terminal-semantics-evidence/focused-clipboard-title-stale-binary.json +161 -0
- package/docs/native-terminal-semantics-evidence/layout-stale-binary-observation-not-accepted.json +153 -0
- package/docs/native-terminal-semantics-evidence/picker-latest-incomplete-attempt.json +62 -0
- package/docs/native-terminal-semantics-evidence/picker-previous-probe-pass.json +61 -0
- package/docs/native-terminal-semantics.md +89 -0
- package/docs/native-upgrade.md +175 -0
- package/docs/opencode-composed-source-review.md +89 -0
- package/docs/opencode-migration.md +225 -9
- package/docs/opencode-owned-runtime.md +241 -0
- package/docs/opencode-runtime.md +12 -0
- package/docs/opencode-theme-provider-proof/README.md +55 -0
- package/docs/opencode-theme-provider-proof/live-theme-api-base.patch +122 -0
- package/docs/opencode-theme-provider-proof/plugin-theme-provider.patch +107 -0
- package/docs/opencode-theme-provider-proof/session-ui-base.patch +1217 -0
- package/docs/owned-host-controls-proof.md +39 -0
- package/docs/owned-runtime-release-manifest.md +42 -0
- package/docs/owned-visual-clear-proof.md +40 -0
- package/docs/patches/opencode-v2.0.32-glyph-spinner-test-isolation-v1.patch +50 -0
- package/docs/patches/opencode-v2.0.32-glyphs.patch +3670 -0
- package/docs/patches/opencode-v2.0.32-help-dispatch.patch +156 -0
- package/docs/patches/opencode-v2.0.32-live-theme-api.patch +122 -0
- package/docs/patches/opencode-v2.0.32-session-ui-combined-v1.patch +5272 -0
- package/docs/patches/opencode-v2.0.32-session-ui-combined-v2.patch +6052 -0
- package/docs/patches/opencode-v2.0.32-session-ui-combined-v3.patch +8657 -0
- package/docs/patches/opencode-v2.0.32-session-ui-combined-v4.patch +9928 -0
- package/docs/patches/opencode-v2.0.32-session-ui-combined-v5.patch +13965 -0
- package/docs/patches/opencode-v2.0.32-session-ui.patch +5137 -0
- package/docs/release-notes-beta.1.md +60 -0
- package/docs/release-notes-native-draft.md +73 -0
- package/docs/release-notes-preview.10.md +121 -0
- package/docs/release-notes-preview.11.md +76 -0
- package/docs/release-notes-preview.12.md +55 -0
- package/docs/release-notes-preview.13.md +68 -0
- package/docs/release-notes-preview.9.md +130 -0
- package/docs/source-preview.md +120 -0
- package/evaluate.mjs +28 -1
- package/lib/budget.mjs +1 -1
- package/lib/codegraph.mjs +1 -1
- package/lib/delivery-review.mjs +19 -6
- package/lib/delivery.mjs +3 -2
- package/lib/environment.mjs +8 -0
- package/lib/guidance.mjs +1 -1
- package/lib/opencode/cli-runtime.mjs +1171 -0
- package/lib/opencode/cli.mjs +252 -0
- package/lib/opencode/credentials.mjs +63 -8
- package/lib/opencode/demo.mjs +53 -0
- package/lib/opencode/evaluation-budget-plugin/index.ts +3 -0
- package/lib/opencode/evaluation.mjs +32 -12
- package/lib/opencode/headless.mjs +22 -5
- package/lib/opencode/provider-policy.mjs +23 -0
- package/lib/opencode/review.mjs +37 -16
- package/lib/opencode/runtime-artifact.mjs +335 -0
- package/lib/opencode/runtime-github-transport.mjs +121 -0
- package/lib/opencode/runtime-release.json +36 -0
- package/lib/opencode/runtime.mjs +299 -20
- package/lib/opencode/service.mjs +77 -35
- package/lib/opencode/session-options.mjs +6 -2
- package/lib/opencode/update.mjs +222 -0
- package/lib/opencode/workspace.mjs +1 -1
- package/lib/planning-advice.mjs +2 -2
- package/lib/providers/experiential.mjs +2 -2
- package/lib/tui/framing.mjs +1 -80
- package/lib/update.mjs +10 -1
- package/package.json +33 -7
- package/plugins/carthagent/README.md +23 -0
- package/plugins/carthagent/src/bootstrap.ts +1 -1
- package/plugins/carthagent/src/daily-evidence.mjs +57 -0
- package/plugins/carthagent/src/daily-quests-rpc.ts +50 -0
- package/plugins/carthagent/src/daily-source-rpc.ts +52 -0
- package/plugins/carthagent/src/index.ts +71 -24
- package/plugins/carthagent/src/rpc.ts +51 -6
- package/plugins/carthagent/src/server/codegraph.ts +12 -5
- package/plugins/carthagent/src/server/daily-quests-rpc.ts +277 -0
- package/plugins/carthagent/src/server/daily-source-rpc.ts +243 -0
- package/plugins/carthagent/src/server/delivery.ts +227 -112
- package/plugins/carthagent/src/server/framing.mjs +80 -0
- package/plugins/carthagent/src/server/policy.ts +1 -1
- package/plugins/carthagent/src/server/providers.ts +59 -31
- package/plugins/carthagent/src/server/session-controls.ts +3 -1
- package/plugins/carthagent/src/server/ship-agents.ts +77 -0
- package/plugins/carthagent/src/server/ship-context.mjs +60 -0
- package/plugins/carthagent/src/server/ship-guidance.ts +41 -0
- package/plugins/carthagent/src/server/ship-rpc.ts +69 -0
- package/plugins/carthagent/src/server/voyages-rpc.ts +280 -0
- package/plugins/carthagent/src/testing.ts +5 -0
- package/plugins/carthagent/src/tui.tsx +496 -0
- package/plugins/carthagent/src/ui/client.ts +127 -0
- package/plugins/carthagent/src/ui/commands.ts +70 -0
- package/plugins/carthagent/src/ui/daily-editor-focus.mjs +52 -0
- package/plugins/carthagent/src/ui/daily-editor.mjs +4 -0
- package/plugins/carthagent/src/ui/daily-quests-events.mjs +18 -0
- package/plugins/carthagent/src/ui/daily-quests-state.mjs +218 -0
- package/plugins/carthagent/src/ui/daily-quests.tsx +235 -0
- package/plugins/carthagent/src/ui/host-state.ts +42 -0
- package/plugins/carthagent/src/ui/model-command.ts +32 -0
- package/plugins/carthagent/src/ui/native-navigation.ts +23 -0
- package/plugins/carthagent/src/ui/native-review.d.mts +33 -0
- package/plugins/carthagent/src/ui/native-review.mjs +159 -0
- package/plugins/carthagent/src/ui/resume-session.mjs +34 -0
- package/plugins/carthagent/src/ui/select-mouse.ts +17 -0
- package/plugins/carthagent/src/ui/session-preferences.d.mts +7 -0
- package/plugins/carthagent/src/ui/session-preferences.mjs +14 -0
- package/plugins/carthagent/src/ui/theme-provision.d.mts +3 -0
- package/plugins/carthagent/src/ui/theme-provision.mjs +134 -0
- package/plugins/carthagent/src/ui/voyages-navigation-state.mjs +56 -0
- package/plugins/carthagent/src/ui/voyages-navigation.tsx +131 -0
- package/plugins/carthagent/src/ui/voyages-state.mjs +165 -0
- package/plugins/carthagent/src/ui/voyages.tsx +131 -0
- package/plugins/carthagent/src/ui/workspace-live.ts +61 -0
- package/plugins/carthagent/src/ui/workspace.tsx +379 -0
- package/plugins/carthagent/src/voyages-rpc.ts +64 -0
- package/plugins/carthagent/src/workspace-rpc.ts +36 -0
- package/plugins/carthagent/tests/commands.test.ts +107 -0
- package/plugins/carthagent/tests/session-preferences.test.mjs +41 -0
- package/plugins/carthagent/tests/voyages-navigation.test.tsx +269 -0
- package/plugins/carthagent/themes/carthage.json +67 -0
- package/plugins/carthagent/tui.ts +26 -1
- package/script/ctg/build-owned-runtime.sh +166 -0
- package/tests/budget-engine.test.mjs +4 -3
- package/tests/cli.test.mjs +52 -96
- package/tests/daily-evidence.test.mjs +62 -0
- package/tests/delivery-review.test.mjs +57 -2
- package/tests/delivery.test.mjs +22 -1
- package/tests/fixtures/native-discovery-plugin/server.ts +15 -0
- package/tests/generate-owned-runtime-release.test.mjs +354 -0
- package/tests/installed-runtime-contract.test.mjs +43 -0
- package/tests/native-cli-host-smoke.mjs +457 -0
- package/tests/native-daily-editor-focus.test.mjs +213 -0
- package/tests/native-daily-editor.test.mjs +43 -0
- package/tests/native-daily-quests-layout.test.mjs +55 -0
- package/tests/native-daily-quests-rpc.test.mjs +456 -0
- package/tests/native-daily-quests-ui.test.mjs +778 -0
- package/tests/native-daily-source.test.mjs +525 -0
- package/tests/native-demo-ui.test.mjs +48 -0
- package/tests/native-evaluation-admission.test.mjs +24 -0
- package/tests/native-fixture-browser-cleanup.test.mjs +65 -0
- package/tests/native-fixture-runtime.test.mjs +111 -0
- package/tests/native-fixture-stop-diagnostics.test.mjs +67 -0
- package/tests/native-glyph-pty.test.mjs +107 -0
- package/tests/native-manual-projects.test.mjs +170 -0
- package/tests/native-model-command.test.mjs +67 -0
- package/tests/native-owned-runtime-env.test.mjs +140 -0
- package/tests/native-paired-guards.test.mjs +464 -0
- package/tests/native-provider-policy.test.mjs +31 -0
- package/tests/native-pty-invocation.test.mjs +114 -0
- package/tests/native-pty-runtime.test.mjs +45 -0
- package/tests/native-resume-session.test.mjs +46 -0
- package/tests/native-review-consumer.test.mjs +286 -0
- package/tests/native-runtime-identity.test.mjs +214 -0
- package/tests/native-select-mouse.test.mjs +23 -0
- package/tests/native-ship-guidance.test.mjs +16 -0
- package/tests/native-ship-parity.test.mjs +526 -0
- package/tests/native-ship-plan.test.mjs +85 -0
- package/tests/native-ship-rpc.test.mjs +71 -0
- package/tests/native-ui-commands.test.mjs +6 -0
- package/tests/native-voyages-layout.test.mjs +28 -0
- package/tests/native-voyages-navigation.test.mjs +169 -0
- package/tests/native-voyages-rpc.test.mjs +397 -0
- package/tests/native-voyages-ui.test.mjs +307 -0
- package/tests/opencode-atomic-write.test.mjs +55 -0
- package/tests/opencode-cli.test.mjs +1312 -0
- package/tests/opencode-codegraph-plugin.test.mjs +47 -0
- package/tests/opencode-delivery.test.mjs +16 -0
- package/tests/opencode-providers.test.mjs +245 -18
- package/tests/opencode-runtime.test.mjs +597 -8
- package/tests/opencode-session-controls.test.mjs +15 -0
- package/tests/opencode-ship-rpc.test.mjs +71 -0
- package/tests/opencode-update.test.mjs +475 -0
- package/tests/opencode-workspace.test.mjs +51 -2
- package/tests/owned-runtime-publish-workflow.test.mjs +477 -0
- package/tests/release-workflow.test.mjs +46 -0
- package/tests/runtime-artifact.test.mjs +269 -0
- package/tests/runtime-development-trust.test.mjs +231 -0
- package/tests/runtime-github-transport.test.mjs +132 -0
- package/tests/runtime-token-env.test.mjs +23 -0
- package/tests/server.test.mjs +3 -1
- package/tests/ship-telemetry.test.mjs +1 -1
- package/tests/source-preview.test.mjs +253 -0
- package/tests/test_native_terminal_probe.py +76 -0
- package/tests/test_native_terminal_semantics.py +232 -0
- package/tests/update.test.mjs +42 -5
- package/tests/verify-draft-runtime-gate.test.mjs +280 -0
- package/tests/verify-owned-runtime-release.test.mjs +371 -0
- package/tests/workspace-live.test.mjs +127 -0
- package/tools/benchmark/diagnose-request.mjs +59 -36
- package/tools/benchmark/eval-common.mjs +3 -3
- package/tools/benchmark/evaluators.test.mjs +4 -4
- package/tools/benchmark/guard.test.mjs +35 -2
- package/tools/benchmark/guard.ts +20 -7
- package/tools/benchmark/planning-startup.test.mjs +30 -34
- package/tools/benchmark/runner.mjs +12 -7
- package/tools/benchmark/runner.test.mjs +23 -7
- package/tools/benchmark/upstream-error.test.mjs +16 -2
- package/tools/generate-owned-runtime-release.mjs +217 -0
- package/tools/installed-runtime-contract.mjs +16 -0
- package/tools/manual-runtime-manifest.mjs +39 -0
- package/tools/native-fixture-browser-cleanup.mjs +59 -0
- package/tools/native-fixture-stop-diagnostics.mjs +43 -0
- package/tools/native-fixture.mjs +199 -40
- package/tools/native-glyph-helpers.py +127 -0
- package/tools/native-glyph-pty.py +144 -0
- package/tools/native-manual-projects.mjs +259 -0
- package/tools/native-manual.mjs +338 -0
- package/tools/native-model-picker-acceptance.py +306 -0
- package/tools/native-owned-runtime-env.sh +47 -0
- package/tools/native-paired-guards.mjs +282 -0
- package/tools/native-paired-manifest.mjs +72 -0
- package/tools/native-paired-orchestration.sh +51 -0
- package/tools/native-plugin-readiness.mjs +33 -0
- package/tools/native-plugin-readiness.test.mjs +53 -0
- package/tools/native-pty-invocation.mjs +26 -0
- package/tools/native-pty-runtime.mjs +83 -0
- package/tools/native-pty-smoke.py +147 -24
- package/tools/native-public-repo-shell-result.mjs +13 -0
- package/tools/native-public-repo-shell-result.test.mjs +28 -0
- package/tools/native-runtime-identity.mjs +201 -0
- package/tools/native-slash-acceptance-env.py +38 -0
- package/tools/native-terminal-semantics.py +876 -0
- package/tools/owned-shell-observer/index.ts +16 -0
- package/tools/owned-shell-observer/package.json +1 -0
- package/tools/owned-visual-clear-env.py +48 -0
- package/tools/owned-visual-clear-model.py +21 -0
- package/tools/pinned-owned-runtime-inputs.mjs +46 -0
- package/tools/prepare-native-manual.mjs +122 -0
- package/tools/run-native-terminal-paired.sh +403 -0
- package/tools/runtime-token-env.mjs +8 -0
- package/tools/seed-native-switch-fixture.mjs +79 -0
- package/tools/test-native-controls.mjs +3 -1
- package/tools/test-native-daily-quests.mjs +65 -0
- package/tools/test-native-default-cli.mjs +106 -0
- package/tools/test-native-delivery-host.mjs +102 -20
- package/tools/test-native-evaluation.mjs +7 -3
- package/tools/test-native-glyph-pty.mjs +94 -0
- package/tools/test-native-host.mjs +87 -63
- package/tools/test-native-outcomes.mjs +3 -1
- package/tools/test-native-package.mjs +206 -38
- package/tools/test-native-performance.mjs +26 -0
- package/tools/test-native-product.mjs +90 -0
- package/tools/test-native-pty.mjs +34 -9
- package/tools/test-native-public-repo.mjs +224 -0
- package/tools/test-native-refresh-reentry.mjs +106 -0
- package/tools/test-native-report.mjs +27 -20
- package/tools/test-native-review.mjs +75 -0
- package/tools/test-native-runtime.mjs +120 -0
- package/tools/test-native-ship-models.mjs +176 -0
- package/tools/test-native-ship-walkthrough.mjs +96 -0
- package/tools/test-native-slash-commands.mjs +125 -0
- package/tools/test-native-slash-commands.py +242 -0
- package/tools/test-native-swe-host.mjs +224 -55
- package/tools/test-native-tasks.mjs +77 -0
- package/tools/test-native-terminal-performance.py +887 -0
- package/tools/test-native-terminal-readiness.sh +85 -0
- package/tools/test-native-terminal-semantics-installed.mjs +38 -0
- package/tools/test-native-visual-clear-installed.mjs +48 -0
- package/tools/test-owned-host-controls.mjs +238 -0
- package/tools/test-owned-opencode-runtime.mjs +35 -0
- package/tools/test-owned-visual-clear-env.py +120 -0
- package/tools/test-owned-visual-clear.py +373 -0
- package/tools/verify-draft-runtime-gate.mjs +138 -0
- package/tools/verify-owned-runtime-release.mjs +114 -0
- package/tools/verify-release-version.mjs +21 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { EventEmitter } from 'node:events';
|
|
4
|
+
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import test from 'node:test';
|
|
8
|
+
import {
|
|
9
|
+
loadNativeTestRuntime,
|
|
10
|
+
preflightNativeTestRuntimeArtifact,
|
|
11
|
+
NATIVE_TEST_COMPATIBILITY_VERSION,
|
|
12
|
+
} from '../tools/native-runtime-identity.mjs';
|
|
13
|
+
|
|
14
|
+
const payload = Buffer.from('reviewed fixture executable bytes');
|
|
15
|
+
const digest = createHash('sha256').update(payload).digest('hex');
|
|
16
|
+
const sourceRevision = '843a6c514e606b436a7fe713422ace0a93ad3d61';
|
|
17
|
+
const patchSha256 = 'a'.repeat(64);
|
|
18
|
+
const lockSha256 = 'b'.repeat(64);
|
|
19
|
+
const runtimeVersion = '0.0.0-ctg.2.0.32';
|
|
20
|
+
const platform = process.platform === 'win32' ? `windows-${process.arch}` : `${process.platform}-${process.arch}`;
|
|
21
|
+
|
|
22
|
+
async function fixture(t, overrides = {}) {
|
|
23
|
+
const root = await mkdtemp(join(tmpdir(), 'ctg-native-identity-'));
|
|
24
|
+
t.after(() => rm(root, { recursive: true, force: true }));
|
|
25
|
+
const ownedRoot = join(root, 'owned');
|
|
26
|
+
const executableName = platform.startsWith('windows-') ? 'opencode.exe' : 'opencode';
|
|
27
|
+
const binary = join(ownedRoot, `cli-${platform}`, 'bin', executableName);
|
|
28
|
+
await mkdir(join(ownedRoot, `cli-${platform}`, 'bin'), { recursive: true });
|
|
29
|
+
await writeFile(binary, payload);
|
|
30
|
+
const manifest = {
|
|
31
|
+
owner: 'Carthagent',
|
|
32
|
+
sourceRepository: 'https://github.com/anomalyco/opencode',
|
|
33
|
+
compatibilityVersion: NATIVE_TEST_COMPATIBILITY_VERSION,
|
|
34
|
+
runtimeVersion,
|
|
35
|
+
sourceRevision,
|
|
36
|
+
patchSha256,
|
|
37
|
+
lockSha256,
|
|
38
|
+
channel: `ctg.${NATIVE_TEST_COMPATIBILITY_VERSION}`,
|
|
39
|
+
platform,
|
|
40
|
+
webUI: false,
|
|
41
|
+
...overrides,
|
|
42
|
+
};
|
|
43
|
+
await writeFile(join(ownedRoot, 'ctg-runtime.json'), JSON.stringify(manifest));
|
|
44
|
+
const release = {
|
|
45
|
+
version: 1,
|
|
46
|
+
releaseVersion: '1.2.3',
|
|
47
|
+
compatibilityVersion: NATIVE_TEST_COMPATIBILITY_VERSION,
|
|
48
|
+
runtimeVersion,
|
|
49
|
+
sourceRevision,
|
|
50
|
+
patchSha256,
|
|
51
|
+
lockSha256,
|
|
52
|
+
assets: {
|
|
53
|
+
[platform]: {
|
|
54
|
+
name: `opencode-${platform}.tar.gz`,
|
|
55
|
+
archiveSha256: 'c'.repeat(64),
|
|
56
|
+
executableSha256: digest,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
return { binary, ownedRoot, release };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function versionSpawner(version) {
|
|
64
|
+
return (_binary, args, options) => {
|
|
65
|
+
assert.deepEqual(args, ['--version']);
|
|
66
|
+
assert.equal(options.windowsHide, true);
|
|
67
|
+
const child = new EventEmitter();
|
|
68
|
+
child.stdout = new EventEmitter();
|
|
69
|
+
child.stderr = new EventEmitter();
|
|
70
|
+
queueMicrotask(() => {
|
|
71
|
+
child.stdout.emit('data', `${version}\n`);
|
|
72
|
+
child.emit('close', 0);
|
|
73
|
+
});
|
|
74
|
+
return child;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function versionSpawnerWithEnv(version, observeEnv) {
|
|
79
|
+
return (_binary, args, options) => {
|
|
80
|
+
assert.deepEqual(args, ['--version']);
|
|
81
|
+
assert.equal(options.windowsHide, true);
|
|
82
|
+
observeEnv(options.env);
|
|
83
|
+
const child = new EventEmitter();
|
|
84
|
+
child.stdout = new EventEmitter();
|
|
85
|
+
child.stderr = new EventEmitter();
|
|
86
|
+
queueMicrotask(() => {
|
|
87
|
+
child.stdout.emit('data', `${version}\n`);
|
|
88
|
+
child.emit('close', 0);
|
|
89
|
+
});
|
|
90
|
+
return child;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
test('accepts exactly the upstream compatibility CLI identity', async t => {
|
|
95
|
+
const { binary } = await fixture(t);
|
|
96
|
+
assert.deepEqual(await loadNativeTestRuntime({ binary, spawnImpl: versionSpawner('opencode v2.0.32') }), {
|
|
97
|
+
binary,
|
|
98
|
+
compatibilityVersion: '2.0.32',
|
|
99
|
+
runtimeVersion: '2.0.32',
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('independent native version verification removes only the draft transport credential from child env', async t => {
|
|
104
|
+
const { binary, ownedRoot, release } = await fixture(t);
|
|
105
|
+
let childEnv;
|
|
106
|
+
await loadNativeTestRuntime({
|
|
107
|
+
binary,
|
|
108
|
+
ownedRoot,
|
|
109
|
+
expectedManifest: release,
|
|
110
|
+
env: { PATH: '/fixture/path', LANG: 'C.UTF-8', CTG_RUNTIME_GITHUB_TOKEN: 'fake-runtime-token' },
|
|
111
|
+
spawnImpl: versionSpawnerWithEnv(`opencode v${runtimeVersion}`, env => { childEnv = env; }),
|
|
112
|
+
});
|
|
113
|
+
assert.equal(childEnv.CTG_RUNTIME_GITHUB_TOKEN, undefined);
|
|
114
|
+
assert.equal(childEnv.PATH, '/fixture/path');
|
|
115
|
+
assert.equal(childEnv.LANG, 'C.UTF-8');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('accepts the CTG runtime only with pinned provenance and independently expected hash', async t => {
|
|
119
|
+
const { binary, ownedRoot, release } = await fixture(t);
|
|
120
|
+
const runtime = await loadNativeTestRuntime({
|
|
121
|
+
binary,
|
|
122
|
+
ownedRoot,
|
|
123
|
+
expectedManifest: release,
|
|
124
|
+
spawnImpl: versionSpawner(`opencode v${runtimeVersion}`),
|
|
125
|
+
});
|
|
126
|
+
assert.deepEqual(runtime, {
|
|
127
|
+
binary,
|
|
128
|
+
compatibilityVersion: '2.0.32',
|
|
129
|
+
runtimeVersion,
|
|
130
|
+
binarySha256: digest,
|
|
131
|
+
sourceRevision,
|
|
132
|
+
patchSha256,
|
|
133
|
+
lockSha256,
|
|
134
|
+
platform,
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('uses the explicit developer hash input when no trusted release record is passed', async t => {
|
|
139
|
+
const { binary, ownedRoot, release } = await fixture(t);
|
|
140
|
+
const runtime = await loadNativeTestRuntime({
|
|
141
|
+
binary,
|
|
142
|
+
ownedRoot,
|
|
143
|
+
expectedManifest: release,
|
|
144
|
+
env: { CTG_TEST_RUNTIME_SHA256: digest },
|
|
145
|
+
spawnImpl: versionSpawner(`opencode v${runtimeVersion}`),
|
|
146
|
+
});
|
|
147
|
+
assert.equal(runtime.binarySha256, digest);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('preflights an injected artifact against an explicit trusted manifest before runtime selection', async t => {
|
|
151
|
+
const { ownedRoot, binary, release } = await fixture(t);
|
|
152
|
+
const expectedManifestPath = join(ownedRoot, 'trusted-release.json');
|
|
153
|
+
await writeFile(expectedManifestPath, JSON.stringify(release));
|
|
154
|
+
const result = await preflightNativeTestRuntimeArtifact({
|
|
155
|
+
ownedRoot,
|
|
156
|
+
expectedManifestPath,
|
|
157
|
+
spawnImpl: versionSpawner(`opencode v${runtimeVersion}`),
|
|
158
|
+
});
|
|
159
|
+
assert.equal(result.identity.binary, binary);
|
|
160
|
+
assert.deepEqual(result.expectedManifest, release);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('requires a trusted test manifest before preflighting an injected artifact', async t => {
|
|
164
|
+
const { ownedRoot } = await fixture(t);
|
|
165
|
+
await assert.rejects(preflightNativeTestRuntimeArtifact({ ownedRoot }), /trusted CTG_TEST_RUNTIME_RELEASE_MANIFEST is required/);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('rejects versions that merely contain the compatibility version', async t => {
|
|
169
|
+
const { binary } = await fixture(t);
|
|
170
|
+
await assert.rejects(loadNativeTestRuntime({
|
|
171
|
+
binary,
|
|
172
|
+
spawnImpl: versionSpawner('opencode v9.0.0-ctg.2.0.32'),
|
|
173
|
+
}), /Unsupported native test runtime version/);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('requires trusted release metadata for owned artifacts', async t => {
|
|
177
|
+
const { binary, ownedRoot } = await fixture(t);
|
|
178
|
+
await assert.rejects(loadNativeTestRuntime({ binary, ownedRoot }), /required pinned identity fields/);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('rejects self-declared provenance mismatches against trusted release metadata before execution', async t => {
|
|
182
|
+
const cases = [
|
|
183
|
+
['sourceRevision', 'f'.repeat(40), /sourceRevision mismatch/],
|
|
184
|
+
['patchSha256', 'd'.repeat(64), /patchSha256 mismatch/],
|
|
185
|
+
['lockSha256', 'e'.repeat(64), /lockSha256 mismatch/],
|
|
186
|
+
['compatibilityVersion', '2.0.33', /compatibilityVersion mismatch/],
|
|
187
|
+
['runtimeVersion', '0.0.0-ctg.2.0.33', /runtimeVersion mismatch/],
|
|
188
|
+
];
|
|
189
|
+
for (const [field, value, error] of cases) {
|
|
190
|
+
const { binary, ownedRoot, release } = await fixture(t, { [field]: value });
|
|
191
|
+
let spawned = false;
|
|
192
|
+
await assert.rejects(loadNativeTestRuntime({ binary, ownedRoot, expectedManifest: release, spawnImpl: (...args) => { spawned = true; return versionSpawner(`opencode v${runtimeVersion}`)(...args); } }), error);
|
|
193
|
+
assert.equal(spawned, false, `${field} mismatch must be rejected before executing binary`);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('checks owned executable path and bytes before invoking version command', async t => {
|
|
198
|
+
const { binary, ownedRoot, release } = await fixture(t);
|
|
199
|
+
let spawned = false;
|
|
200
|
+
await assert.rejects(loadNativeTestRuntime({
|
|
201
|
+
binary: join(ownedRoot, '..', 'opencode'),
|
|
202
|
+
ownedRoot,
|
|
203
|
+
expectedManifest: release,
|
|
204
|
+
spawnImpl: () => { spawned = true; throw Error('must not execute'); },
|
|
205
|
+
}), /executable must be/);
|
|
206
|
+
await writeFile(binary, 'tampered executable');
|
|
207
|
+
await assert.rejects(loadNativeTestRuntime({
|
|
208
|
+
binary,
|
|
209
|
+
ownedRoot,
|
|
210
|
+
expectedManifest: release,
|
|
211
|
+
spawnImpl: () => { spawned = true; throw Error('must not execute'); },
|
|
212
|
+
}), /binary SHA-256 mismatch/);
|
|
213
|
+
assert.equal(spawned, false);
|
|
214
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { clickSelect } from '../plugins/carthagent/src/ui/select-mouse.ts';
|
|
4
|
+
|
|
5
|
+
const node = (scrollOffset, linesPerItem) => {
|
|
6
|
+
const calls = [];
|
|
7
|
+
return { calls, scrollOffset, linesPerItem, maxVisibleItems: 3, screenY: 10, options: [{}, {}, {}, {}], setSelectedIndex: i => calls.push(['set', i]), selectCurrent: () => calls.push(['select']) };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
test('clicks activate the row under the pointer, accounting for scroll and row height', () => {
|
|
11
|
+
const n = node(1, 2);
|
|
12
|
+
clickSelect(n, { button: 0, y: 13 });
|
|
13
|
+
assert.deepEqual(n.calls, [['set', 2], ['select']]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('clicks outside rows or with other buttons are ignored', () => {
|
|
17
|
+
for (const event of [{ button: 0, y: 9 }, { button: 0, y: 30 }, { button: 0, y: 13 }, { button: 2, y: 10 }]) {
|
|
18
|
+
const n = node(0, 1);
|
|
19
|
+
clickSelect(n, event);
|
|
20
|
+
assert.deepEqual(n.calls, []);
|
|
21
|
+
}
|
|
22
|
+
clickSelect(undefined, { button: 0, y: 10 });
|
|
23
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createJiti } from 'jiti';
|
|
4
|
+
|
|
5
|
+
const { shipGuidance } = await createJiti(import.meta.url).import('../plugins/carthagent/src/server/ship-guidance.ts');
|
|
6
|
+
|
|
7
|
+
test('both workflows explain gated direct tools independently of code-mode discovery', () => {
|
|
8
|
+
for (const workflow of ['standard', 'strict']) {
|
|
9
|
+
const text = shipGuidance({ workflow, prompt: 'Repair trade validation' });
|
|
10
|
+
assert.match(text, /first create delivery_plan/);
|
|
11
|
+
assert.match(text, /standard mode then unlocks implementation/);
|
|
12
|
+
assert.match(text, /strict mode also requires tested-design approval/);
|
|
13
|
+
assert.match(text, /shell \(not bash\), outside execute/);
|
|
14
|
+
assert.match(text, /never use delivery_check to bootstrap file edits/);
|
|
15
|
+
}
|
|
16
|
+
});
|