@akira-tl/forgerelay 0.8.7 → 0.8.9
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/CHANGELOG.md +18 -0
- package/README.md +10 -18
- package/capabilities/host-integration/GUIDE.md +2 -2
- package/dist/activity/{audit-store.js → history/audit-store.js} +129 -21
- package/dist/activity/history/bash-output-store.js +250 -0
- package/dist/activity/{host-turn-store.js → history/host-turn-store.js} +4 -1
- package/dist/activity/{query-service.js → history/query-service.js} +13 -7
- package/dist/activity/{lifecycle.js → runtime/lifecycle.js} +1 -1
- package/dist/activity/{mcp-query-tools.js → runtime/mcp-query-tools.js} +3 -3
- package/dist/activity/storage/history.js +12 -0
- package/dist/activity/storage/paths.js +56 -0
- package/dist/activity/storage/segmented-log.js +149 -0
- package/dist/cli/setup-support.js +116 -0
- package/dist/cli.js +18 -126
- package/dist/lsp/code-intelligence.js +1 -1
- package/dist/lsp/test-support/server-fixture.js +9 -9
- package/dist/mcp/filesystem/filesystem-tools.js +245 -0
- package/dist/mcp/hooks/command-runner.js +79 -0
- package/dist/{hook-cli.js → mcp/hooks/hook-cli.js} +1 -1
- package/dist/{hooks.js → mcp/hooks/hooks.js} +3 -80
- package/dist/{oauth-provider.js → mcp/oauth/oauth-provider.js} +1 -1
- package/dist/{oauth-store.js → mcp/oauth/oauth-store.js} +5 -4
- package/dist/{operations → mcp/operations}/native-bulk-mutations.js +2 -2
- package/dist/mcp/panel/app.js +143 -0
- package/dist/{mcp-app-template.js → mcp/panel/mcp-app-template.js} +2 -38
- package/dist/mcp/process/runtime.js +257 -0
- package/dist/mcp/process/tools.js +346 -0
- package/dist/mcp/server/core/activity-support.js +70 -0
- package/dist/{capabilities.js → mcp/server/core/capabilities.js} +5 -3
- package/dist/{capability-registry.js → mcp/server/core/capability-registry.js} +2 -2
- package/dist/mcp/server/core/capability-support.js +90 -0
- package/dist/mcp/server/core/schemas.js +216 -0
- package/dist/mcp/server/core/tool-support.js +207 -0
- package/dist/mcp/server/core/version.js +9 -0
- package/dist/mcp/server/operations/runtime/filesystem-tools.js +400 -0
- package/dist/mcp/server/operations/runtime/operation-runtime.js +523 -0
- package/dist/mcp/server/transport/http-server.js +301 -0
- package/dist/mcp/server/transport/http-support.js +43 -0
- package/dist/mcp/server/workspace/runtime/workspace-open-presentation.js +222 -0
- package/dist/mcp/server/workspace/runtime/workspace-open-schema.js +187 -0
- package/dist/mcp/server/workspace/runtime/workspace-open.js +552 -0
- package/dist/mcp/server/workspace/runtime/workspace-tools.js +601 -0
- package/dist/{config.js → runtime/config/config.js} +3 -3
- package/dist/{user-config.js → runtime/config/user-config.js} +14 -54
- package/dist/{db → runtime/state/db}/client.js +1 -1
- package/dist/{db → runtime/state/db}/migrations.js +34 -3
- package/dist/runtime/state/lock/file-lock.js +130 -0
- package/dist/runtime/testing/server-fixture.js +190 -0
- package/dist/server.js +139 -4192
- package/dist/subagents/providers/adapters/claude.js +86 -52
- package/dist/subagents/providers/adapters/codex.js +103 -39
- package/dist/subagents/providers/adapters/opencode.js +114 -84
- package/dist/subagents/providers/adapters/pi.js +59 -8
- package/dist/subagents/providers/availability.js +15 -30
- package/dist/subagents/providers/runtime/external-command.js +56 -0
- package/dist/subagents/sessions/capability.js +1 -1
- package/dist/subagents/sessions/execution.js +1 -1
- package/dist/subagents/sessions/mcp/activity-audit-test-support.js +30 -0
- package/dist/subagents/sessions/store.js +1 -1
- package/dist/ui/.vite/manifest.json +342 -409
- package/dist/ui/activity-panel-app.html +2 -4
- package/dist/ui/assets/activity-panel-app-7Xe0alhm.css +1 -0
- package/dist/ui/assets/activity-panel-app-Sl1Jro8v.js +115 -0
- package/dist/ui/assets/angular-html-B_yn91wW.js +1 -0
- package/dist/ui/assets/{angular-ts-Bxh4-O1-.js → angular-ts-DSgtloKz.js} +1 -1
- package/dist/ui/assets/{apl-BmYHKQ6m.js → apl-NatWtF8X.js} +1 -1
- package/dist/ui/assets/{astro-C51vqDKq.js → astro-BYFEVBuN.js} +1 -1
- package/dist/ui/assets/{blade-CdhVsmwq.js → blade-DoO7yvMR.js} +1 -1
- package/dist/ui/assets/c-Rl2hMCcg.js +1 -0
- package/dist/ui/assets/{cobol-Cf6azoN_.js → cobol-ByC5mWiB.js} +1 -1
- package/dist/ui/assets/{coffee-vVdGzlmt.js → coffee-Dez77Qov.js} +1 -1
- package/dist/ui/assets/cpp-DtaAQT9h.js +1 -0
- package/dist/ui/assets/{crystal-5UZy6KIX.js → crystal-Bgmbf8ec.js} +1 -1
- package/dist/ui/assets/css-C1tjBtVN.js +1 -0
- package/dist/ui/assets/{edge-CESgo4ia.js → edge-DeH6u8Wg.js} +1 -1
- package/dist/ui/assets/{elixir-9FKfw4cJ.js → elixir-_H3KnmWT.js} +1 -1
- package/dist/ui/assets/{elm-Dv7A0aLa.js → elm-CsCe3U28.js} +1 -1
- package/dist/ui/assets/{erb-DHFmDvM0.js → erb-CbM-L2g8.js} +1 -1
- package/dist/ui/assets/{git-rebase-utbU6CzV.js → git-rebase-D0s5pDh9.js} +1 -1
- package/dist/ui/assets/{glimmer-js-t2kiCkyB.js → glimmer-js-BfOToq_A.js} +1 -1
- package/dist/ui/assets/{glimmer-ts-F0Jv5okV.js → glimmer-ts-CCUOkL2K.js} +1 -1
- package/dist/ui/assets/glsl-DH4ec9dE.js +1 -0
- package/dist/ui/assets/graphql-DilAMBoI.js +1 -0
- package/dist/ui/assets/{hack-8yjdbaSA.js → hack-BDkNDZlF.js} +1 -1
- package/dist/ui/assets/haml-D_QBp6K7.js +1 -0
- package/dist/ui/assets/{handlebars-BBFEg4Lo.js → handlebars-DePUrTpC.js} +1 -1
- package/dist/ui/assets/heavy-payload-DOwZpO6n.js +290 -0
- package/dist/ui/assets/html-By4dNnM4.js +1 -0
- package/dist/ui/assets/{html-derivative-DJAQcZyc.js → html-derivative-DDw9Ef4Q.js} +1 -1
- package/dist/ui/assets/{http-Dg5LSYRK.js → http-B0QxWc9M.js} +1 -1
- package/dist/ui/assets/{hurl-Y5uYzMZR.js → hurl-vMQ4lda1.js} +1 -1
- package/dist/ui/assets/java-DYRe2lWG.js +1 -0
- package/dist/ui/assets/javascript-CxyGqwcL.js +1 -0
- package/dist/ui/assets/{jinja-Bt30h8Ik.js → jinja-JUwV-fZt.js} +1 -1
- package/dist/ui/assets/{jison-D5uZ1Nyo.js → jison-7ZqCEvS8.js} +1 -1
- package/dist/ui/assets/json-dbltgiiA.js +1 -0
- package/dist/ui/assets/jsx-oDopT7YQ.js +1 -0
- package/dist/ui/assets/{julia-76hRaaGz.js → julia-CkKiNSav.js} +1 -1
- package/dist/ui/assets/{just-CDE7W0vW.js → just-DuqCAKJ3.js} +1 -1
- package/dist/ui/assets/{latex-CVO2Byab.js → latex-sudcRDSn.js} +1 -1
- package/dist/ui/assets/{liquid-CA-AS3EX.js → liquid-Di-08Js7.js} +1 -1
- package/dist/ui/assets/lua-YlqdMoV0.js +1 -0
- package/dist/ui/assets/{marko-_BWrPfny.js → marko-CJRNyJDb.js} +1 -1
- package/dist/ui/assets/{mdc-PyJv85eS.js → mdc-t12CzZHs.js} +1 -1
- package/dist/ui/assets/{nginx-DAWVw8yu.js → nginx-57-b4XwT.js} +1 -1
- package/dist/ui/assets/{nim-CKE1dzpU.js → nim-BzrswYQa.js} +1 -1
- package/dist/ui/assets/{perl-BBhWva19.js → perl-D9JR_iIh.js} +1 -1
- package/dist/ui/assets/{php-ChIeaAoF.js → php-Py2gFHil.js} +1 -1
- package/dist/ui/assets/{pug-CMgI5afi.js → pug-PzLLy0h1.js} +1 -1
- package/dist/ui/assets/{qml-CjxTkcFH.js → qml-By8fwgV4.js} +1 -1
- package/dist/ui/assets/r-CcezTbLq.js +1 -0
- package/dist/ui/assets/{razor-i4DbHr8p.js → razor-dG-vdhL_.js} +1 -1
- package/dist/ui/assets/regexp-BlsQ-N_8.js +1 -0
- package/dist/ui/assets/{rst-oy_97Kl4.js → rst-C2awDCat.js} +1 -1
- package/dist/ui/assets/{ruby-C5zYZIyl.js → ruby-zA2W_49d.js} +1 -1
- package/dist/ui/assets/{sas-BnMEh2S3.js → sas-D49bhyaN.js} +1 -1
- package/dist/ui/assets/scss-BQb-cp01.js +1 -0
- package/dist/ui/assets/shellscript-Dga4H_Ni.js +1 -0
- package/dist/ui/assets/{shellsession-BpE5o7_3.js → shellsession-n3-5CqcF.js} +1 -1
- package/dist/ui/assets/{soy-COesmhTY.js → soy-XYBOf_BA.js} +1 -1
- package/dist/ui/assets/sql-ET4u5Cpl.js +1 -0
- package/dist/ui/assets/{stata-CGQEuSZq.js → stata-CLHcJHO_.js} +1 -1
- package/dist/ui/assets/{surrealql-Bz4JbU-9.js → surrealql-BdjQ60T4.js} +1 -1
- package/dist/ui/assets/{svelte-1jM2ejXj.js → svelte-B2RPtKJe.js} +1 -1
- package/dist/ui/assets/{templ-C-VwELcp.js → templ-CrByPW_W.js} +1 -1
- package/dist/ui/assets/{tex-t1rUiQCm.js → tex-DZBkg363.js} +1 -1
- package/dist/ui/assets/{ts-tags-Bewoa6pS.js → ts-tags-DJR3Gphb.js} +1 -1
- package/dist/ui/assets/tsx-CajzROyy.js +1 -0
- package/dist/ui/assets/{twig-DVg-vELl.js → twig-BZjk5Zda.js} +1 -1
- package/dist/ui/assets/typescript-B-EWToLj.js +1 -0
- package/dist/ui/assets/{vue-wPQ7UlMy.js → vue-D_rHCCr8.js} +1 -1
- package/dist/ui/assets/{vue-html-BHtJ8geX.js → vue-html-CC4WlvVt.js} +1 -1
- package/dist/ui/assets/{vue-vine-CNSGAWwc.js → vue-vine-BgNMVgpk.js} +1 -1
- package/dist/ui/assets/xml-BI86-WbH.js +1 -0
- package/dist/ui/assets/{xsl-3_vJ27aE.js → xsl-DXeLZV4J.js} +1 -1
- package/dist/ui/assets/yaml-60_PFlWa.js +1 -0
- package/dist/workspaces/bootstrap.js +72 -0
- package/dist/workspaces/context.js +302 -0
- package/dist/workspaces/conversation-test-support.js +86 -0
- package/dist/{git-worktrees.js → workspaces/git/git-worktrees.js} +1 -1
- package/dist/workspaces/inventory.js +131 -0
- package/dist/workspaces/paths.js +55 -0
- package/dist/{remote-auth.js → workspaces/relay/auth/remote-auth.js} +2 -2
- package/dist/workspaces/relay/result-support.js +111 -0
- package/dist/workspaces/relay/tests/test-support.js +203 -0
- package/dist/{remote-mcp-connection-pool.js → workspaces/relay/transport/remote-mcp-connection-pool.js} +1 -1
- package/dist/workspaces/relay/types.js +1 -0
- package/dist/{remote-workspace-relay.js → workspaces/relay/workspace-relay.js} +23 -172
- package/dist/workspaces/resources/skills.js +285 -0
- package/dist/{review-checkpoints.js → workspaces/review/review-checkpoints.js} +2 -2
- package/dist/workspaces/sessions.js +457 -0
- package/dist/{workspace-store.js → workspaces/state/workspace-store.js} +2 -2
- package/dist/workspaces.js +69 -991
- package/docs/chatgpt-coding-workflow.md +3 -11
- package/docs/configuration.md +12 -25
- package/docs/gotchas.md +0 -30
- package/docs/roadmap.md +6 -10
- package/docs/security.md +1 -5
- package/docs/setup.md +0 -11
- package/package.json +6 -8
- package/scripts/ci/architecture.mjs +109 -0
- package/scripts/ci/verify.mjs +5 -0
- package/scripts/debug/accept/bootstrap.mjs +326 -0
- package/scripts/debug/accept/harness.mjs +76 -0
- package/scripts/debug/accept/support.mjs +432 -0
- package/scripts/debug/accept.mjs +43 -806
- package/scripts/debug/relay-accept/support.mjs +135 -0
- package/scripts/debug/relay-accept.mjs +26 -115
- package/scripts/debug/traffic/support.mjs +167 -0
- package/scripts/debug/traffic/traffic-audit.mjs +4 -161
- package/scripts/{lsp-interop-support.test.mjs → lsp/interop-support.test.mjs} +1 -1
- package/scripts/{lsp-interop.mjs → lsp/interop.mjs} +3 -3
- package/scripts/wiki/sync.mjs +21 -10
- package/dist/activity/bash-output-store.js +0 -127
- package/dist/pi-tools.js +0 -110
- package/dist/skills.js +0 -127
- package/dist/ui/assets/activity-panel-app-CUAN6zyW.js +0 -2
- package/dist/ui/assets/angular-html-BkgDQl-G.js +0 -1
- package/dist/ui/assets/c-IBzBpxAO.js +0 -1
- package/dist/ui/assets/chunk-EyZ2wyi3.js +0 -1
- package/dist/ui/assets/cpp-CVHeO-Jk.js +0 -1
- package/dist/ui/assets/css-DEfus9J5.js +0 -1
- package/dist/ui/assets/glsl-_ooCjaeB.js +0 -1
- package/dist/ui/assets/graphql-B9LqP-cY.js +0 -1
- package/dist/ui/assets/haml-BU5EoZBn.js +0 -1
- package/dist/ui/assets/heavy-payload-CgzrutLm.js +0 -4
- package/dist/ui/assets/html-D-C6YZk4.js +0 -1
- package/dist/ui/assets/java-ppHvycj5.js +0 -1
- package/dist/ui/assets/javascript-DDTjKLlQ.js +0 -1
- package/dist/ui/assets/json-Cw91r8h1.js +0 -1
- package/dist/ui/assets/jsx-04X2FT_1.js +0 -1
- package/dist/ui/assets/lua-CiyBp52Y.js +0 -1
- package/dist/ui/assets/r-DfFga4si.js +0 -1
- package/dist/ui/assets/regexp-iC9_nbSI.js +0 -1
- package/dist/ui/assets/review-payload-BrLbezbq.js +0 -1
- package/dist/ui/assets/scrollbar-CbhpdW05.js +0 -287
- package/dist/ui/assets/scss-BfZXsAWQ.js +0 -1
- package/dist/ui/assets/shellscript-BC2srNaB.js +0 -1
- package/dist/ui/assets/sql-Ccv_yeUm.js +0 -1
- package/dist/ui/assets/tsx-CTXzrBkN.js +0 -1
- package/dist/ui/assets/typescript--ElHoFkw.js +0 -1
- package/dist/ui/assets/workspace-app-Bhj96tsR.js +0 -1
- package/dist/ui/assets/workspace-app-CxwJuZyS.js +0 -111
- package/dist/ui/assets/workspace-app-D6UR0AFl.js +0 -5
- package/dist/ui/assets/workspace-app-ldjBmCJR.css +0 -1
- package/dist/ui/assets/workspace-lifecycle-app-Cqfhx9pV.js +0 -1
- package/dist/ui/assets/xml-JnmX6vyS.js +0 -1
- package/dist/ui/assets/yaml-OAcZkP-w.js +0 -1
- package/dist/ui/workspace-app.html +0 -18
- package/dist/ui/workspace-lifecycle-app.html +0 -18
- package/docs/agent-profile-schema.md +0 -114
- package/docs/artifact-exchange.md +0 -65
- package/docs/versioning.md +0 -205
- /package/capabilities/{managed-worktrees → workspace/managed-worktrees}/GUIDE.md +0 -0
- /package/capabilities/{workspace-tasks → workspace/workspace-tasks}/GUIDE.md +0 -0
- /package/dist/activity/{process-output-audit.js → runtime/process-output-audit.js} +0 -0
- /package/dist/{artifact-error.js → mcp/artifacts/artifact-error.js} +0 -0
- /package/dist/{artifact-tools.js → mcp/artifacts/artifact-tools.js} +0 -0
- /package/dist/{incoming-artifacts.js → mcp/artifacts/incoming-artifacts.js} +0 -0
- /package/dist/{advertised-files.js → mcp/filesystem/advertised-files.js} +0 -0
- /package/dist/{apply-patch.js → mcp/filesystem/apply-patch.js} +0 -0
- /package/dist/{file-mutations.js → mcp/filesystem/file-mutations.js} +0 -0
- /package/dist/{roots.js → mcp/filesystem/roots.js} +0 -0
- /package/dist/{oauth → mcp/oauth}/public-url.js +0 -0
- /package/dist/{oauth → mcp/oauth}/router.js +0 -0
- /package/dist/{operations → mcp/operations}/batch/executor.js +0 -0
- /package/dist/{operations → mcp/operations}/batch/scheduler.js +0 -0
- /package/dist/{operations → mcp/operations}/batch/types.js +0 -0
- /package/dist/{operations → mcp/operations}/bulk-mutation.js +0 -0
- /package/dist/{operations → mcp/operations}/bulk-read.js +0 -0
- /package/dist/{operations → mcp/operations}/core-operation-executor.js +0 -0
- /package/dist/{process-platform.js → mcp/process/process-platform.js} +0 -0
- /package/dist/{process-sessions.js → mcp/process/process-sessions.js} +0 -0
- /package/dist/{request-meta.js → mcp/request-meta.js} +0 -0
- /package/dist/{mcp-sessions.js → mcp/server/transport/mcp-sessions.js} +0 -0
- /package/dist/{server-shutdown.js → mcp/server/transport/server-shutdown.js} +0 -0
- /package/dist/{logger.js → runtime/logging/logger.js} +0 -0
- /package/dist/{db → runtime/state/db}/schema.js +0 -0
- /package/dist/{composite-activity.js → workspaces/composite/composite-activity.js} +0 -0
- /package/dist/{composite-workspaces.js → workspaces/composite/composite-workspaces.js} +0 -0
- /package/dist/{git.js → workspaces/git/git.js} +0 -0
- /package/dist/{workspace-presentation.js → workspaces/presentation/workspace-presentation.js} +0 -0
- /package/dist/{remote-transport.js → workspaces/relay/transport/remote-transport.js} +0 -0
- /package/dist/{workspace-task-reminders.js → workspaces/tasks/workspace-task-reminders.js} +0 -0
- /package/dist/{workspace-tasks.js → workspaces/tasks/workspace-tasks.js} +0 -0
- /package/scripts/{lsp-interop-support.mjs → lsp/interop-support.mjs} +0 -0
|
@@ -164,9 +164,6 @@ same safe finalize/integrate/cleanup lifecycle before ForgeRelay deletes its ide
|
|
|
164
164
|
For an already-closed managed-worktree Workspace, delete removes only ForgeRelay-owned
|
|
165
165
|
state and does not recreate the physical backing.
|
|
166
166
|
|
|
167
|
-
Legacy `devspace/*` managed branches remain closable when they are already stored
|
|
168
|
-
in workspace metadata; only new managed branches use `forgerelay/*`.
|
|
169
|
-
|
|
170
167
|
## Instructions
|
|
171
168
|
|
|
172
169
|
When a workspace opens, ForgeRelay first loads exactly one global system-instructions
|
|
@@ -253,8 +250,6 @@ global config directory plus:
|
|
|
253
250
|
.forgerelay/agents/*.md
|
|
254
251
|
```
|
|
255
252
|
|
|
256
|
-
Rename-era `.devspace/agents` discovery has ended.
|
|
257
|
-
|
|
258
253
|
The workspace result exposes only compact profile metadata so the host can
|
|
259
254
|
choose a provider/profile without loading full provider launch details. Read the
|
|
260
255
|
ForgeRelay-owned `subagents` capability guide when delegation is actually needed;
|
|
@@ -350,10 +345,7 @@ and keeps widget usage focused on workspace/change review.
|
|
|
350
345
|
|
|
351
346
|
`FORGERELAY_WIDGETS=off` disables widget UI.
|
|
352
347
|
|
|
353
|
-
##
|
|
348
|
+
## Configuration
|
|
354
349
|
|
|
355
|
-
`FORGERELAY_*` is the canonical environment-variable prefix.
|
|
356
|
-
|
|
357
|
-
older installations explicitly; persisted internal identifiers that would
|
|
358
|
-
otherwise orphan state remain compatible. See
|
|
359
|
-
[Configuration Reference](configuration.md) for the current rules.
|
|
350
|
+
`FORGERELAY_*` is the canonical environment-variable prefix. See
|
|
351
|
+
[Configuration Reference](configuration.md) for the current settings.
|
package/docs/configuration.md
CHANGED
|
@@ -18,11 +18,6 @@ Override the directory with:
|
|
|
18
18
|
FORGERELAY_CONFIG_DIR=/path/to/config npx @akira-tl/forgerelay serve
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
The rename-era automatic fallback has ended. `DEVSPACE_CONFIG_DIR` is ignored,
|
|
22
|
-
and the default directory is always `~/.forgerelay`. If an older installation
|
|
23
|
-
still has data in a DevSpace-named directory, migrate it explicitly or point
|
|
24
|
-
`FORGERELAY_CONFIG_DIR` at that directory during the migration.
|
|
25
|
-
|
|
26
21
|
## Commands
|
|
27
22
|
|
|
28
23
|
```bash
|
|
@@ -35,9 +30,7 @@ npx @akira-tl/forgerelay config set publicBaseUrl https://forge.example.com/forg
|
|
|
35
30
|
|
|
36
31
|
## Environment variables
|
|
37
32
|
|
|
38
|
-
The public prefix is `FORGERELAY_*`.
|
|
39
|
-
variables are no longer read. Migrate automation, service files, shell profiles,
|
|
40
|
-
and CI configuration to the canonical ForgeRelay names.
|
|
33
|
+
The public environment-variable prefix is `FORGERELAY_*`.
|
|
41
34
|
|
|
42
35
|
## Core variables
|
|
43
36
|
|
|
@@ -79,11 +72,6 @@ A single persisted string remains fully supported, so existing configs require n
|
|
|
79
72
|
migration. For environment configuration, use a comma-separated list in
|
|
80
73
|
`FORGERELAY_PUBLIC_BASE_URL`.
|
|
81
74
|
|
|
82
|
-
ForgeRelay no longer auto-detects DevSpace-named state or worktree directories.
|
|
83
|
-
Persisted `stateDir` and `worktreeRoot` values in `config.json` continue to win
|
|
84
|
-
over defaults, so an explicit configuration may temporarily point at an older
|
|
85
|
-
location while data is migrated.
|
|
86
|
-
|
|
87
75
|
## Native artifact download
|
|
88
76
|
|
|
89
77
|
Native-file download is disabled by default. Enable it with:
|
|
@@ -101,7 +89,7 @@ The same settings may be persisted as `artifactsEnabled` and
|
|
|
101
89
|
`artifactMaxFileBytes` in `config.json`.
|
|
102
90
|
|
|
103
91
|
The tool currently supports the secure native-file publication path on Linux.
|
|
104
|
-
See [Native File Download](artifact-exchange.md).
|
|
92
|
+
See [Native File Download](reference/artifact-exchange.md).
|
|
105
93
|
|
|
106
94
|
## OAuth
|
|
107
95
|
|
|
@@ -111,13 +99,9 @@ ForgeRelay uses a single-user Owner-password OAuth approval flow.
|
|
|
111
99
|
| --- | --- |
|
|
112
100
|
| `FORGERELAY_OAUTH_ACCESS_TOKEN_TTL_SECONDS` | `3600` |
|
|
113
101
|
| `FORGERELAY_OAUTH_REFRESH_TOKEN_TTL_SECONDS` | `2592000` |
|
|
114
|
-
| `FORGERELAY_OAUTH_SCOPES` |
|
|
102
|
+
| `FORGERELAY_OAUTH_SCOPES` | `forgerelay` |
|
|
115
103
|
| `FORGERELAY_OAUTH_ALLOWED_REDIRECT_HOSTS` | `chatgpt.com,localhost,127.0.0.1` |
|
|
116
104
|
|
|
117
|
-
The default OAuth scope intentionally remains the legacy internal value during
|
|
118
|
-
the rename so existing registrations/state do not need a destructive migration.
|
|
119
|
-
This is a protocol compatibility identifier, not product branding.
|
|
120
|
-
|
|
121
105
|
MCP clients discover metadata from:
|
|
122
106
|
|
|
123
107
|
```text
|
|
@@ -136,7 +120,7 @@ MCP clients discover metadata from:
|
|
|
136
120
|
| `codex` | Experimental Codex-shaped compatibility adapter using `open_workspace`, `close_workspace`, `read`, `rename`, `delete`, `apply_patch`, `exec_command`, `write_stdin`, and `capability`. It does not define the ForgeRelay canonical interface. |
|
|
137
121
|
|
|
138
122
|
`FORGERELAY_MINIMAL_TOOLS` remains a compatibility-style boolean alias when the
|
|
139
|
-
explicit tool mode is unset.
|
|
123
|
+
explicit tool mode is unset.
|
|
140
124
|
|
|
141
125
|
`minimal` and `full` now resolve to the same regular 9-tool `tools/list`; `full`
|
|
142
126
|
is retained only as a configuration-compatibility value. `codex` selects a
|
|
@@ -581,7 +565,7 @@ directories; deeper instruction files are discovered lazily when a workspace pat
|
|
|
581
565
|
is first accessed. Reads surface newly discovered instructions inline, while
|
|
582
566
|
side-effecting file/shell operations stop before execution and require a retry if
|
|
583
567
|
that access discovers new local instructions. `FORGERELAY_AGENT_DIR` does not
|
|
584
|
-
select a global instruction file;
|
|
568
|
+
select a global instruction file; its `skills` child is an additional Agent Skills source.
|
|
585
569
|
|
|
586
570
|
## Skills and subagents
|
|
587
571
|
|
|
@@ -589,7 +573,7 @@ select a global instruction file; it remains a compatibility path for Agent Skil
|
|
|
589
573
|
| --- | --- |
|
|
590
574
|
| `FORGERELAY_SKILLS` | Set to `0` to hide skills. Enabled by default. |
|
|
591
575
|
| `FORGERELAY_SUBAGENTS` | Set to `1` to expose configured subagent profiles. |
|
|
592
|
-
| `FORGERELAY_AGENT_DIR` | Defaults to `~/.codex`; its `skills` child is
|
|
576
|
+
| `FORGERELAY_AGENT_DIR` | Defaults to `~/.codex`; its `skills` child is included as an additional Skill source. |
|
|
593
577
|
| `FORGERELAY_SKILL_PATHS` | Optional comma-separated additional skill directories. |
|
|
594
578
|
|
|
595
579
|
Standard Agent Skills are discovered from:
|
|
@@ -605,9 +589,12 @@ When subagents are enabled, profiles are discovered from:
|
|
|
605
589
|
- the active ForgeRelay config directory's `agents/*.md`;
|
|
606
590
|
- project `.forgerelay/agents/*.md`.
|
|
607
591
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
592
|
+
|
|
593
|
+
ForgeRelay does not install or bundle coding-agent executors. Subagent providers
|
|
594
|
+
are available only when the corresponding user-installed executable can be found
|
|
595
|
+
on the server. The default commands are `codex`, `claude`, `opencode`, `pi`,
|
|
596
|
+
`cursor-agent`, and `copilot`. Override the first four when needed with
|
|
597
|
+
`CODEX_COMMAND`, `CLAUDE_COMMAND`, `OPENCODE_COMMAND`, or `PI_COMMAND`.
|
|
611
598
|
|
|
612
599
|
The ForgeRelay-owned `subagents` capability guide teaches the current CLI
|
|
613
600
|
workflow on demand:
|
package/docs/gotchas.md
CHANGED
|
@@ -28,27 +28,6 @@ npm rebuild better-sqlite3
|
|
|
28
28
|
npx @akira-tl/forgerelay doctor
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
## Existing DevSpace config stopped being used
|
|
32
|
-
|
|
33
|
-
The automatic rename-era fallback has ended. ForgeRelay now defaults to
|
|
34
|
-
`~/.forgerelay` and ignores `DEVSPACE_*` environment variables.
|
|
35
|
-
|
|
36
|
-
Check the resolved directory:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
forgerelay doctor
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
If an older installation still needs data from a DevSpace-named directory,
|
|
43
|
-
point the canonical setting at it explicitly while migrating:
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
FORGERELAY_CONFIG_DIR="$HOME/.forgerelay" forgerelay init
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Do not delete the old directory until you have confirmed which persisted state,
|
|
50
|
-
worktrees, skills, and profiles you still need.
|
|
51
|
-
|
|
52
31
|
## Public base URL includes `/mcp`
|
|
53
32
|
|
|
54
33
|
Store the public base URL *before* the final `/mcp`. A routed deployment keeps
|
|
@@ -135,10 +114,6 @@ New installs normally use:
|
|
|
135
114
|
~/.forgerelay/auth.json
|
|
136
115
|
```
|
|
137
116
|
|
|
138
|
-
ForgeRelay no longer discovers `~/.devspace/auth.json` automatically. Move the
|
|
139
|
-
credential file to the active ForgeRelay config directory or explicitly set
|
|
140
|
-
`FORGERELAY_CONFIG_DIR` while migrating.
|
|
141
|
-
|
|
142
117
|
Regenerate setup intentionally with:
|
|
143
118
|
|
|
144
119
|
```bash
|
|
@@ -168,8 +143,6 @@ New managed branches use:
|
|
|
168
143
|
forgerelay/*
|
|
169
144
|
```
|
|
170
145
|
|
|
171
|
-
Legacy persisted `devspace/*` branches remain valid and closable.
|
|
172
|
-
|
|
173
146
|
Uncommitted source-checkout changes are not automatically copied into a newly
|
|
174
147
|
created worktree.
|
|
175
148
|
|
|
@@ -229,9 +202,6 @@ New profile locations include:
|
|
|
229
202
|
.forgerelay/agents/*.md
|
|
230
203
|
```
|
|
231
204
|
|
|
232
|
-
Legacy `.devspace/agents` paths are no longer scanned automatically. Move
|
|
233
|
-
profiles into one of the canonical locations before upgrading.
|
|
234
|
-
|
|
235
205
|
`forgerelay agents ls` lists sessions, not profile definitions. The compact
|
|
236
206
|
profile catalog is returned through `open_workspace`.
|
|
237
207
|
|
package/docs/roadmap.md
CHANGED
|
@@ -55,8 +55,7 @@ The initial independent release establishes:
|
|
|
55
55
|
- branch-backed managed worktrees using `forgerelay/*` branches;
|
|
56
56
|
- safe `close_worktree` fast-forward lifecycle;
|
|
57
57
|
- persisted worktree branch/target metadata;
|
|
58
|
-
- existing local coding-agent profile/provider integration
|
|
59
|
-
- compatibility with legacy DevSpace configuration/state identifiers.
|
|
58
|
+
- existing local coding-agent profile/provider integration.
|
|
60
59
|
|
|
61
60
|
## 0.2 — Hooks v1
|
|
62
61
|
|
|
@@ -358,9 +357,10 @@ Task is a checklist/continuation primitive rather than an execution scheduler:
|
|
|
358
357
|
Subagent coordination can reference Task content when useful, but ForgeRelay does
|
|
359
358
|
not bind Tasks to Subagent Sessions or infer Task completion from execution facts.
|
|
360
359
|
|
|
361
|
-
##
|
|
360
|
+
## Project identity
|
|
362
361
|
|
|
363
|
-
|
|
362
|
+
ForgeRelay uses its own package, CLI, configuration, state, project-directory,
|
|
363
|
+
and managed-branch namespaces:
|
|
364
364
|
|
|
365
365
|
- `@akira-tl/forgerelay`
|
|
366
366
|
- `forgerelay`
|
|
@@ -369,9 +369,5 @@ New public names use ForgeRelay:
|
|
|
369
369
|
- `.forgerelay`
|
|
370
370
|
- `forgerelay/*` managed branches
|
|
371
371
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
`.devspace/agents` discovery, and old package-path special cases are retired once
|
|
375
|
-
they are outside that window. Persisted internal identifiers remain compatible
|
|
376
|
-
when removing them would orphan real user state; those are storage/protocol
|
|
377
|
-
migration concerns, not public product aliases.
|
|
372
|
+
Upstream attribution is preserved separately through `LICENSE`, `NOTICE.md`, and
|
|
373
|
+
release provenance checks; it is not a runtime compatibility surface.
|
package/docs/security.md
CHANGED
|
@@ -60,10 +60,6 @@ FORGERELAY_OAUTH_OWNER_TOKEN="$(openssl rand -base64 32)"
|
|
|
60
60
|
|
|
61
61
|
The token must be at least 16 characters.
|
|
62
62
|
|
|
63
|
-
Rename-era `DEVSPACE_*` environment-variable and automatic `~/.devspace`
|
|
64
|
-
configuration fallbacks have ended. Use canonical `FORGERELAY_*` settings and
|
|
65
|
-
explicit paths when migrating older installations.
|
|
66
|
-
|
|
67
63
|
## Public URL and tunnels
|
|
68
64
|
|
|
69
65
|
ForgeRelay needs `FORGERELAY_PUBLIC_BASE_URL` when an MCP client reaches it
|
|
@@ -186,7 +182,7 @@ not accept arbitrary signed URLs, local paths,
|
|
|
186
182
|
embedded credentials, or base64 strings as substitutes.
|
|
187
183
|
|
|
188
184
|
Downloads are streamed, size-limited, created without overwrite, and published
|
|
189
|
-
as owner-only files. See [Native File Download](artifact-exchange.md).
|
|
185
|
+
as owner-only files. See [Native File Download](reference/artifact-exchange.md).
|
|
190
186
|
|
|
191
187
|
## Logging
|
|
192
188
|
|
package/docs/setup.md
CHANGED
|
@@ -119,17 +119,6 @@ New installations use:
|
|
|
119
119
|
|
|
120
120
|
Keep `auth.json` private.
|
|
121
121
|
|
|
122
|
-
### Existing DevSpace configuration
|
|
123
|
-
|
|
124
|
-
Automatic DevSpace directory fallback has ended. ForgeRelay defaults to
|
|
125
|
-
`~/.forgerelay` and ignores `DEVSPACE_CONFIG_DIR`.
|
|
126
|
-
|
|
127
|
-
Before upgrading an older installation, move or copy the needed configuration
|
|
128
|
-
and credentials into the ForgeRelay directory, or temporarily point
|
|
129
|
-
`FORGERELAY_CONFIG_DIR` at the old directory. If state or managed worktrees live
|
|
130
|
-
under older paths, preserve them with explicit `stateDir` / `worktreeRoot`
|
|
131
|
-
configuration until migration is complete.
|
|
132
|
-
|
|
133
122
|
## Check the setup
|
|
134
123
|
|
|
135
124
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akira-tl/forgerelay",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.9",
|
|
4
4
|
"description": "Local development control plane for MCP coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/Akira-TL/forgerelay#readme",
|
|
@@ -41,9 +41,11 @@
|
|
|
41
41
|
"debug:serve": "node scripts/debug/serve.mjs",
|
|
42
42
|
"debug:accept": "node scripts/debug/accept.mjs",
|
|
43
43
|
"debug:accept:relay": "node scripts/debug/relay-accept.mjs",
|
|
44
|
-
"
|
|
44
|
+
"traffic:audit": "node --import tsx scripts/debug/traffic/traffic-audit.mjs",
|
|
45
|
+
"lsp:interop": "node scripts/lsp/interop.mjs",
|
|
45
46
|
"wiki:check": "node scripts/wiki/sync.mjs check",
|
|
46
47
|
"wiki:publish": "node scripts/wiki/sync.mjs publish",
|
|
48
|
+
"architecture:check": "node scripts/ci/architecture.mjs",
|
|
47
49
|
"ci:verify": "node scripts/ci/verify.mjs",
|
|
48
50
|
"release:parity": "node scripts/release-parity.mjs",
|
|
49
51
|
"release:pack": "node scripts/release/pack.mjs",
|
|
@@ -51,7 +53,7 @@
|
|
|
51
53
|
"release:push-ready": "node scripts/release/push-ready.mjs",
|
|
52
54
|
"postinstall": "node scripts/fix-node-pty-permissions.mjs",
|
|
53
55
|
"start": "node dist/cli.js serve",
|
|
54
|
-
"test": "node --test scripts/debug/runtime.test.mjs scripts/release-proof.test.mjs scripts/release/release-gate.test.mjs scripts/release/push-ready.test.mjs scripts/release/release-version.test.mjs && tsx src/oauth/router.test.ts && tsx src/remote-auth-cli.test.ts && tsx src/remote-ssh-auth-cli.test.ts && tsx src/
|
|
56
|
+
"test": "node --test scripts/debug/runtime.test.mjs scripts/release-proof.test.mjs scripts/release/release-gate.test.mjs scripts/release/push-ready.test.mjs scripts/release/release-version.test.mjs && tsx src/mcp/oauth/router.test.ts && tsx src/workspaces/relay/auth/remote-auth-cli.test.ts && tsx src/workspaces/relay/auth/remote-ssh-auth-cli.test.ts && tsx src/workspaces/relay/tests/lifecycle.test.ts && tsx src/workspaces/relay/tests/routing.test.ts && tsx src/workspaces/relay/tests/ssh.test.ts && tsx src/workspaces/relay/tests/process.test.ts && tsx src/runtime/config/config.test.ts && tsx src/lsp/language-server-config.test.ts && tsx src/lsp/normalization/hover.test.ts && tsx src/lsp/references.server.test.ts && tsx src/lsp/operations/document-symbols.server.test.ts && tsx src/lsp/operations/workspace-symbols.server.test.ts && tsx src/lsp/operations/diagnostics-push.server.test.ts && tsx src/lsp/operations/diagnostics-pull.server.test.ts && tsx src/lsp/operations/request-hardening.server.test.ts && tsx src/lsp/operations/recovery.server.test.ts && tsx src/lsp/operations/lifecycle.server.test.ts && tsx src/lsp/runtime/semantic-requests.test.ts && tsx src/runtime/logging/logger.test.ts && tsx src/runtime/logging/proxy-trust.test.ts && tsx src/runtime/state/lock/file-lock.test.ts && tsx src/mcp/panel/mcp-app-template.test.ts && tsx src/mcp/hooks/hooks.test.ts && tsx src/mcp/server/core/capability-registry.test.ts && tsx src/mcp/server-instructions.test.ts && tsx src/mcp/request-meta.test.ts && tsx src/mcp/artifacts/incoming-artifacts.test.ts && tsx src/mcp/artifacts/artifact-download.test.ts && tsx src/ui/core/card-types.test.ts && tsx src/ui/activity/model.test.ts && tsx src/ui/activity/detail-card.test.ts && tsx src/ui/review/patch-display.test.ts && tsx src/ui/core/tool-display.test.ts && tsx src/mcp/filesystem/apply-patch.test.ts && tsx src/mcp/process/process-platform.test.ts && tsx src/mcp/process/process-sessions.test.ts && tsx src/mcp/server/transport/mcp-sessions.test.ts && tsx src/mcp/server/transport/server-shutdown.test.ts && tsx src/subagents/providers/adapters/codex.test.ts && tsx src/subagents/providers/adapters/pi.test.ts && tsx src/subagents/providers/registry.test.ts && tsx src/subagents/providers/availability.test.ts && tsx src/subagents/profiles.test.ts && tsx src/subagents/cli-target.test.ts && tsx src/subagents/sessions/store.test.ts && tsx src/subagents/sessions/manager.test.ts && tsx src/subagents/sessions/mcp/capability.server.test.ts && tsx src/subagents/sessions/mcp/continuation.server.test.ts && tsx src/subagents/sessions/mcp/lifecycle.server.test.ts && tsx src/subagents/sessions/mcp/reconciliation.server.test.ts && tsx src/subagents/sessions/mcp/routing.server.test.ts && tsx src/mcp/filesystem/roots.test.ts && tsx src/mcp/filesystem/file-mutations.test.ts && tsx src/mcp/operations/edit-preflight.test.ts && tsx src/workspaces/resources/skills.test.ts && tsx src/runtime/state/db/migrations.test.ts && tsx src/workspaces/state/workspace-store.test.ts && tsx src/workspaces/tasks/workspace-tasks.test.ts && tsx src/workspaces/tasks/workspace-task-reminders.test.ts && tsx src/activity/history/audit-store.test.ts && tsx src/activity/history/bash-output-store.test.ts && tsx src/activity/runtime/lifecycle.test.ts && tsx src/activity/history/query-service.test.ts && tsx src/mcp/operations/core-operation-executor.test.ts && tsx src/mcp/operations/bulk-mutation.test.ts && tsx src/mcp/operations/batch/scheduler.test.ts && tsx src/mcp/operations/batch/executor-policy.test.ts && tsx src/workspaces.test.ts && tsx src/workspaces/conversation-checkout.test.ts && tsx src/workspaces/conversation-worktree.test.ts && tsx src/workspaces/review/review-checkpoints.test.ts && tsx src/lsp/code-intelligence.server.test.ts && npm run build:app && tsx src/mcp/process/server.test.ts && tsx src/mcp/panel/server.test.ts && tsx src/mcp/server/server.test.ts && tsx src/mcp/oauth/oauth-store.test.ts && tsx src/cli/cli.test.ts",
|
|
55
57
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
56
58
|
"release:check": "node scripts/release-version.mjs check",
|
|
57
59
|
"release:tag-check": "node scripts/release-version.mjs tag",
|
|
@@ -73,15 +75,11 @@
|
|
|
73
75
|
"license": "MIT",
|
|
74
76
|
"dependencies": {
|
|
75
77
|
"@agentclientprotocol/sdk": "^1.1.0",
|
|
76
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.200",
|
|
77
78
|
"@clack/prompts": "^1.5.1",
|
|
78
|
-
"@earendil-works/pi-coding-agent": "^0.80.3",
|
|
79
79
|
"@modelcontextprotocol/ext-apps": "^1.7.2",
|
|
80
80
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
81
|
-
"@openai/codex-sdk": "^0.142.5",
|
|
82
|
-
"@opencode-ai/sdk": "^1.17.13",
|
|
83
81
|
"@pierre/diffs": "^1.2.5",
|
|
84
|
-
"better-sqlite3": "^
|
|
82
|
+
"better-sqlite3": "^13.0.3",
|
|
85
83
|
"diff": "^8.0.3",
|
|
86
84
|
"drizzle-orm": "^0.45.2",
|
|
87
85
|
"express": "^5.2.1",
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { extname, basename, dirname } from "node:path";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
|
|
7
|
+
const MAX_LINES = 800;
|
|
8
|
+
const MAX_DIRECT_FILES = 8;
|
|
9
|
+
const MAX_DIRECT_DIRS = 8;
|
|
10
|
+
const LINE_LIMIT_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".mjs", ".cjs", ".css"]);
|
|
11
|
+
|
|
12
|
+
// Repository-root protocol files are intentionally discoverable by Git, npm,
|
|
13
|
+
// Node, Vite, contributors, and agents. Keep that conventional surface explicit
|
|
14
|
+
// instead of hiding required/default-discovery files merely to satisfy a count.
|
|
15
|
+
const ROOT_PROTOCOL_FILES = new Set([
|
|
16
|
+
".env.example",
|
|
17
|
+
".gitignore",
|
|
18
|
+
".nvmrc",
|
|
19
|
+
"AGENTS.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
"CONTEXT.md",
|
|
22
|
+
"CONTRIBUTING.md",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"NOTICE.md",
|
|
25
|
+
"README.md",
|
|
26
|
+
"package-lock.json",
|
|
27
|
+
"package.json",
|
|
28
|
+
"tsconfig.build.json",
|
|
29
|
+
"tsconfig.json",
|
|
30
|
+
"vite.config.ts",
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const tracked = gitTrackedFiles();
|
|
34
|
+
const violations = [];
|
|
35
|
+
const directFiles = new Map();
|
|
36
|
+
const directDirs = new Map();
|
|
37
|
+
|
|
38
|
+
for (const path of tracked) {
|
|
39
|
+
const parent = normalizeDirectory(dirname(path));
|
|
40
|
+
directFiles.set(parent, (directFiles.get(parent) ?? 0) + 1);
|
|
41
|
+
|
|
42
|
+
let child = parent;
|
|
43
|
+
while (child !== ".") {
|
|
44
|
+
const grandparent = normalizeDirectory(dirname(child));
|
|
45
|
+
let children = directDirs.get(grandparent);
|
|
46
|
+
if (!children) directDirs.set(grandparent, children = new Set());
|
|
47
|
+
children.add(basename(child));
|
|
48
|
+
child = grandparent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (LINE_LIMIT_EXTENSIONS.has(extname(path))) {
|
|
52
|
+
const lines = physicalLineCount(readFileSync(path, "utf8"));
|
|
53
|
+
if (lines > MAX_LINES) violations.push(`${path}: ${lines} lines > ${MAX_LINES}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (const path of tracked.filter((path) => dirname(path) === ".")) {
|
|
58
|
+
if (!ROOT_PROTOCOL_FILES.has(path)) violations.push(`repository root has unclassified file: ${path}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const allowed of ROOT_PROTOCOL_FILES) {
|
|
62
|
+
if (!tracked.includes(allowed)) continue;
|
|
63
|
+
// Presence is allowed, not required; this loop documents the intentional set.
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const directories = new Set([...directFiles.keys(), ...directDirs.keys()]);
|
|
67
|
+
for (const directory of [...directories].sort()) {
|
|
68
|
+
const files = directFiles.get(directory) ?? 0;
|
|
69
|
+
const dirs = directDirs.get(directory)?.size ?? 0;
|
|
70
|
+
if (directory !== "." && files > MAX_DIRECT_FILES) {
|
|
71
|
+
violations.push(`${directory}: ${files} direct files > ${MAX_DIRECT_FILES}`);
|
|
72
|
+
}
|
|
73
|
+
if (dirs > MAX_DIRECT_DIRS) {
|
|
74
|
+
violations.push(`${directory}: ${dirs} direct directories > ${MAX_DIRECT_DIRS}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (violations.length > 0) {
|
|
79
|
+
console.error("Architecture check failed:");
|
|
80
|
+
for (const violation of violations) console.error(`- ${violation}`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log(
|
|
85
|
+
`Architecture check passed: ${tracked.length} tracked files; ` +
|
|
86
|
+
`code <= ${MAX_LINES} lines; non-root directories <= ${MAX_DIRECT_FILES} files / ${MAX_DIRECT_DIRS} directories.`,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
function gitTrackedFiles() {
|
|
90
|
+
const result = spawnSync("git", ["ls-files", "-z"], {
|
|
91
|
+
cwd: process.cwd(),
|
|
92
|
+
encoding: "utf8",
|
|
93
|
+
windowsHide: true,
|
|
94
|
+
shell: false,
|
|
95
|
+
});
|
|
96
|
+
if (result.error) throw result.error;
|
|
97
|
+
if (result.status !== 0) throw new Error(`git ls-files failed with exit ${result.status ?? "unknown"}`);
|
|
98
|
+
return result.stdout.split("\0").filter(Boolean);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function normalizeDirectory(directory) {
|
|
102
|
+
return directory === "" ? "." : directory.replaceAll("\\", "/");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function physicalLineCount(text) {
|
|
106
|
+
if (text.length === 0) return 0;
|
|
107
|
+
const newlines = text.match(/\n/g)?.length ?? 0;
|
|
108
|
+
return newlines + (text.endsWith("\n") ? 0 : 1);
|
|
109
|
+
}
|
package/scripts/ci/verify.mjs
CHANGED
|
@@ -9,10 +9,15 @@ if (!npmCli) {
|
|
|
9
9
|
|
|
10
10
|
console.log(`CI environment: ${process.platform}/${process.arch} ${process.version}`);
|
|
11
11
|
runNpm(["--version"], "npm version");
|
|
12
|
+
runNpm(["run", "architecture:check"], "Architecture");
|
|
12
13
|
runNpm(["run", "release:check"], "Release metadata");
|
|
13
14
|
runNpm(["run", "typecheck"], "Typecheck");
|
|
14
15
|
runNpm(["test"], "Full test suite");
|
|
15
16
|
runNpm(["run", "build"], "Build");
|
|
17
|
+
// The traffic audit is an end-to-end wire-budget check, not a platform feature
|
|
18
|
+
// matrix. Run it once on Linux so regressions are gated without tripling the
|
|
19
|
+
// 7677/7678 server exercise across every CI operating system.
|
|
20
|
+
if (process.platform === "linux") runNpm(["run", "traffic:audit"], "Traffic audit");
|
|
16
21
|
runNpm(["run", "lsp:interop"], "Optional LSP interoperability");
|
|
17
22
|
run(process.execPath, ["dist/cli.js", "doctor"], "Doctor");
|
|
18
23
|
|