carthagent 1.0.7 → 1.1.0-beta.2
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/cloud-onboarding-acceptance.md +65 -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-beta.2.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/cloud/client.mjs +13 -7
- 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 +1188 -0
- package/lib/opencode/cli.mjs +253 -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/providers/names.mjs +1 -1
- package/lib/tui/framing.mjs +1 -80
- package/lib/tui/models.mjs +1 -1
- 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 +65 -36
- 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 +71 -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 +506 -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/cloud-client.test.mjs +2 -2
- 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/experiential-extension.test.mjs +2 -2
- package/tests/experiential.test.mjs +1 -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 +33 -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 +83 -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 +248 -20
- 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/tui.test.mjs +2 -2
- 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 +45 -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 +882 -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 +91 -65
- 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,120 @@
|
|
|
1
|
+
# Projects sidebar source preview
|
|
2
|
+
|
|
3
|
+
This preview runs the redesigned Projects sidebar from OpenCode source plus the
|
|
4
|
+
Carthagent plugin in this checkout. It is a development preview. Nothing here
|
|
5
|
+
builds, publishes, installs, or changes the published `ctg` runtime.
|
|
6
|
+
|
|
7
|
+
## What is pinned where
|
|
8
|
+
|
|
9
|
+
| Purpose | Patch | Recipe | Hash reference |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| Published runtime (preview.13) | `docs/patches/opencode-v2.0.32-session-ui-combined-v5.patch` | `script/ctg/build-owned-runtime.sh`, publish workflow | `CTG_RUNTIME_PATCH_SHA256`, `lib/opencode/runtime-release.json` |
|
|
12
|
+
| Source preview (development) | `docs/patches/opencode-v2.0.32-session-ui-combined-v5.patch` | `script/ctg/prepare-development-runtime.sh` | `CTG_DEVELOPMENT_RUNTIME_PATCH_SHA256` |
|
|
13
|
+
|
|
14
|
+
Both patches apply to clean upstream `https://github.com/anomalyco/opencode` at
|
|
15
|
+
`843a6c514e606b436a7fe713422ace0a93ad3d61`. v5 is a replacement patch: it
|
|
16
|
+
contains everything in v4 plus the sidebar, folder browser and new-session
|
|
17
|
+
setup sources and their tests under `packages/tui/test/sidebar`. Do not apply
|
|
18
|
+
v4 first.
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
1. `npm ci` in this checkout (the plugin runs from `plugins/carthagent`).
|
|
23
|
+
2. Clone upstream into a new directory, check out the pinned commit, and run
|
|
24
|
+
`script/ctg/prepare-development-runtime.sh <checkout>`. The script refuses a
|
|
25
|
+
different commit, a dirty checkout or a patch with the wrong SHA-256, then
|
|
26
|
+
runs `git apply --check` and `git apply`. It does not install or compile.
|
|
27
|
+
3. Run `bun install` with Bun 1.4.2 in the prepared checkout.
|
|
28
|
+
|
|
29
|
+
## Launch
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
script/ctg/source-preview.sh --source DIR --profile DIR --bun PATH [--workspace DIR] [-- ARGS...]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- All three of `--source`, `--profile` and `--bun` are required. Relative
|
|
36
|
+
paths resolve against your current directory, so you can launch from
|
|
37
|
+
anywhere. Paths with spaces work when quoted.
|
|
38
|
+
- The launcher checks that `packages/cli/src/index.ts` and `node_modules`
|
|
39
|
+
exist and that `bun --version` matches the checkout's `packageManager` pin.
|
|
40
|
+
It fails before touching the profile when a prerequisite is missing.
|
|
41
|
+
- It runs Bun with `--no-env-file` from `<source>/packages/cli` (required for
|
|
42
|
+
JSX resolution) under `env -i`. Only these variables reach OpenCode: `HOME`,
|
|
43
|
+
`PATH` (Bun's directory, Node's directory if found, `/usr/bin`, `/bin`),
|
|
44
|
+
`TERM`, `COLORTERM`, `TMPDIR`, the four `XDG_*` directories,
|
|
45
|
+
`OPENCODE_CONFIG_DIR`, `OPENCODE_TEST_HOME`,
|
|
46
|
+
`OPENCODE_DISABLE_PROJECT_CONFIG=1`, `OPENCODE_DISABLE_AUTOUPDATE=1` and
|
|
47
|
+
`BUN_RUNTIME_TRANSPILER_CACHE_PATH=0`. Provider API-key variables are never
|
|
48
|
+
passed through.
|
|
49
|
+
- First launch creates the profile (0700) with `config/opencode/opencode.json`
|
|
50
|
+
(the plugin path), `cli.json` (Carthage theme) and `themes/carthage.json`
|
|
51
|
+
(all 0600). Each file is created only if absent; existing configuration,
|
|
52
|
+
sessions and authentication are left untouched. If an existing
|
|
53
|
+
`opencode.json` does not list the plugin, the launcher prints a warning and
|
|
54
|
+
still leaves the file alone.
|
|
55
|
+
- `--standalone` is always used, so the CLI starts its own private server on
|
|
56
|
+
a loopback ephemeral port (`--port 0`) that exits with the TUI. `--server`
|
|
57
|
+
is rejected. Without `--`, the workspace (default: current directory) is
|
|
58
|
+
opened. With `--`, the remaining arguments run another CLI command in the
|
|
59
|
+
same profile, for example `-- auth login`.
|
|
60
|
+
|
|
61
|
+
## Use
|
|
62
|
+
|
|
63
|
+
- **Folder card** (top of Projects): current folder, abbreviated path (click
|
|
64
|
+
for the full path), Browse, New session and the model action. Narrow layouts
|
|
65
|
+
show compact `⌕` search, `▤` Browse and `◇` model controls.
|
|
66
|
+
- **Browse** (`/browse`, palette “Browse folders”): Filter and Path inputs
|
|
67
|
+
(Tab switches), Up/Down select, Enter opens, Alt+Left/Right/Up for
|
|
68
|
+
Back/Forward/Up, Alt+H for Home, Ctrl+S confirms, Escape cancels.
|
|
69
|
+
- **New session** (`Ctrl+X N`, `/new`, palette “New session” or “New session
|
|
70
|
+
in folder…”, folder card, compact `+`, folder right-click menu): choose the
|
|
71
|
+
folder, then the model. Global entries start at the folder a plain new
|
|
72
|
+
session would use; project entries start at that project's folder. Nothing
|
|
73
|
+
is created until the first message is sent; cancelling leaves the current
|
|
74
|
+
session, draft and model unchanged. The new session keeps the agent you were
|
|
75
|
+
using and, when you keep the same model, its variant (including the default).
|
|
76
|
+
If the chosen agent or model is not available at the folder when you send,
|
|
77
|
+
the send is blocked with your text kept and no session created; pick another
|
|
78
|
+
agent (`Shift+Tab`) or model (`/model`, `Ctrl+X M`) and send again. There is
|
|
79
|
+
no automatic fallback to another model. `/model` also works before a session
|
|
80
|
+
exists. The model step inside setup has no integration shortcut; connect
|
|
81
|
+
integrations from the standalone model picker (`Ctrl+X M`).
|
|
82
|
+
- **Exit**: `/exit` or palette “Exit the app”. The private server exits with
|
|
83
|
+
the TUI.
|
|
84
|
+
- **Resume**: relaunch with the same `--profile` and select the session in
|
|
85
|
+
Projects. Automatic resume is not part of this preview.
|
|
86
|
+
|
|
87
|
+
## Tests
|
|
88
|
+
|
|
89
|
+
Run serially. Close the preview first.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
# Product (from this checkout)
|
|
93
|
+
node --test --test-concurrency=1 tests/source-preview.test.mjs tests/native-ship-plan.test.mjs tests/native-model-command.test.mjs
|
|
94
|
+
npx eslint . && npm run typecheck
|
|
95
|
+
|
|
96
|
+
# Native (from <source>/packages/tui, using the same isolated variables as the launcher)
|
|
97
|
+
bun --no-env-file test --timeout 30000 test/navigation-rail.test.tsx \
|
|
98
|
+
test/component/session-tabs-rail.test.tsx test/context/session-tabs-model.test.ts \
|
|
99
|
+
test/ui/layout.test.ts test/sidebar
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`tests/source-preview.test.mjs` uses a Bun test double and synthetic profiles,
|
|
103
|
+
so it proves argument handling, isolation and config preservation, not a real
|
|
104
|
+
launch. It runs the launcher with `/bin/sh` on Linux and macOS and is skipped
|
|
105
|
+
on native Windows, where the POSIX launcher is not supported.
|
|
106
|
+
|
|
107
|
+
## Limits
|
|
108
|
+
|
|
109
|
+
- Source preview only. No native binary, package or release includes these
|
|
110
|
+
changes, and the published runtime remains v4.
|
|
111
|
+
- The launcher is a POSIX `sh` script for Linux and macOS (GNU and BSD
|
|
112
|
+
utilities). Native Windows is not supported.
|
|
113
|
+
- Real launches were verified on Linux with Bun 1.4.2. No cross-platform
|
|
114
|
+
launch matrix was run.
|
|
115
|
+
- The native type checker (`tsgo`) and native build are not part of this
|
|
116
|
+
workflow; Bun tests compile the changed modules but are not a full static
|
|
117
|
+
type check.
|
|
118
|
+
- Some native tests outside the focused list fail in the same way on the
|
|
119
|
+
pre-change sources (for example missing `ToastProvider` in
|
|
120
|
+
`session-tabs-status` harnesses).
|
package/evaluate.mjs
CHANGED
|
@@ -23,7 +23,33 @@ const { values: args } = parseArgs({ options: {
|
|
|
23
23
|
timeout: { type: 'string', default: '600' }, 'max-turns': { type: 'string', default: '100' }, 'max-cost': { type: 'string', default: '3' },
|
|
24
24
|
python: { type: 'string' }, 'seed-from': { type: 'string' }, 'allow-live': { type: 'boolean', default: false },
|
|
25
25
|
'dry-run': { type: 'boolean', default: false },
|
|
26
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
26
27
|
} });
|
|
28
|
+
if (args.help) {
|
|
29
|
+
console.log(`Usage: ctg eval [options]
|
|
30
|
+
|
|
31
|
+
Opt-in live A/B evaluation of baseline vs custom configurations against a
|
|
32
|
+
scenario manifest under scenarios/<name>/. Live calls spend API credit and
|
|
33
|
+
generated code runs with your permissions, so a run must be explicit.
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
--mode baseline|custom|both What to evaluate (default both)
|
|
37
|
+
--task <name> Scenario short name (default cli)
|
|
38
|
+
--scenario <name> Scenario directory (overrides --task)
|
|
39
|
+
--model <id> Model id
|
|
40
|
+
--provider <name> Provider name; needs <PROVIDER>_API_KEY
|
|
41
|
+
--thinking <level> Thinking level (default medium)
|
|
42
|
+
--timeout <seconds> Per-run timeout, max 3600 (default 600)
|
|
43
|
+
--max-turns <n> Turn budget, max 1000 (default 100)
|
|
44
|
+
--max-cost <usd> Cost budget (default 3)
|
|
45
|
+
--python <path> Python executable for scenarios that need it
|
|
46
|
+
--seed-from <dir> Continue from a previous candidate directory
|
|
47
|
+
--allow-live Confirm live provider calls
|
|
48
|
+
--dry-run Assemble and preview without calling a provider
|
|
49
|
+
--help, -h Show this help
|
|
50
|
+
`);
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
27
53
|
if (!args['allow-live'] && !args['dry-run']) throw Error('Live calls spend API credit and generated code runs with your permissions. Use --allow-live explicitly (or --dry-run to preview the assembled run without calling a provider).');
|
|
28
54
|
if (!['baseline', 'custom', 'both'].includes(args.mode)) throw Error('Use --mode baseline|custom|both');
|
|
29
55
|
for (const key of ['timeout', 'max-turns', 'max-cost']) if (!(Number(args[key]) > 0 && Number.isFinite(Number(args[key])))) throw Error(`Invalid ${key}`);
|
|
@@ -197,7 +223,8 @@ for (const mode of args.mode === 'both' ? ['baseline', 'custom'] : [args.mode])
|
|
|
197
223
|
cwd,
|
|
198
224
|
evidenceSchema: 2,
|
|
199
225
|
runtime: NATIVE_EVALUATION_RUNTIME,
|
|
200
|
-
|
|
226
|
+
compatibilityVersion: result.compatibilityVersion,
|
|
227
|
+
runtimeVersion: result.runtimeVersion,
|
|
201
228
|
exitCode: result.exitCode,
|
|
202
229
|
timedOut: result.timedOut,
|
|
203
230
|
budgetReason: result.budgetReason,
|
package/lib/budget.mjs
CHANGED
|
@@ -22,7 +22,7 @@ export function budgetReason(budget, action, now = Date.now()) {
|
|
|
22
22
|
|
|
23
23
|
export function validateBudgetOptions(opts, { allowWithoutDelivery = false } = {}) {
|
|
24
24
|
const keys = ['maxTools', 'maxSeconds', 'maxRepairs'];
|
|
25
|
-
|
|
25
|
+
if (!allowWithoutDelivery && opts.delivery === false && keys.some(key => opts[key] !== undefined)) {
|
|
26
26
|
throw Error('Budget options require the delivery extension');
|
|
27
27
|
}
|
|
28
28
|
budgetLimits(flag => opts[{ 'delivery-max-tools': 'maxTools', 'delivery-max-seconds': 'maxSeconds', 'delivery-max-repairs': 'maxRepairs' }[flag]]);
|
package/lib/cloud/client.mjs
CHANGED
|
@@ -73,7 +73,7 @@ export class CloudClient {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
async request(path, { method = 'GET', accessToken, body, signal } = {}) {
|
|
76
|
-
if (typeof this.fetch !== 'function') throw new Error('Carthagent
|
|
76
|
+
if (typeof this.fetch !== 'function') throw new Error('Carthagent Cloud requires fetch support.');
|
|
77
77
|
const headers = { accept: 'application/json' };
|
|
78
78
|
if (body !== undefined) headers['content-type'] = 'application/json';
|
|
79
79
|
if (accessToken) headers.authorization = `Bearer ${accessToken}`;
|
|
@@ -128,6 +128,11 @@ export class CloudClient {
|
|
|
128
128
|
return this.request('/v1/billing/checkout', { method: 'POST', accessToken, body: { successUrl, cancelUrl, priceId }, signal });
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/** @param {{ accessToken?: string, plan?: string, signal?: AbortSignal }} [input] */
|
|
132
|
+
quote({ accessToken, plan = 'builder', signal } = {}) {
|
|
133
|
+
return this.request(`/v1/billing/quote?plan=${encodeURIComponent(plan)}`, { accessToken, signal });
|
|
134
|
+
}
|
|
135
|
+
|
|
131
136
|
portal({ accessToken, returnUrl, signal } = {}) {
|
|
132
137
|
return this.request('/v1/billing/portal', { method: 'POST', accessToken, body: { returnUrl }, signal });
|
|
133
138
|
}
|
|
@@ -184,10 +189,10 @@ function formatEpochSeconds(value) {
|
|
|
184
189
|
|
|
185
190
|
export function cloudManagedUsageRecovery(value) {
|
|
186
191
|
const text = String(value?.code || value?.message || value || '');
|
|
187
|
-
if (/daily_limit_reached|managed daily usage limit/i.test(text)) return '
|
|
188
|
-
if (/monthly_allowance_exhausted|managed monthly allowance/i.test(text)) return '
|
|
189
|
-
if (/subscription_inactive|managed subscription is not active/i.test(text)) return '
|
|
190
|
-
if (/insufficient_quota|insufficient.credit|credit (?:is )?exhausted/i.test(text)) return 'Carthagent
|
|
192
|
+
if (/daily_limit_reached|managed daily usage limit/i.test(text)) return 'Cloud daily usage is exhausted. It resets at 00:00 UTC. Use /account for your plan and headroom, /billing portal to manage billing, or /login for your own provider (BYOK). Your task stays in this session.';
|
|
193
|
+
if (/monthly_allowance_exhausted|managed monthly allowance/i.test(text)) return 'Cloud monthly usage is exhausted. Use /account for your renewal date, /billing portal to manage billing, or /login for your own provider (BYOK). To review a different plan use /billing checkout pro or /billing checkout max. After payment use /billing refresh, then explicitly continue this task.';
|
|
194
|
+
if (/subscription_inactive|managed subscription is not active/i.test(text)) return 'Cloud access is awaiting payment or activation. Use /billing refresh to check, /billing portal to manage payment, or /login for your own provider.';
|
|
195
|
+
if (/insufficient_quota|insufficient.credit|credit (?:is )?exhausted/i.test(text)) return 'Carthagent Cloud usage credit is exhausted. Use /billing checkout builder to review your eligible price (new Builder customers: $1 first month, then $10/month), or /login for your own provider. After payment use /billing refresh, then explicitly continue this task.';
|
|
191
196
|
return null;
|
|
192
197
|
}
|
|
193
198
|
|
|
@@ -256,9 +261,10 @@ export function formatCloudAccount(account, { usage } = {}) {
|
|
|
256
261
|
const managed = account?.managedUsage;
|
|
257
262
|
const planName = managed?.planName || 'plan';
|
|
258
263
|
const lines = [
|
|
259
|
-
`Carthagent
|
|
264
|
+
`Carthagent Cloud account ${account?.accountId || 'unknown'}`,
|
|
260
265
|
`Credit: ${formatNanoUsd(account?.balance?.availableNanoUsd)} available`,
|
|
261
|
-
`Plan: ${subscription.status && subscription.status !== 'none' ? `${planName} (${subscription.status})` : '
|
|
266
|
+
`Plan: ${subscription.status && subscription.status !== 'none' ? `${planName} (${subscription.status})` : 'No paid plan'}`,
|
|
267
|
+
...(account?.email ? [`Signed in as: ${account.email}`] : []),
|
|
262
268
|
];
|
|
263
269
|
const subscriptionEnd = formatEpochSeconds(subscription.current_period_end);
|
|
264
270
|
if (subscriptionEnd) lines.push(`Renews/ends: ${subscriptionEnd}`);
|
package/lib/codegraph.mjs
CHANGED
|
@@ -153,7 +153,7 @@ const parsers = new Map(); // lang -> dedicated parser (setLanguage once; concur
|
|
|
153
153
|
async function parserFor(lang) {
|
|
154
154
|
if (!runtimePromise) {
|
|
155
155
|
runtimePromise = (async () => {
|
|
156
|
-
const Parser = require_('web-tree-sitter');
|
|
156
|
+
const Parser = require_('web-tree-sitter-legacy');
|
|
157
157
|
await Parser.init();
|
|
158
158
|
const wasmDir = require_.resolve('tree-sitter-wasms/package.json').replace(/package\.json$/, 'out');
|
|
159
159
|
const languages = new Map();
|
package/lib/delivery-review.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { readFileSync, writeFileSync, mkdirSync, realpathSync, statSync } from 'node:fs';
|
|
3
|
-
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { dirname, join, resolve, relative, isAbsolute, sep } from 'node:path';
|
|
4
4
|
import { fingerprint, runCommand, localPath, pendingRequirements, evidenceExcludedDirectories, evidenceFresh } from './delivery.mjs';
|
|
5
5
|
|
|
6
6
|
// Captures real Git output and new source contents. The receipt binds a
|
|
@@ -13,15 +13,18 @@ export async function captureDeliveryReview(state, cwd, directory, signal) {
|
|
|
13
13
|
text = 'No Git repository available. Manually inspect source files and describe the review scope honestly; no diff comparison was possible.\n';
|
|
14
14
|
} else {
|
|
15
15
|
if (top.timedOut || top.cancelled || top.outputLimit) throw Error('Git repository discovery failed.');
|
|
16
|
-
|
|
16
|
+
const root = realpathSync.native(resolve(top.output.trim()));
|
|
17
|
+
const workspace = realpathSync.native(resolve(cwd));
|
|
18
|
+
const scope = relative(root, workspace);
|
|
19
|
+
if (isAbsolute(scope) || scope === '..' || scope.startsWith(`..${sep}`)) throw Error('Review requires a workspace inside the discovered Git repository.');
|
|
17
20
|
const log = join(directory, `diff-${randomUUID()}.log`);
|
|
18
21
|
const exclusions = evidenceExcludedDirectories.map(name => `:(exclude,glob)**/${name}/**`);
|
|
19
|
-
const diff = await runCommand(['git', 'diff', '--no-ext-diff', '--no-textconv', 'HEAD', '--', '.', ...exclusions], { cwd, signal, timeoutSeconds: 30, logPath: log });
|
|
22
|
+
const diff = await runCommand(['git', 'diff', '--relative', '--no-renames', '--no-ext-diff', '--no-textconv', 'HEAD', '--', '.', ...exclusions], { cwd, signal, timeoutSeconds: 30, logPath: log });
|
|
20
23
|
if (diff.code !== 0 || diff.timedOut || diff.cancelled || diff.outputLimit) throw Error('Cannot capture complete Git diff (requires a committed baseline and bounded output).');
|
|
21
24
|
const untrackedLog = join(directory, `untracked-${randomUUID()}.log`);
|
|
22
|
-
const status = await runCommand(['git', 'ls-files', '-z', '--others', '--exclude-standard', ...evidenceExcludedDirectories.map(name => `--exclude=${name}/`)], { cwd, signal, timeoutSeconds: 10, logPath: untrackedLog });
|
|
25
|
+
const status = await runCommand(['git', 'ls-files', '-z', '--others', '--exclude-standard', ...evidenceExcludedDirectories.map(name => `--exclude=${name}/`), '--', '.'], { cwd, signal, timeoutSeconds: 10, logPath: untrackedLog });
|
|
23
26
|
if (status.code !== 0 || status.cancelled || status.timedOut || status.outputLimit) throw Error('Cannot enumerate untracked files for review.');
|
|
24
|
-
text = `Review scope excludes dependency/cache/output directories: ${evidenceExcludedDirectories.join(', ')}.\n${readFileSync(log, 'utf8')}\nNew source files:\n`;
|
|
27
|
+
text = `Review scope: workspace ${JSON.stringify(scope || '.')} relative to Git root; paths below are workspace-relative.\nReview scope excludes dependency/cache/output directories: ${evidenceExcludedDirectories.join(', ')}.\n${readFileSync(log, 'utf8')}\nNew source files:\n`;
|
|
25
28
|
for (const name of readFileSync(untrackedLog, 'utf8').split('\0').filter(Boolean).sort()) {
|
|
26
29
|
const path = localPath(cwd, name);
|
|
27
30
|
if (statSync(path).size > 1024 * 1024) throw Error(`New file too large for review capture: ${JSON.stringify(name)}. Inspect it separately or narrow the workspace.`);
|
|
@@ -41,13 +44,23 @@ export async function captureDeliveryReview(state, cwd, directory, signal) {
|
|
|
41
44
|
return { ...capture, diff: text.slice(0, 12000), truncated: text.length > 12000, unresolvedFindings: (state.reviewFindings || []).filter(f => !f.resolution), next: 'Read the full capture path if truncated; new text source is included. Inspect binary assets separately. Probe critical component connections and user outcomes, not only individual functions or artifact existence. Record coverage, findings and limitations; earlier findings require explicit resolutions with evidence, never silently move them to limitations.' };
|
|
42
45
|
}
|
|
43
46
|
|
|
47
|
+
/** Models commonly send `assertion` or a string array; both carry the same claim. */
|
|
48
|
+
function coverageAssertions(item) {
|
|
49
|
+
const value = item.assertions ?? item.assertion;
|
|
50
|
+
if (Array.isArray(value)) return value.filter(v => typeof v === 'string' && v.trim()).join('; ');
|
|
51
|
+
return typeof value === 'string' ? value : '';
|
|
52
|
+
}
|
|
53
|
+
|
|
44
54
|
export function recordDeliveryReview(state, cwd, params) {
|
|
45
55
|
const capture = state.reviewCapture;
|
|
46
56
|
const hash = fingerprint(cwd, ['.']);
|
|
47
57
|
if (!capture || capture.id !== params.captureId || capture.runId !== state.runId || capture.revision !== state.revision || capture.fingerprint !== hash) throw Error('Review capture missing or stale. Use delivery_review action=inspect after final source edits.');
|
|
48
58
|
if (pendingRequirements(state, hash).length) throw Error('Run fresh checks for every requirement before recording review.');
|
|
49
59
|
const nonempty = value => typeof value === 'string' && value.trim().length > 0;
|
|
50
|
-
if (!Array.isArray(params.coverage) ||
|
|
60
|
+
if (!Array.isArray(params.coverage) || params.coverage.some(c => !c || typeof c !== 'object')) throw Error('coverage must be an array of {requirement, assertions, status?} objects.');
|
|
61
|
+
params = { ...params, coverage: params.coverage.map(c => ({ ...c, assertions: coverageAssertions(c) })) };
|
|
62
|
+
const uncovered = (state.plan.acceptance || []).filter(a => !params.coverage.some(c => c.requirement === a.requirement && nonempty(c.assertions))).map(a => a.requirement);
|
|
63
|
+
if (uncovered.length) throw Error(`Review coverage must explain concrete assertions for every exact acceptance requirement, including required validators. Missing: ${JSON.stringify(uncovered.slice(0, 10))}${uncovered.length > 10 ? ` (+${uncovered.length - 10} more)` : ''}. Each item: {requirement: <exact acceptance text>, assertions: "<what the checks assert>", status?: "demonstrated"|"unverified"}.`);
|
|
51
64
|
if (params.coverage.some(c => c.status !== undefined && !['demonstrated', 'unverified'].includes(c.status))) throw Error('Coverage status must be demonstrated or unverified.');
|
|
52
65
|
if (!Array.isArray(params.probes) || !params.probes.length || params.probes.some(p => !nonempty(p))) throw Error('Record boundary/metamorphic probes and observed results, not just a generic review claim.');
|
|
53
66
|
if (!Array.isArray(params.findings) || params.findings.some(p => !nonempty(p))) throw Error('findings must be an array; unresolved findings require repairs or a blocked handoff.');
|
package/lib/delivery.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
4
4
|
import { existsSync, lstatSync, readdirSync, readFileSync, mkdirSync, writeFileSync, renameSync, openSync, writeSync, closeSync } from 'node:fs';
|
|
5
5
|
import { resolve, relative, isAbsolute, join, dirname, basename } from 'node:path';
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
|
+
import { withoutRuntimeGithubToken } from './environment.mjs';
|
|
7
8
|
|
|
8
9
|
// Generic dependency/cache/output directories excluded from the source fingerprint.
|
|
9
10
|
// Scenarios or projects can add more via the manifest; these are the common defaults.
|
|
@@ -425,7 +426,7 @@ export function atomicJson(path, data) {
|
|
|
425
426
|
export function killTree(child) {
|
|
426
427
|
if (!child.pid) return;
|
|
427
428
|
if (process.platform === 'win32') {
|
|
428
|
-
const killer = spawn('taskkill.exe', ['/pid', String(child.pid), '/t', '/f'], { windowsHide: true, stdio: 'ignore' });
|
|
429
|
+
const killer = spawn('taskkill.exe', ['/pid', String(child.pid), '/t', '/f'], { windowsHide: true, stdio: 'ignore', env: withoutRuntimeGithubToken() });
|
|
429
430
|
killer.on('error', () => child.kill());
|
|
430
431
|
} else {
|
|
431
432
|
try { process.kill(-child.pid, 'SIGKILL'); } catch { child.kill('SIGKILL'); }
|
|
@@ -443,7 +444,7 @@ export async function runCommand(argv, { cwd, timeoutSeconds = 60, signal, logPa
|
|
|
443
444
|
const started = Date.now();
|
|
444
445
|
return new Promise(resolveResult => {
|
|
445
446
|
let tail = '', written = 0, timedOut = false, cancelled = false, outputLimit = false;
|
|
446
|
-
const child = spawn(argv[0], argv.slice(1), { cwd, shell: false, windowsHide: true, detached: process.platform !== 'win32', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
447
|
+
const child = spawn(argv[0], argv.slice(1), { cwd, env: withoutRuntimeGithubToken(), shell: false, windowsHide: true, detached: process.platform !== 'win32', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
447
448
|
const stop = () => killTree(child);
|
|
448
449
|
const abort = () => { cancelled = true; stop(); };
|
|
449
450
|
const timer = setTimeout(() => { timedOut = true; stop(); }, timeoutSeconds * 1000);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Return a copy of an environment without the optional runtime transport token. */
|
|
2
|
+
export function withoutRuntimeGithubToken(env = process.env) {
|
|
3
|
+
const clean = { ...env };
|
|
4
|
+
for (const key of Object.keys(clean)) {
|
|
5
|
+
if (key.toUpperCase() === 'CTG_RUNTIME_GITHUB_TOKEN') delete clean[key];
|
|
6
|
+
}
|
|
7
|
+
return clean;
|
|
8
|
+
}
|
package/lib/guidance.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { unframe } from '
|
|
4
|
+
import { unframe } from '../plugins/carthagent/src/server/framing.mjs';
|
|
5
5
|
|
|
6
6
|
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
7
|
export const DEFAULT_PROFILE_DIR = join(root, 'guidance', 'profiles');
|