@visual-z/xeno 0.8.4 → 0.9.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/CHANGELOG.md +19 -0
- package/README.md +31 -746
- package/bin/xeno.exe +26 -0
- package/install.cjs +88 -0
- package/package.json +18 -48
- package/docs/app-server.md +0 -115
- package/docs/foundations.md +0 -88
- package/docs/install.md +0 -244
- package/docs/providers.md +0 -172
- package/docs/research/foundation-clients-2026-10-09.md +0 -27
- package/docs/research/foundation-editing-2026-10-09.md +0 -56
- package/docs/research/foundation-network-2026-10-09.md +0 -37
- package/docs/research/foundation-workflow-2026-10-09.md +0 -37
- package/src/apps/acp-server.ts +0 -41
- package/src/apps/agent-profiles.ts +0 -19
- package/src/apps/app-server.ts +0 -30
- package/src/apps/approve.ts +0 -49
- package/src/apps/cli.ts +0 -99
- package/src/apps/commands.ts +0 -319
- package/src/apps/completions.ts +0 -87
- package/src/apps/control-transport.ts +0 -90
- package/src/apps/export-cli.ts +0 -24
- package/src/apps/goal-flow.ts +0 -70
- package/src/apps/image-draft.ts +0 -46
- package/src/apps/input.ts +0 -312
- package/src/apps/model-catalog.ts +0 -69
- package/src/apps/preferences.ts +0 -20
- package/src/apps/project-trust.ts +0 -9
- package/src/apps/provider-connect.ts +0 -346
- package/src/apps/question-ui.ts +0 -27
- package/src/apps/render.ts +0 -181
- package/src/apps/resources.ts +0 -66
- package/src/apps/review.ts +0 -109
- package/src/apps/session-hub.ts +0 -96
- package/src/apps/session-lifecycle.ts +0 -64
- package/src/apps/shell.ts +0 -2071
- package/src/apps/startup-input.ts +0 -135
- package/src/apps/startup.ts +0 -1677
- package/src/apps/ui/app.ts +0 -1818
- package/src/apps/ui/control-model.ts +0 -43
- package/src/apps/ui/extension-host.ts +0 -194
- package/src/apps/ui/image-cache.ts +0 -121
- package/src/apps/ui/palette.ts +0 -88
- package/src/apps/ui/project.ts +0 -127
- package/src/apps/ui/standalone.ts +0 -148
- package/src/apps/ui/status-model.ts +0 -68
- package/src/apps/ui/surface.ts +0 -91
- package/src/apps/ui/theme.ts +0 -86
- package/src/apps/update-check.ts +0 -112
- package/src/apps/workflow.ts +0 -58
- package/src/core/acceptance.ts +0 -139
- package/src/core/action-defaults.ts +0 -58
- package/src/core/activity-status.ts +0 -52
- package/src/core/agent-profile.ts +0 -130
- package/src/core/attachment-input.ts +0 -17
- package/src/core/blind-checks.ts +0 -72
- package/src/core/boundary.ts +0 -174
- package/src/core/branch-receipt.ts +0 -26
- package/src/core/catalog-merge.ts +0 -19
- package/src/core/checkpoints.ts +0 -85
- package/src/core/churn.ts +0 -61
- package/src/core/command-artifacts.ts +0 -94
- package/src/core/command-contract.ts +0 -151
- package/src/core/completion-action.ts +0 -20
- package/src/core/completion-review.ts +0 -98
- package/src/core/context-detail.ts +0 -37
- package/src/core/context-policy.ts +0 -133
- package/src/core/context-window.ts +0 -54
- package/src/core/continuation.ts +0 -130
- package/src/core/control-protocol.ts +0 -69
- package/src/core/control-view.ts +0 -39
- package/src/core/cycle.ts +0 -17
- package/src/core/data-query.ts +0 -201
- package/src/core/deadline.ts +0 -40
- package/src/core/derive.ts +0 -516
- package/src/core/draft-images.ts +0 -56
- package/src/core/edit-plan.ts +0 -200
- package/src/core/environment.ts +0 -181
- package/src/core/event-validation.ts +0 -220
- package/src/core/events.ts +0 -670
- package/src/core/evidence-ladder.ts +0 -62
- package/src/core/evidence-links.ts +0 -68
- package/src/core/evidence.ts +0 -240
- package/src/core/execution.ts +0 -18
- package/src/core/exhaustive.ts +0 -18
- package/src/core/export.ts +0 -179
- package/src/core/extension-flags.ts +0 -14
- package/src/core/external-effects.ts +0 -488
- package/src/core/failure-recovery.ts +0 -173
- package/src/core/file-precondition.ts +0 -78
- package/src/core/file-references.ts +0 -35
- package/src/core/frontmatter.ts +0 -213
- package/src/core/git-status.ts +0 -29
- package/src/core/goal-view.ts +0 -64
- package/src/core/goal.ts +0 -200
- package/src/core/handoff.ts +0 -479
- package/src/core/history-query.ts +0 -139
- package/src/core/history.ts +0 -237
- package/src/core/image-limits.ts +0 -72
- package/src/core/images.ts +0 -46
- package/src/core/integration-health.ts +0 -34
- package/src/core/json-event.ts +0 -131
- package/src/core/json-pointer.ts +0 -46
- package/src/core/keymap.ts +0 -153
- package/src/core/lsp-framing.ts +0 -34
- package/src/core/mcp-config.ts +0 -68
- package/src/core/model-picker.ts +0 -64
- package/src/core/model-preferences.ts +0 -28
- package/src/core/model-replay.ts +0 -22
- package/src/core/model-scope.ts +0 -53
- package/src/core/note-guidance.ts +0 -34
- package/src/core/oauth-fields.ts +0 -44
- package/src/core/observation-view.ts +0 -152
- package/src/core/outcome.ts +0 -44
- package/src/core/overflow.ts +0 -59
- package/src/core/packages.ts +0 -47
- package/src/core/patch.ts +0 -130
- package/src/core/path-suggestions.ts +0 -59
- package/src/core/permissions.ts +0 -410
- package/src/core/process-receipt.ts +0 -105
- package/src/core/process-state.ts +0 -37
- package/src/core/program-status.ts +0 -40
- package/src/core/progress.ts +0 -150
- package/src/core/project.ts +0 -431
- package/src/core/prompt-policy.ts +0 -46
- package/src/core/prompts.ts +0 -111
- package/src/core/question.ts +0 -94
- package/src/core/queue.ts +0 -78
- package/src/core/read-bounds.ts +0 -24
- package/src/core/read-observation.ts +0 -106
- package/src/core/recovery-sources.ts +0 -74
- package/src/core/regex-dialect.ts +0 -25
- package/src/core/request-budget.ts +0 -23
- package/src/core/request-progress.ts +0 -87
- package/src/core/request-state.ts +0 -273
- package/src/core/resource-selection.ts +0 -36
- package/src/core/response-recovery.ts +0 -59
- package/src/core/resume.ts +0 -59
- package/src/core/review.ts +0 -68
- package/src/core/ripgrep-release.ts +0 -64
- package/src/core/runtime-target.ts +0 -94
- package/src/core/scheduling.ts +0 -8
- package/src/core/search-observation.ts +0 -97
- package/src/core/secrets.ts +0 -188
- package/src/core/session-archive.ts +0 -4
- package/src/core/session-browser.ts +0 -82
- package/src/core/session-entry.ts +0 -61
- package/src/core/session-exit.ts +0 -42
- package/src/core/session-format.ts +0 -169
- package/src/core/session-position.ts +0 -26
- package/src/core/session-tree.ts +0 -147
- package/src/core/settings.ts +0 -192
- package/src/core/skills.ts +0 -165
- package/src/core/sql-query.ts +0 -211
- package/src/core/stall.ts +0 -128
- package/src/core/stop-report.ts +0 -68
- package/src/core/text-normalize.ts +0 -81
- package/src/core/theme.ts +0 -166
- package/src/core/thinking.ts +0 -26
- package/src/core/tokens.ts +0 -151
- package/src/core/tool-contract.ts +0 -153
- package/src/core/tool-discovery.ts +0 -87
- package/src/core/tool-failure.ts +0 -81
- package/src/core/tool-input.ts +0 -44
- package/src/core/transcript.ts +0 -108
- package/src/core/tui-mode.ts +0 -29
- package/src/core/update-check.ts +0 -157
- package/src/core/version.ts +0 -55
- package/src/core/web-content.ts +0 -80
- package/src/core/work-state.ts +0 -154
- package/src/core/workflow-mode.ts +0 -34
- package/src/core/working-set.ts +0 -119
- package/src/core/yaml.ts +0 -282
- package/src/runtime/acp-agent.ts +0 -289
- package/src/runtime/agent-profiles.ts +0 -21
- package/src/runtime/auth.ts +0 -367
- package/src/runtime/blind-check.ts +0 -36
- package/src/runtime/branch-jobs.ts +0 -36
- package/src/runtime/catalog.ts +0 -285
- package/src/runtime/clipboard.ts +0 -125
- package/src/runtime/command-artifacts.ts +0 -64
- package/src/runtime/connection-reuse.ts +0 -40
- package/src/runtime/control-client.ts +0 -149
- package/src/runtime/control-connection.ts +0 -139
- package/src/runtime/counter-check.ts +0 -74
- package/src/runtime/environment-tools.ts +0 -60
- package/src/runtime/evidence-notes.ts +0 -35
- package/src/runtime/exec-sessions.ts +0 -456
- package/src/runtime/execution-control.ts +0 -40
- package/src/runtime/extension-loader.ts +0 -37
- package/src/runtime/extension-ui.ts +0 -47
- package/src/runtime/extensions.ts +0 -370
- package/src/runtime/formatter-tool.ts +0 -38
- package/src/runtime/formatter.ts +0 -50
- package/src/runtime/foundation.ts +0 -116
- package/src/runtime/history-cache.ts +0 -57
- package/src/runtime/history-tools.ts +0 -168
- package/src/runtime/images.ts +0 -80
- package/src/runtime/integrations.ts +0 -216
- package/src/runtime/loop.ts +0 -3108
- package/src/runtime/lsp-client.ts +0 -201
- package/src/runtime/mcp-client.ts +0 -264
- package/src/runtime/mcp-oauth.ts +0 -168
- package/src/runtime/mcp-schema.ts +0 -51
- package/src/runtime/model-config.ts +0 -232
- package/src/runtime/model-data.LICENSE +0 -27
- package/src/runtime/model-data.ts +0 -21
- package/src/runtime/model-discovery.ts +0 -208
- package/src/runtime/model-replay.ts +0 -10
- package/src/runtime/model-scope.ts +0 -20
- package/src/runtime/model-sources.ts +0 -151
- package/src/runtime/model.ts +0 -686
- package/src/runtime/models-fetch.ts +0 -57
- package/src/runtime/oauth-device.ts +0 -86
- package/src/runtime/oauth.ts +0 -853
- package/src/runtime/open-image.ts +0 -42
- package/src/runtime/openai-responses.ts +0 -304
- package/src/runtime/openai.ts +0 -697
- package/src/runtime/output-schema.ts +0 -26
- package/src/runtime/package-manager.ts +0 -125
- package/src/runtime/patch-tool.ts +0 -38
- package/src/runtime/permission-resources.ts +0 -18
- package/src/runtime/pi-provider.ts +0 -423
- package/src/runtime/program-status.ts +0 -38
- package/src/runtime/progress.ts +0 -26
- package/src/runtime/provider-access.ts +0 -21
- package/src/runtime/provider-connect.ts +0 -109
- package/src/runtime/provider-presets.ts +0 -98
- package/src/runtime/provider-protocols.ts +0 -29
- package/src/runtime/provider-request.ts +0 -87
- package/src/runtime/provider-tool-policy.ts +0 -33
- package/src/runtime/provider.ts +0 -580
- package/src/runtime/question-tool.ts +0 -62
- package/src/runtime/retry.ts +0 -447
- package/src/runtime/review-tool.ts +0 -48
- package/src/runtime/rich-text.ts +0 -36
- package/src/runtime/runtime-target.ts +0 -149
- package/src/runtime/secrets.ts +0 -79
- package/src/runtime/self-update.ts +0 -74
- package/src/runtime/session-control.ts +0 -265
- package/src/runtime/session-hub.ts +0 -85
- package/src/runtime/stream-idle.ts +0 -80
- package/src/runtime/tool-broker.ts +0 -137
- package/src/runtime/tool-discovery.ts +0 -58
- package/src/runtime/tool-queue.ts +0 -77
- package/src/runtime/tools.ts +0 -1820
- package/src/runtime/turn-effects.ts +0 -31
- package/src/runtime/update-check.ts +0 -48
- package/src/runtime/usage.ts +0 -253
- package/src/runtime/version.ts +0 -12
- package/src/runtime/web-http.ts +0 -56
- package/src/runtime/web-tools.ts +0 -88
- package/src/runtime/working-notes.ts +0 -60
- package/src/runtime/workspace-lifecycle.ts +0 -141
- package/src/store/acceptance.ts +0 -15
- package/src/store/agent-profile-files.ts +0 -13
- package/src/store/atomic.ts +0 -31
- package/src/store/auth-store.ts +0 -50
- package/src/store/blind-checks.ts +0 -32
- package/src/store/blobs.ts +0 -143
- package/src/store/checkpoint-history.ts +0 -32
- package/src/store/command-artifacts.ts +0 -96
- package/src/store/command.ts +0 -111
- package/src/store/config.ts +0 -69
- package/src/store/context-files.ts +0 -436
- package/src/store/file-checkpoints.ts +0 -108
- package/src/store/file-index.ts +0 -174
- package/src/store/foundation-config.ts +0 -24
- package/src/store/git-checkpoints.ts +0 -67
- package/src/store/git-status.ts +0 -15
- package/src/store/history-search.ts +0 -19
- package/src/store/log.ts +0 -725
- package/src/store/lsp-document.ts +0 -30
- package/src/store/mcp-credentials.ts +0 -85
- package/src/store/models.ts +0 -60
- package/src/store/observations.ts +0 -224
- package/src/store/packages.ts +0 -98
- package/src/store/patch.ts +0 -92
- package/src/store/permission-paths.ts +0 -34
- package/src/store/process-receipts.ts +0 -34
- package/src/store/query-source.ts +0 -49
- package/src/store/recovery.ts +0 -44
- package/src/store/replay.ts +0 -76
- package/src/store/resource-index.ts +0 -170
- package/src/store/resources.ts +0 -285
- package/src/store/restore.ts +0 -110
- package/src/store/review.ts +0 -109
- package/src/store/runtime-target.ts +0 -64
- package/src/store/search.ts +0 -728
- package/src/store/secrets.ts +0 -44
- package/src/store/serial.ts +0 -13
- package/src/store/session-archive.ts +0 -165
- package/src/store/session-browser.ts +0 -68
- package/src/store/session-position.ts +0 -27
- package/src/store/sessions.ts +0 -525
- package/src/store/source-cancellation.ts +0 -6
- package/src/store/tool-binaries.ts +0 -90
- package/src/store/trust.ts +0 -82
- package/src/store/update-cache.ts +0 -36
- package/src/store/user-settings.ts +0 -30
- package/src/store/workspace-clone.ts +0 -42
- package/src/store/workspace-observation.ts +0 -113
- package/src/store/workspace.ts +0 -115
- package/src/store/worktree.ts +0 -278
- package/src/tui/ansi-spans.ts +0 -126
- package/src/tui/diff.ts +0 -160
- package/src/tui/exhaustive.ts +0 -14
- package/src/tui/fuzzy.ts +0 -75
- package/src/tui/style.ts +0 -208
- package/src/tui/ui/atomic-draft.ts +0 -121
- package/src/tui/ui/branch-panel.ts +0 -47
- package/src/tui/ui/canvas.ts +0 -96
- package/src/tui/ui/colors.ts +0 -70
- package/src/tui/ui/composer.ts +0 -199
- package/src/tui/ui/control-panel.ts +0 -25
- package/src/tui/ui/control-sidebar.ts +0 -49
- package/src/tui/ui/dialog.ts +0 -398
- package/src/tui/ui/draft.ts +0 -23
- package/src/tui/ui/duration.ts +0 -16
- package/src/tui/ui/edge.ts +0 -186
- package/src/tui/ui/image-size.ts +0 -44
- package/src/tui/ui/ink.ts +0 -210
- package/src/tui/ui/items.ts +0 -42
- package/src/tui/ui/keys.ts +0 -40
- package/src/tui/ui/layout.ts +0 -74
- package/src/tui/ui/list-model.ts +0 -86
- package/src/tui/ui/list-view.ts +0 -172
- package/src/tui/ui/mascot.ts +0 -67
- package/src/tui/ui/messages.ts +0 -518
- package/src/tui/ui/motion.ts +0 -28
- package/src/tui/ui/paths.ts +0 -10
- package/src/tui/ui/pictures.ts +0 -108
- package/src/tui/ui/prompt-history.ts +0 -60
- package/src/tui/ui/screen.ts +0 -579
- package/src/tui/ui/status.ts +0 -403
- package/src/tui/ui/styled.ts +0 -85
- package/src/tui/ui/tool-card.ts +0 -150
- package/src/tui/width.ts +0 -567
- package/src/vendor/pi-rich/LICENSE.upstream +0 -21
- package/src/vendor/pi-rich/UPSTREAM.json +0 -17
- package/src/vendor/pi-rich/clipboard-command.ts +0 -44
- package/src/vendor/pi-rich/exif-orientation.ts +0 -182
- package/src/vendor/pi-rich/html.ts +0 -51
- package/src/vendor/pi-rich/image-convert.ts +0 -49
- package/src/vendor/pi-rich/image-resize-core.ts +0 -164
- package/src/vendor/pi-rich/image-resize-worker.ts +0 -42
- package/src/vendor/pi-rich/image-resize.ts +0 -123
- package/src/vendor/pi-rich/mime.ts +0 -116
- package/src/vendor/pi-rich/photon.ts +0 -139
- package/src/vendor/pi-rich/syntax-highlight.ts +0 -214
package/bin/xeno.exe
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# xeno placeholder (docs/tasks/feat-binary-release.md). No shebang on purpose:
|
|
2
|
+
# npm's Windows cmd-shim then execs bin/xeno.exe directly once postinstall has
|
|
3
|
+
# replaced this file with the real binary. POSIX shells run a file without a
|
|
4
|
+
# shebang as a sh script, which is what happens when postinstall never ran
|
|
5
|
+
# (`bun add -g` skips dependency scripts unless the package is trusted).
|
|
6
|
+
# Platform keys must match scripts/binary-targets.ts.
|
|
7
|
+
self=$0
|
|
8
|
+
while [ -h "$self" ]; do
|
|
9
|
+
link=$(readlink "$self")
|
|
10
|
+
case $link in /*) self=$link ;; *) self=$(dirname "$self")/$link ;; esac
|
|
11
|
+
done
|
|
12
|
+
main=$(cd "$(dirname "$self")/.." && pwd -P)
|
|
13
|
+
case $(uname -s) in Darwin) os=darwin ;; Linux) os=linux ;; *) os=$(uname -s) ;; esac
|
|
14
|
+
case $(uname -m) in arm64|aarch64) arch=arm64 ;; x86_64|amd64) arch=x64 ;; *) arch=$(uname -m) ;; esac
|
|
15
|
+
libc=
|
|
16
|
+
if [ "$os" = linux ] && { ls /lib/ld-musl-* >/dev/null 2>&1 || ldd --version 2>&1 | grep -qi musl; }; then libc=-musl; fi
|
|
17
|
+
# An x64 shell under Rosetta on Apple Silicon: prefer the native arm64 build.
|
|
18
|
+
if [ "$os" = darwin ] && [ "$arch" = x64 ] && [ "$(sysctl -n sysctl.proc_translated 2>/dev/null)" = 1 ]; then arch=arm64; fi
|
|
19
|
+
key=$os-$arch$libc
|
|
20
|
+
# npm nests optional dependencies under the main package; bun hoists them beside it.
|
|
21
|
+
for bin in "$main/node_modules/@visual-z/xeno-$key/xeno" "$main/../xeno-$key/xeno"; do
|
|
22
|
+
if [ -x "$bin" ]; then exec "$bin" "$@"; fi
|
|
23
|
+
done
|
|
24
|
+
echo "xeno: no binary for $key was installed." >&2
|
|
25
|
+
echo "Reinstall without --omit=optional: npm i -g @visual-z/xeno" >&2
|
|
26
|
+
exit 1
|
package/install.cjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Postinstall for @visual-z/xeno (docs/tasks/feat-binary-release.md).
|
|
3
|
+
//
|
|
4
|
+
// Finds this machine's platform package among the optionalDependencies and
|
|
5
|
+
// hard-links its binary over the bin/xeno.exe placeholder, so `xeno` execs the
|
|
6
|
+
// native program directly with no Node or shell process in between. Same
|
|
7
|
+
// layout as Claude Code's npm wrapper. The photon wasm goes beside it because
|
|
8
|
+
// the image module looks for it next to the executable.
|
|
9
|
+
//
|
|
10
|
+
// If this never runs (`bun add -g` skips dependency scripts unless trusted),
|
|
11
|
+
// the placeholder is itself a POSIX sh launcher that finds the same binary.
|
|
12
|
+
// A failure here never fails the install: the placeholder still works.
|
|
13
|
+
//
|
|
14
|
+
// PLATFORMS must match scripts/binary-targets.ts; test/binary-release.test.ts
|
|
15
|
+
// enforces that.
|
|
16
|
+
|
|
17
|
+
const { spawnSync } = require("child_process");
|
|
18
|
+
const { copyFileSync, existsSync, linkSync, renameSync, unlinkSync, chmodSync } = require("fs");
|
|
19
|
+
const { arch } = require("os");
|
|
20
|
+
const path = require("path");
|
|
21
|
+
|
|
22
|
+
const PREFIX = "@visual-z/xeno";
|
|
23
|
+
const PLATFORMS = {
|
|
24
|
+
"darwin-arm64": { pkg: PREFIX + "-darwin-arm64", bin: "xeno" },
|
|
25
|
+
"darwin-x64": { pkg: PREFIX + "-darwin-x64", bin: "xeno" },
|
|
26
|
+
"linux-arm64": { pkg: PREFIX + "-linux-arm64", bin: "xeno" },
|
|
27
|
+
"linux-x64": { pkg: PREFIX + "-linux-x64", bin: "xeno" },
|
|
28
|
+
"linux-arm64-musl": { pkg: PREFIX + "-linux-arm64-musl", bin: "xeno" },
|
|
29
|
+
"linux-x64-musl": { pkg: PREFIX + "-linux-x64-musl", bin: "xeno" },
|
|
30
|
+
"win32-arm64": { pkg: PREFIX + "-win32-arm64", bin: "xeno.exe" },
|
|
31
|
+
"win32-x64": { pkg: PREFIX + "-win32-x64", bin: "xeno.exe" },
|
|
32
|
+
};
|
|
33
|
+
const WASM = "photon_rs_bg.wasm";
|
|
34
|
+
|
|
35
|
+
function isMusl() {
|
|
36
|
+
if (process.platform !== "linux") return false;
|
|
37
|
+
// glibcVersionRuntime is absent on musl; ld-musl is the fallback when report is unavailable (Bun).
|
|
38
|
+
const report = typeof process.report?.getReport === "function" ? process.report.getReport() : null;
|
|
39
|
+
if (report?.header && "glibcVersionRuntime" in report.header) return false;
|
|
40
|
+
if (report?.header) return true;
|
|
41
|
+
return ["/lib/ld-musl-x86_64.so.1", "/lib/ld-musl-aarch64.so.1"].some(file => existsSync(file));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function platformKey() {
|
|
45
|
+
let cpu = arch();
|
|
46
|
+
// An x64 Node under Rosetta on Apple Silicon: prefer the native arm64 build.
|
|
47
|
+
if (process.platform === "darwin" && cpu === "x64") {
|
|
48
|
+
const translated = spawnSync("sysctl", ["-n", "sysctl.proc_translated"], { encoding: "utf8" });
|
|
49
|
+
if (translated.stdout?.trim() === "1") cpu = "arm64";
|
|
50
|
+
}
|
|
51
|
+
return `${process.platform}-${cpu}${isMusl() ? "-musl" : ""}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Hard link first: instant and no second copy of a ~90 MB file. Copy across filesystems.
|
|
55
|
+
function place(source, dest) {
|
|
56
|
+
const temp = dest + ".tmp-" + process.pid;
|
|
57
|
+
try { linkSync(source, temp); } catch { copyFileSync(source, temp); }
|
|
58
|
+
// rename replaces atomically on POSIX, so the placeholder is never missing; Windows refuses to rename over a file.
|
|
59
|
+
if (process.platform === "win32") { try { unlinkSync(dest); } catch { /* nothing to replace */ } }
|
|
60
|
+
try { renameSync(temp, dest); }
|
|
61
|
+
catch (error) { try { unlinkSync(temp); } catch { /* already gone */ } throw error; }
|
|
62
|
+
if (process.platform !== "win32") chmodSync(dest, 0o755);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function main() {
|
|
66
|
+
const key = platformKey(), info = PLATFORMS[key];
|
|
67
|
+
if (!info) {
|
|
68
|
+
console.error(`[xeno postinstall] Unsupported platform: ${key}. Supported: ${Object.keys(PLATFORMS).join(", ")}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let dir;
|
|
72
|
+
try { dir = path.dirname(require.resolve(info.pkg + "/package.json", { paths: [__dirname] })); }
|
|
73
|
+
catch {
|
|
74
|
+
console.error(`[xeno postinstall] ${info.pkg} is not installed (--omit=optional, or its download failed).`);
|
|
75
|
+
console.error(" Reinstall @visual-z/xeno to fetch it.");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
place(path.join(dir, info.bin), path.join(__dirname, "bin", "xeno.exe"));
|
|
80
|
+
if (existsSync(path.join(dir, WASM))) place(path.join(dir, WASM), path.join(__dirname, "bin", WASM));
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(`[xeno postinstall] Could not place the binary: ${error.message}`);
|
|
83
|
+
console.error(" xeno still starts through its launcher, one process slower.");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (require.main === module) main();
|
|
88
|
+
module.exports = { PLATFORMS, platformKey };
|
package/package.json
CHANGED
|
@@ -1,60 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visual-z/xeno",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
|
-
"type": "module",
|
|
6
5
|
"description": "Segmented append-only agent log with pure context and handoff projections",
|
|
7
6
|
"bin": {
|
|
8
|
-
"xeno": "
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"src",
|
|
12
|
-
"README.md",
|
|
13
|
-
"CHANGELOG.md",
|
|
14
|
-
"docs/install.md",
|
|
15
|
-
"docs/providers.md",
|
|
16
|
-
"docs/app-server.md",
|
|
17
|
-
"docs/foundations.md",
|
|
18
|
-
"docs/research/foundation-clients-2026-10-09.md",
|
|
19
|
-
"docs/research/foundation-editing-2026-10-09.md",
|
|
20
|
-
"docs/research/foundation-network-2026-10-09.md",
|
|
21
|
-
"docs/research/foundation-workflow-2026-10-09.md"
|
|
22
|
-
],
|
|
23
|
-
"engines": {
|
|
24
|
-
"bun": ">=1.3.0"
|
|
25
|
-
},
|
|
26
|
-
"repository": {
|
|
27
|
-
"type": "git",
|
|
28
|
-
"url": "git+https://github.com/visual-z/xeno.git"
|
|
7
|
+
"xeno": "bin/xeno.exe"
|
|
29
8
|
},
|
|
30
9
|
"scripts": {
|
|
31
|
-
"
|
|
32
|
-
"typecheck": "bun run scripts/typecheck.ts",
|
|
33
|
-
"check": "bun run scripts/check-boundaries.ts",
|
|
34
|
-
"gate": "bun test && bun run typecheck && bun run scripts/check-boundaries.ts",
|
|
35
|
-
"eval:test": "bun test ./eval/test",
|
|
36
|
-
"gate:full": "bun run gate && bun run eval:test",
|
|
37
|
-
"verify-red": "bun run scripts/verify-red.ts",
|
|
38
|
-
"regen-golden": "bun run scripts/regen-golden.ts",
|
|
39
|
-
"measure": "bun run scripts/measure-handoff.ts",
|
|
40
|
-
"agent": "bun run src/apps/cli.ts"
|
|
10
|
+
"postinstall": "node install.cjs"
|
|
41
11
|
},
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"@
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"@opentui/core": "0.5.14",
|
|
52
|
-
"@silvia-odwyer/photon-node": "0.3.4",
|
|
53
|
-
"ajv": "8.20.0",
|
|
54
|
-
"grok-mermaid": "0.2.3",
|
|
55
|
-
"highlight.js": "10.7.3",
|
|
56
|
-
"marked": "18.0.11"
|
|
12
|
+
"optionalDependencies": {
|
|
13
|
+
"@visual-z/xeno-darwin-arm64": "0.9.1",
|
|
14
|
+
"@visual-z/xeno-darwin-x64": "0.9.1",
|
|
15
|
+
"@visual-z/xeno-linux-arm64": "0.9.1",
|
|
16
|
+
"@visual-z/xeno-linux-x64": "0.9.1",
|
|
17
|
+
"@visual-z/xeno-linux-arm64-musl": "0.9.1",
|
|
18
|
+
"@visual-z/xeno-linux-x64-musl": "0.9.1",
|
|
19
|
+
"@visual-z/xeno-win32-arm64": "0.9.1",
|
|
20
|
+
"@visual-z/xeno-win32-x64": "0.9.1"
|
|
57
21
|
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin/xeno.exe",
|
|
24
|
+
"install.cjs",
|
|
25
|
+
"README.md",
|
|
26
|
+
"CHANGELOG.md"
|
|
27
|
+
],
|
|
58
28
|
"publishConfig": {
|
|
59
29
|
"access": "public"
|
|
60
30
|
}
|
package/docs/app-server.md
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# 会话控制接口与 TUI 工作台
|
|
2
|
-
|
|
3
|
-
状态:实验性 `xeno-control/0.1`。TUI 和适配器共用一个 `SessionControl`、一个实际 Session 和同一份 append-only 日志。协议借鉴 Codex App Server 的生命周期,**不声明与 Codex v2 wire format 兼容**。没有新增模型调用、第二个执行进程或独立目标数据库。
|
|
4
|
-
|
|
5
|
-
## 从源码使用
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bun run agent app-server schema
|
|
9
|
-
bun run agent app-server --model openai-codex/gpt-6-luna
|
|
10
|
-
bun run agent --control-socket /tmp/xeno-control-private/control.sock
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
第一条只打印版本、请求参数 schema、通知清单及限制,不加载模型凭证。第二条用 stdin/stdout 双向 JSONL;诊断在 stderr。启动会话仍采用原有的凭证、工具权限、`--session` / `--continue` 和 `--acceptance-file` 参数。提示从 `turn/start` 提交,不能作为位置参数。结构化模式不构造 TUI,也不发送 OSC。
|
|
14
|
-
|
|
15
|
-
第三条正常启动 TUI,Unix socket 连接到它当前的同一个会话。父目录必须由当前用户拥有且权限为 0700;不存在时自动创建,socket 为 0600。已有路径拒绝覆盖。这里没有 TCP、Web 面板或远程认证服务。每个适配器都是具有当前用户本地控制能力的客户端,可启动工具和答复审批。
|
|
16
|
-
|
|
17
|
-
## 初始化与恢复
|
|
18
|
-
|
|
19
|
-
每行一个 JSON 对象;省略 `jsonrpc`。请求必须有字符串或安全整数 `id`,响应返回相同 `id` 及 `result` 或 `error`。只有 `initialized` 是客户端无 id 通知。所有其他方法必须等初始化完成。
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{"id":1,"method":"initialize","params":{"clientInfo":{"name":"my-adapter","version":"0.1"}}}
|
|
23
|
-
{"method":"initialized"}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
读取 initialize 的 `result.threadId` 和 `result.streamId` 后,提交:
|
|
27
|
-
|
|
28
|
-
```json
|
|
29
|
-
{"id":2,"method":"thread/subscribe","params":{"threadId":"<returned-threadId>"}}
|
|
30
|
-
{"id":3,"method":"turn/start","params":{"threadId":"<returned-threadId>","input":"Inspect the failing test and report the evidence."}}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
通知可以早于对应请求响应,客户端应按 request id 关联响应。`thread/subscribe` 先订阅,再返回快照;应先缓存这期间的通知,拿到快照后只应用同一 streamId 且 sequence 大于快照 sequence 的通知。sequence 是控制器生命周期内递增的通知序号,包含瞬时输出,不能作为持久日志地址。
|
|
34
|
-
|
|
35
|
-
- `threadId` 是规范化绝对 session 目录路径的 SHA-256。同路径冷恢复保持身份;移动或复制目录会改变身份,不是可携带 UUID。
|
|
36
|
-
- `streamId` 每个活控制器生成一次。重启会变化;`turnId` 等于这一轮原始 user event ID;steering 引用这个请求,不另开目标。
|
|
37
|
-
- `item/completed` 在持久 append 成功后发送 `{node,id,type}`。完整事件通过 `item/read` 读取,唯一地址是 node + event id。
|
|
38
|
-
- 断线、序号跳跃或 streamId 改变:重新初始化、订阅,消费返回快照,再分页读 `item/list` / `item/read`。可给订阅传 `after:{streamId,sequence}`;游标与当前快照不同就返回 `resyncRequired:true`。
|
|
39
|
-
- 不保存、重放瞬时文本 delta,不重放命令。控制请求不具备幂等重试保证;丢失 `turn/start` 响应时先查看当前 turn 和日志,不能盲目重发。
|
|
40
|
-
- TUI 切换 Session 后,旧 threadId 拒绝继续控制,适配器应建立新连接重新初始化。stdio app-server 另外由 SessionHub 拥有多个 Session;每个 durable log 只有一个活执行者,path/basename/threadId 别名的并发冷恢复收敛到同一个拥有者。
|
|
41
|
-
|
|
42
|
-
## 方法与事件
|
|
43
|
-
|
|
44
|
-
`app-server schema` 输出的 `methods` 是实际入参验证器共用的 schema;目前不是所有响应类型的完整 JSON Schema/生成式 SDK。
|
|
45
|
-
|
|
46
|
-
| 方法 | 除 threadId 外的参数 | 结果 / 作用 |
|
|
47
|
-
|---|---|---|
|
|
48
|
-
| `thread/list` | 无 | 当前 workspace 的保存会话与活拥有者身份 |
|
|
49
|
-
| `thread/new` | 可选 name | 创建并返回独立会话快照 |
|
|
50
|
-
| `thread/resume` | session | 以当前 workspace 的 path/id/threadId 恢复并返回快照 |
|
|
51
|
-
| `thread/fork` | 可选 name | 从 idle thread 创建新日志,保留原始 ancestry 引用 |
|
|
52
|
-
| `thread/close` | 无 | 取消、等待原拥有者清理后关闭;日志保留 |
|
|
53
|
-
| `thread/mode` | mode | build/plan,在 idle 共享资源检查点切换 |
|
|
54
|
-
| `thread/read` | 无 | 当前目标、执行、进展、上下文和待审批快照 |
|
|
55
|
-
| `thread/subscribe` | 可选 after | 订阅通知并返回快照及 resyncRequired |
|
|
56
|
-
| `turn/start` | input | 开始唯一执行,返回 turnId;忙时拒绝 |
|
|
57
|
-
| `turn/steer` | turnId, input | 排队,在原有模型/工具边界消费;最多 32 项 |
|
|
58
|
-
| `turn/interrupt` | turnId | 取消并清理当前执行;完成由 turn/completed 确认 |
|
|
59
|
-
| `approval/respond` | turnId, approvalId, choice | once / command / tool / deny;过期身份拒绝 |
|
|
60
|
-
| `question/respond` | turnId, requestId, reply | reply 为 JSON 编码的结构化答案,按原问题/选择身份验证 |
|
|
61
|
-
| `acceptance/accept` | requestId, criterionId | 只在 idle 显式批准本请求已声明的人验条件 |
|
|
62
|
-
| `context/read` | focus,可选 offset / limit | messages / omitted / history 来源分页,不改模型输入 |
|
|
63
|
-
| `item/list` | 可选 after:{node,event} / limit | 当前活动路径的日志身份分页 |
|
|
64
|
-
| `item/read` | node, event | 当前活动路径上的完整日志事件 |
|
|
65
|
-
|
|
66
|
-
分页 limit 为 1–100,默认 50。切换路径后旧游标可能失效,应重新获取快照。完整单条事件超过帧上限会报错;此版本不提供大事件分块下载。
|
|
67
|
-
|
|
68
|
-
通知包括 `turn/started`、`turn/event`(原有 LoopEvent 的瞬时进展)、`item/completed`、`turn/completed`、`turn/error`、`turn/steeringQueued`、`approval/request`、`approval/resolved`、`question/request`、`question/resolved`、`thread/statusChanged`。每条带 threadId / streamId / sequence,活动 turn 存在时带 turnId。question 请求及答复按原始 turn、tool call、question 和 choice 身份关联;重连快照包含尚未回答的问题。`turn/completed.steeringUndelivered` 明确没有消费的排队输入;客户端不能将“已入队”显示为“已执行”。provider 抛错时仍从持久日志读取 outcome,错误通知不透出原始 provider 报文。
|
|
69
|
-
|
|
70
|
-
日志是事实来源。观察者得到独立副本,修改或抛错不能改变执行。刷新 idle 快照沿原有验收观察边界重新检查工作区,可能追加失效证据;这不提交提示或调用模型。活动目标和快照游标采用同一个已发布事件边界;切段期间无法一致读取时返回刷新错误。
|
|
71
|
-
|
|
72
|
-
## 审批、断连与限制
|
|
73
|
-
|
|
74
|
-
审批是同一个权限请求;TUI 或适配器答复后另一端的待审批状态同时结束。取消清理审批承诺,不允许晚到 provider 响应覆盖取消状态或继续执行工具。stdio 是独立会话的主控制连接:EOF/关闭会拒绝审批并取消执行。Unix socket 客户端断开只撤掉该观察者,TUI 继续拥有当前审批与执行。
|
|
75
|
-
|
|
76
|
-
输入单帧上限 1 MiB,每连接最多排队 32 请求,输出缓冲上限 2 MiB,socket 最多 32 客户端,SessionHub 最多 32 个活会话(包含尚未完成的打开请求);这些是容量假设,不是模型策略阈值。超限断开或返回有界错误。错误码:`-32600` envelope、`-32601` 未知方法、`-32602` 参数、`-32700` JSON、`-32000` 生命周期/执行冲突、`-32001` 传输容量、`-32002` 响应过大。快照本身过大时使用分页 inspector;超大目标详情需要后续协议扩展。
|
|
77
|
-
|
|
78
|
-
## 类型化客户端与 ACP
|
|
79
|
-
|
|
80
|
-
源码客户端 `src/runtime/control-client.ts` 验证发送参数、响应 envelope、方法结果与通知身份;限制帧、在途请求和超时,不自动重发请求。适配器负责接入字节流并在 EOF 调用 close:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { ControlClient } from "./src/runtime/control-client.ts";
|
|
84
|
-
|
|
85
|
-
const client = new ControlClient(line => transport.write(line), { close: () => transport.close() });
|
|
86
|
-
transport.onText(text => client.feed(text));
|
|
87
|
-
transport.onEnd(() => client.close());
|
|
88
|
-
const initial = await client.initialize("my-adapter", "0.1");
|
|
89
|
-
const other = await client.request("thread/new", { name: "Investigation" });
|
|
90
|
-
const unsubscribe = client.onNotice(notice => render(notice), other.threadId);
|
|
91
|
-
const subscription = await client.request("thread/subscribe", { threadId: other.threadId });
|
|
92
|
-
await client.request("thread/mode", { threadId: other.threadId, mode: "plan" });
|
|
93
|
-
await client.request("turn/start", { threadId: other.threadId, input: "检查实现并列出证据" });
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
transport/render 为适配器自行提供的接口;订阅期间仍需使用上述 snapshot/sequence 恢复规则。respondQuestion 便利方法接收完整 QuestionReply,包含 request_id、turn_id 与按稳定 id 回答的 answers;外层请求同样指定 threadId、turnId、requestId。
|
|
97
|
-
|
|
98
|
-
`bun run agent acp --agent build` 提供官方 ACP SDK 的 stdio JSON-RPC 入口,与 xeno-control 的 wire format 分开。支持 initialize、new/load session、prompt/cancel、Plan/Build 模式、文本与工具进展、客户端权限请求及其 MCP 配置。所有 session 固定在启动 workspace,外部 cwd 具名拒绝;load 不发送模型提示。支持 elicitation 的客户端可以回答 question,否则工具返回不可用。stdout 只含协议,诊断走 stderr;EOF 取消并等待所有正在打开和活跃会话清理。此入口沿用现有配置与权限,不自动安装模型、MCP 或语言服务器。
|
|
99
|
-
|
|
100
|
-
## TUI 与终端状态
|
|
101
|
-
|
|
102
|
-
常驻 Goal 区展示原始目标、验收状态、执行状态和观察/重试数。`/control` 在右侧栏打开同一会话的面板,保留底部输入框和草稿;窄窗口改为消息区内的右侧抽屉,尺寸不足时提示放大。F6 切换面板与编辑器焦点,Esc 回到编辑器并保留面板,Q 关闭并恢复状态侧栏。面板有焦点时,Tab 切 Goal / Progress / Context Lens,左右键切上下文来源/省略事件/handoff 恢复引用,上下键或 PageUp/PageDown 翻阅,R 刷新,I 取消,A 选择当前声明的人验条件;其它文字输入会回到原编辑器。长目标和证据换行显示,缩放保留页签、滚动和草稿。
|
|
103
|
-
|
|
104
|
-
远程开始的普通 turn 会更新当前 TUI,并可在面板取消。TUI 输入的 steering 在同一 turn 的原有边界消费,followup 等原 turn 释放后执行;远程取消也把未发送内容归还编辑器。既有隔离 skill / shell 保留各自执行入口,当前协议不新增远程 skill/shell 方法。
|
|
105
|
-
|
|
106
|
-
无验收合同保持 `unverified`;模型结束 `model_end` 不等于目标 `verified`。Progress 的观察、产物、验收、新诊断和原样重试均带日志来源;数量不是完成百分比。Context Lens 复用实际 dispatch 的投影,只过滤检查视图,不修改 frozen prefix、handoff 或消息。
|
|
107
|
-
|
|
108
|
-
OSC 7501 遵循 [Program Status Protocol](https://www.superlogical.com/rex/docs/build/program-status) 的状态、身份及 UTF-8 base64 消息语法:
|
|
109
|
-
|
|
110
|
-
- `XENO_PROGRAM_STATUS=auto`(默认):TTY 探测成功后才发送状态;未回复时只有一次探测,不发送报告。
|
|
111
|
-
- `XENO_PROGRAM_STATUS=1`:显式开启;`0`:关闭。管道始终关闭;auto 在 tmux/screen 内关闭,可用 1 显式覆盖。
|
|
112
|
-
- running → working,审批/认证/提问 → blocked + kind,取消 → idle,失败 → error。结束使用 done,同时固定消息明确是否通过目标合同;待人验保持 blocked。
|
|
113
|
-
- 不发送用户提示、模型输出、凭证或假百分比。每进程只操作自己的 `xeno-<pid>` 记录;退出清理瞬时记录,保留规范要求可留存的 done/error。
|
|
114
|
-
|
|
115
|
-
自动验证包含真实 TUI、真实 Unix socket、CLI JSONL 与 PTY 探测;不等同于作者在所有终端上的视觉验收。配对实验及真实历史语料统计见[研究报告](research/session-control-evaluation-2026-10-08.md)。
|
package/docs/foundations.md
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# 基础工作流
|
|
2
|
-
|
|
3
|
-
保留 `coding` 的十工具默认配置与老会话能力边界。新建会话选择 `--agent build`、`--agent plan` 或 `--tool-profile foundation`,启用 question、apply_patch、diff、webfetch、websearch、format,以及配置存在时的 lsp。`--tools` 仍为严格白名单,`--no-tools` 不被模式或角色自动覆盖。
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
bun run agent --agent build "实现并验证这个功能"
|
|
7
|
-
bun run agent --agent plan "先检查实现并提出计划"
|
|
8
|
-
bun run agent --tool-profile foundation "读取网站并核对项目"
|
|
9
|
-
bun run agent --output-schema result.schema.json --output-last-message result.json -p "返回符合 schema 的 JSON"
|
|
10
|
-
bun run agent review branch main
|
|
11
|
-
bun run agent acp --agent build
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## 模式与角色
|
|
15
|
-
|
|
16
|
-
`/plan` 与 `/build` 在 idle 时切换,改变真实工具准入和冻结前缀,追加检查点。Plan 允许 read 与 harness 的 note/question,不执行 shell、写文件或任意扩展代码。它是能力边界,沿用 xeno 既有的无 OS sandbox 设计。明确的工具白名单和配置 deny 保持有效。
|
|
17
|
-
|
|
18
|
-
`/agent` 列出角色,`/agent <name>` 选择。内置 build/plan/reviewer;用户文件为 `~/.xeno/agents.json`,已信任项目可用 `.xeno/agents.json`。`XENO_CONFIG_DIR` 改变用户配置目录。低到高为内置、用户、项目;相同角色按整个字段覆盖,不拼接半份 tools/model。明确 CLI 参数优先,模型、thinking、权限、说明和预算共同应用于一个检查点。失败保留旧配置;冷启动保存角色名称,按当前文件及项目信任重新解析。缺失或撤销信任的项目角色具名报错。
|
|
19
|
-
|
|
20
|
-
```json
|
|
21
|
-
{
|
|
22
|
-
"profiles": [{
|
|
23
|
-
"name": "investigator",
|
|
24
|
-
"description": "检查实际证据并提出方案",
|
|
25
|
-
"mode": "plan",
|
|
26
|
-
"instructions": "以仓库和工具回执为依据,指出未知项。",
|
|
27
|
-
"tools": { "profile": "foundation", "exclude": ["websearch"] },
|
|
28
|
-
"permissions": [{ "action": "deny", "tool": "read", "paths": ["private/**"] }],
|
|
29
|
-
"budget": { "maxTurns": 20, "timeBudgetMs": 60000 }
|
|
30
|
-
}]
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
maxTurns 为硬限制;timeBudgetMs 沿用剩余时间提示语义,不是强制截止。结构化 question 最多三个问题,有稳定 question/choice id,支持单选、多选、自定义文字。TUI、控制客户端或支持 elicitation 的 ACP 客户端答复;缺少答复入口时返回不可用,取消与晚到答复不能串到下一次调用。
|
|
35
|
-
|
|
36
|
-
## 工具配置
|
|
37
|
-
|
|
38
|
-
用户 `~/.xeno/foundation.json` 与已信任项目 `.xeno/foundation.json` 的同名顶层字段整体替换。配置允许五个字段:mcp、webSearch、formatters、lsp、permissions。未知字段或无效 schema 在发布资源前报错。配置命令不会自动安装可执行文件。
|
|
39
|
-
|
|
40
|
-
```json
|
|
41
|
-
{
|
|
42
|
-
"mcp": {
|
|
43
|
-
"local": { "transport": "stdio", "command": "my-mcp-server", "args": [], "timeoutMs": 10000 },
|
|
44
|
-
"remote": { "transport": "http", "url": "https://example.com/mcp", "oauth": true }
|
|
45
|
-
},
|
|
46
|
-
"webSearch": { "provider": "brave", "apiKeyEnv": "BRAVE_API_KEY" },
|
|
47
|
-
"formatters": [{ "name": "prettier", "extensions": [".ts", ".tsx"], "command": ["prettier", "--write", "$FILE"] }],
|
|
48
|
-
"lsp": [{ "name": "typescript", "command": ["typescript-language-server", "--stdio"], "extensions": [".ts", ".tsx"], "languageId": "typescript" }],
|
|
49
|
-
"permissions": [
|
|
50
|
-
{ "action": "deny", "tool": "*", "paths": ["private/**"] },
|
|
51
|
-
{ "action": "allow", "tool": "exec_command", "commandPrefix": ["git", "status"] }
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
这些命令是假定已安装工具的配置示例。可在 `/reload` 后应用,角色/模式切换同样走资源拥有者。解析、发现和模型选择先完成;只有旧 integration 完成清理才发布新检查点。staging 的协议握手可能短暂存在,但业务调用仍只有已发布的执行拥有者;失败丢弃新资源,不重放旧调用。
|
|
57
|
-
|
|
58
|
-
权限保持首匹配规则;配置 deny 优先于会话记忆的批准。路径匹配归一化真实资源,包括 symlink 指向;read 的资源判定也适用于 query、搜索、diff 和 LSP。grep/find/ls 在读取内容前过滤资源。`.env`、`.env.*` 默认请求批准,`.env.example` 保持普通读取。commandPrefix 只匹配完整的字面 argv 前缀,组合 shell、重定向或插值不会借此前缀批准整个程序。
|
|
59
|
-
|
|
60
|
-
## 联网与 MCP
|
|
61
|
-
|
|
62
|
-
webfetch 参数为 `{url,format?,timeout?}`,format 可为 markdown/text/html,timeout 为 1–120 秒。流式响应受 5 MiB 限额,逐跳验证重定向;原始内容存观察工件,提取的正文是可重算投影。websearch 参数为 `{query,count?}`,只使用明确配置的 Brave 或 Exa;未配置或无密钥时直接说明不可用。`--offline` 禁止这些工具的网络请求与 HTTP MCP 自动连接。
|
|
63
|
-
|
|
64
|
-
`/mcp`、`/mcp status` 查看状态,`/mcp login <server>` 显式发起 OAuth,`/mcp logout <server>` 清理凭据。HTTP 也可用 bearerTokenEnv 或 headersEnv;密钥保存在环境或私有凭据存储,不写到模型参数和日志。OAuth 使用 PKCE、state、issuer 与 loopback callback。授权/刷新在业务请求前或用户修复时进行,401/403 不自动重放业务调用。
|
|
65
|
-
|
|
66
|
-
MCP 使用官方客户端的 stdio/Streamable HTTP;按 server capabilities 发布 tools、resources 和 prompts。工具经现有 tool_search 延迟发现、权限检查与 broker 执行。注解不是只读证据,Plan 不执行 MCP 工具。完整 JSON Schema 在发现时编译和冻结,无效参数在远程业务调用之前拒绝;未知关键字、引用或格式需修复配置。HTTP session 关闭会发送有界 DELETE,stdio 进程由客户端清理。
|
|
67
|
-
|
|
68
|
-
## 编辑、格式化、目录规范
|
|
69
|
-
|
|
70
|
-
apply_patch 参数为 `{patchText,expected_sha256?}`,语法使用 `*** Begin Patch` / `*** Add File:` / `*** Update File:` / `*** Move to:` / `*** Delete File:` / `*** End Patch`。更新和删除需要先读到实际版本,或提供路径到 SHA-256 的 expected_sha256 映射;只准备新文件时无需旧版本。多文件全部预检,提交使用现有 CAS 和补偿回滚,保留 BOM、换行与权限;`/back ... files` 复用真实检查点。
|
|
71
|
-
|
|
72
|
-
format 参数为 `{paths:[...]}`,只执行配置中的 literal argv;`$FILE` 替换为绝对路径。每条命令经真实拥有者、审批、退出码与检查点执行,不会在 edit 后暗中格式化。读到新的文件版本后再生成后续编辑。
|
|
73
|
-
|
|
74
|
-
启动从 Git 根到 cwd 加载目录规范。首次碰到目标文件的更深层 AGENTS.md / AGENTS.override.md 时:read / query / lsp 照常执行,规范(带来源和 scope)附在同一个结果之后;write / edit / apply_patch / format 先返回指令回执,原操作未执行,模型读到后可显式重试。同一批调用里一份规范只下发一次,后到的修改只指向先附上规范的那次调用。规范追加到原始日志并按内容指纹去重,保留冻结前缀和旧事件。
|
|
75
|
-
|
|
76
|
-
## Diff、Review 与 LSP
|
|
77
|
-
|
|
78
|
-
`/diff [working|last-turn|branch <base>|commit <ref>]` 查看 diff。`/review-code` 与 `xeno review` 用相同范围创建独立只读 review Session,主对话不进入 review 模型输入,主会话获得指向独立日志和不可变 premise 的回执。`/review` 仍可用于原有用户提示模板/skill,避免占名。Git 禁止 ext-diff/textconv,不改作者 index。last-turn 依据原始 applied checkpoint;未捕获的 shell/外部变化明确列为未知。
|
|
79
|
-
|
|
80
|
-
lsp 参数为 `{action,path,line?,character?}`;action 为 diagnostics、definition、references、hover,位置使用零起点行号与 UTF-16 character。请求前读取实际文件并发 didOpen/didChange。诊断包含 current/stale/unversioned 等新鲜度,不把没有版本的缓存当成最新事实。取消初始化会清理进程;普通请求取消只发对应 cancelRequest。服务器 applyEdit 明确拒绝,写入须经 Patch 拥有者。
|
|
81
|
-
|
|
82
|
-
## JSON 输出与客户端
|
|
83
|
-
|
|
84
|
-
--output-schema 支持 draft-07(默认)、2019-09、2020-12 及标准 formats;不 coercion、不填默认值、不删除额外字段。未知 schema 语义启动失败。最终输出须为纯 JSON,验证失败留下 execution_error,print stdout 不发布无效答案,CLI 退出 1;--output-last-message 仅保存完成后的最终答案。日志与 JSON 事件流仍保留实际响应和最终失败事实。
|
|
85
|
-
|
|
86
|
-
多会话控制、类型化客户端与标准 ACP 的入口、恢复、权限、提问及容量限制见 [app-server.md](app-server.md)。本地 fake 模型、真实协议子进程与 PTY 验证不等同于付费供应商、外部生产服务器或作者终端的人工验收。
|
|
87
|
-
|
|
88
|
-
设计依据:[联网/MCP](research/foundation-network-2026-10-09.md)、[工作流/权限/LSP](research/foundation-workflow-2026-10-09.md)、[编辑/Review/ACP](research/foundation-editing-2026-10-09.md)、[客户端与输出](research/foundation-clients-2026-10-09.md)。
|
package/docs/install.md
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
# Install xeno
|
|
2
|
-
|
|
3
|
-
Published as `@visual-z/xeno`. The license is `UNLICENSED`: the package is
|
|
4
|
-
public to read and install, and no right to reuse the code is granted.
|
|
5
|
-
|
|
6
|
-
```bash
|
|
7
|
-
npm i -g @visual-z/xeno # or: bun add -g @visual-z/xeno
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
The installed `xeno` still runs with Bun (below). Installing from a
|
|
11
|
-
checkout works the same way and is described after it.
|
|
12
|
-
|
|
13
|
-
## Bun, not Node
|
|
14
|
-
|
|
15
|
-
The entry point is `src/apps/cli.ts` with `#!/usr/bin/env bun`. The
|
|
16
|
-
process uses Bun APIs (`Bun.file`, `Bun.spawn`, `Bun.spawnSync`,
|
|
17
|
-
`for await (const line of console)`). Those are why the runtime is Bun.
|
|
18
|
-
|
|
19
|
-
`engines.bun` is `>=1.3.0` (required by the OpenTUI renderer, D20). This checkout was run on **Bun 1.3.10**.
|
|
20
|
-
Node is untested. That is a fact about this tree, not a promise that
|
|
21
|
-
Node support is coming.
|
|
22
|
-
|
|
23
|
-
Install Bun from https://bun.sh.
|
|
24
|
-
|
|
25
|
-
## From a checkout
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
git clone <this-repo> xeno
|
|
29
|
-
cd xeno
|
|
30
|
-
bun install
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
`bun install` pulls the provider SDKs, OpenTUI and its platform renderer,
|
|
34
|
-
Markdown, syntax highlighting, Mermaid, Photon image processing, and TypeScript tooling.
|
|
35
|
-
The exact versions are in `package.json` and `bun.lock`.
|
|
36
|
-
|
|
37
|
-
OpenTUI supplies the native renderer through its platform dependencies.
|
|
38
|
-
Clipboard integration uses terminal OSC 52 and platform commands; the old
|
|
39
|
-
vendored Pi native helpers are no longer packaged. Release package checks run
|
|
40
|
-
on macOS arm64; they do not establish Linux or Windows device acceptance.
|
|
41
|
-
|
|
42
|
-
Run the CLI without linking:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
bun src/apps/cli.ts --help
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Or put `xeno` on your PATH from this checkout:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
bun link
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Then, in any directory:
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
xeno --help
|
|
58
|
-
xeno --list-models
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
`bun link` writes a shim that executes the `bin` field
|
|
62
|
-
(`src/apps/cli.ts`) with Bun. It does not copy the tree.
|
|
63
|
-
|
|
64
|
-
Each invocation starts a new session. `xeno -c` continues the newest one;
|
|
65
|
-
`xeno -r` opens a picker. `--fresh` is a compatibility alias for the default,
|
|
66
|
-
and nothing is deleted. Resume restores the saved model. An explicit
|
|
67
|
-
`--model` switches at a checkpoint while keeping the original log intact.
|
|
68
|
-
|
|
69
|
-
Startup loads resources and opens or restores the session. Workspace snapshots
|
|
70
|
-
are deferred until file tools need them, so opening an editor does not scan the
|
|
71
|
-
whole project. Slow initialization shows its current stage; Ctrl+C cancels it
|
|
72
|
-
and restores the terminal. Start inside the intended project or pass
|
|
73
|
-
`--workspace <path>`.
|
|
74
|
-
|
|
75
|
-
## Updates
|
|
76
|
-
|
|
77
|
-
xeno says when a newer version is published. It never installs one on its
|
|
78
|
-
own: the notice names the command. Typing `/update` is how you ask it to
|
|
79
|
-
install (below).
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
xeno 0.4.0 is available (you have 0.3.0)
|
|
83
|
-
bun add -g @visual-z/xeno@latest
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
The command follows where this copy is installed: `bun add -g` under
|
|
87
|
-
`~/.bun/install/global/`, `npm i -g` under an npm global prefix
|
|
88
|
-
(`…/lib/node_modules/`, or `…\npm\node_modules\` on Windows). Anywhere else
|
|
89
|
-
the notice points to this file. A checkout updates with `git pull`.
|
|
90
|
-
|
|
91
|
-
To update now, type `/update` in the TUI. It checks the registry and, when
|
|
92
|
-
a newer release exists and xeno was installed with bun or npm, runs the
|
|
93
|
-
command from the notice pinned to that exact version (for example
|
|
94
|
-
`bun add -g @visual-z/xeno@0.7.1`). The status line shows the target version,
|
|
95
|
-
elapsed time against a 3-minute limit, and the package manager's latest output
|
|
96
|
-
line; the editor stays usable. Success says `Updated xeno A → B. Restart xeno
|
|
97
|
-
to use it.` — the running session keeps the old code until you restart. A
|
|
98
|
-
failure says why (exit code or timeout, with the package manager's last lines)
|
|
99
|
-
and repeats the command to run yourself. An unwritable install directory is
|
|
100
|
-
refused before anything runs. Other install locations and checkouts are never
|
|
101
|
-
installed into; they get the notice or `git pull` advice.
|
|
102
|
-
|
|
103
|
-
To check without installing:
|
|
104
|
-
|
|
105
|
-
```sh
|
|
106
|
-
xeno update --check
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
The explicit check bypasses the daily cache, `updateCheck: false`, the
|
|
110
|
-
automatic-check environment switches, and CI suppression. It reports the
|
|
111
|
-
current version and the result, including a failed query; a stale cache is
|
|
112
|
-
never presented as a successful fresh check. A successful query refreshes
|
|
113
|
-
the same cache used by startup. Repeated checks while a request is running
|
|
114
|
-
share that request. `xeno update --check` never installs, and needs no model
|
|
115
|
-
credential or session.
|
|
116
|
-
|
|
117
|
-
`--offline` / `XENO_OFFLINE` still prevent network access. Source checkouts
|
|
118
|
-
explain that they update with `git pull` instead of querying npm. Bare
|
|
119
|
-
`xeno update` and `xeno update --extensions` retain their existing extension
|
|
120
|
-
package behavior; do not combine `--check` with package sources, `--local`
|
|
121
|
-
or `--extensions`.
|
|
122
|
-
|
|
123
|
-
- **Request.** `GET https://registry.npmjs.org/-/package/@visual-z%2fxeno/dist-tags`
|
|
124
|
-
(an 18-byte answer). If that fails, `GET …/@visual-z%2fxeno/latest`.
|
|
125
|
-
`npm_config_registry` replaces the host. The timeout is 3 seconds.
|
|
126
|
-
- **What the registry learns.** Your IP address, the time, the package name
|
|
127
|
-
and Bun's default `User-Agent` (`Bun/<version>`). No identifier, no query
|
|
128
|
-
string, nothing from your session.
|
|
129
|
-
- **How often automatically.** At most once every 24 hours. The time and the version seen
|
|
130
|
-
are kept in `~/.xeno/update-check.json`. A failed attempt is recorded too,
|
|
131
|
-
so a closed network is not retried on every start.
|
|
132
|
-
- **When.** In the background after the editor opens. Startup never waits for
|
|
133
|
-
it, and quitting cancels it. A version found during a session is shown only
|
|
134
|
-
while that session is still empty. Otherwise it waits for the next start,
|
|
135
|
-
so it never interrupts a turn.
|
|
136
|
-
|
|
137
|
-
Background checks send nothing when any of these holds (the explicit manual
|
|
138
|
-
check described above is a separate action):
|
|
139
|
-
|
|
140
|
-
- `--offline` or `XENO_OFFLINE=1`
|
|
141
|
-
- `XENO_NO_UPDATE_CHECK` or `NO_UPDATE_NOTIFIER` is set (to anything but empty, `0` or `false`)
|
|
142
|
-
- `"updateCheck": false` in `settings.json` (*Check for updates* in `/settings`)
|
|
143
|
-
- `CI` or `CONTINUOUS_INTEGRATION` is set, by the same rule
|
|
144
|
-
- the run is not the interactive app: `-p`, `--mode json`, `--export`, `--list-models`, `models --refresh`, package and `config` commands, `--version`
|
|
145
|
-
- xeno runs from a checkout: its package root is not under `node_modules`, or has a `.git` (`bun src/apps/cli.ts`, `bun run agent`, `bun link`)
|
|
146
|
-
|
|
147
|
-
## ripgrep
|
|
148
|
-
|
|
149
|
-
Agents reach for `rg` in shell commands, and xeno's grep tool is faster with
|
|
150
|
-
it. When neither `PATH` nor `~/.xeno/bin` has one, the interactive app
|
|
151
|
-
installs ripgrep 14.1.1 into `~/.xeno/bin/rg` in the background:
|
|
152
|
-
|
|
153
|
-
- **Only that build.** The archive comes from the ripgrep GitHub release and
|
|
154
|
-
must match a sha256 pinned in xeno (`src/core/ripgrep-release.ts`).
|
|
155
|
-
Anything else is discarded before extraction; only the `rg` executable is
|
|
156
|
-
unpacked.
|
|
157
|
-
- **Yours wins.** `~/.xeno/bin` is appended to the end of the PATH of tool
|
|
158
|
-
commands, so an `rg` you install yourself is used instead.
|
|
159
|
-
- **What the model is told.** The session's environment section says whether
|
|
160
|
-
`rg` exists in the shell at session start. A copy that finishes
|
|
161
|
-
downloading during the first session appears in the next one's line, but
|
|
162
|
-
shell commands can use it immediately.
|
|
163
|
-
- **When not.** The same conditions as background update checks, except the
|
|
164
|
-
update settings: `--offline` / `XENO_OFFLINE`, `CI` /
|
|
165
|
-
`CONTINUOUS_INTEGRATION`, a non-interactive run, or running from a
|
|
166
|
-
checkout. `XENO_NO_TOOL_INSTALL` turns off only this download. Quitting
|
|
167
|
-
cancels it.
|
|
168
|
-
|
|
169
|
-
Platforms: macOS arm64 and x64, Linux x64 (static musl) and arm64 (glibc).
|
|
170
|
-
Elsewhere grep uses its built-in TypeScript search.
|
|
171
|
-
|
|
172
|
-
## Credentials
|
|
173
|
-
|
|
174
|
-
Resolution order, first match wins:
|
|
175
|
-
|
|
176
|
-
1. `--api-key`
|
|
177
|
-
2. `~/.xeno/auth.json` (created `0600` by `/login`)
|
|
178
|
-
3. the model or provider `apiKey` in `~/.xeno/models.json`
|
|
179
|
-
4. the provider's environment variable
|
|
180
|
-
|
|
181
|
-
A stored entry owns that provider. The environment is not a fallback
|
|
182
|
-
after a stored key fails.
|
|
183
|
-
|
|
184
|
-
| Provider | Environment variable |
|
|
185
|
-
|-------------|-----------------------------------------------------------|
|
|
186
|
-
| anthropic | `ANTHROPIC_API_KEY` |
|
|
187
|
-
| openai | `OPENAI_API_KEY` |
|
|
188
|
-
| google | `GOOGLE_API_KEY` or `GOOGLE_GENERATIVE_AI_API_KEY` or `GEMINI_API_KEY` |
|
|
189
|
-
| deepseek | `DEEPSEEK_API_KEY` |
|
|
190
|
-
| xai | `XAI_API_KEY` |
|
|
191
|
-
| groq | `GROQ_API_KEY` |
|
|
192
|
-
| cerebras | `CEREBRAS_API_KEY` |
|
|
193
|
-
| mistral | `MISTRAL_API_KEY` |
|
|
194
|
-
| openrouter | `OPENROUTER_API_KEY` |
|
|
195
|
-
| zai | `ZHIPU_API_KEY` |
|
|
196
|
-
| moonshotai | `MOONSHOT_API_KEY` |
|
|
197
|
-
| together | `TOGETHER_API_KEY` |
|
|
198
|
-
|
|
199
|
-
Interactive: export one of those, or run `/login <provider>`.
|
|
200
|
-
`-p` / no tty: pass `--api-key` or export the variable. `/login` is
|
|
201
|
-
not a script path.
|
|
202
|
-
|
|
203
|
-
`/login claude-pro`, `/login codex`, and `/login github-copilot` start
|
|
204
|
-
subscription flows (authorization-code + PKCE, or a device code for
|
|
205
|
-
Copilot). They use first-party client credentials; the terms-of-service
|
|
206
|
-
risk is on your account. Those flows have been tested against injected
|
|
207
|
-
transports, not against a live authorization endpoint.
|
|
208
|
-
|
|
209
|
-
## What a run writes
|
|
210
|
-
|
|
211
|
-
In the **workspace**:
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
.xeno/sessions/<id>/ node-NNNN.jsonl, handoff-NNNN.yaml, manifest
|
|
215
|
-
.xeno/blobs/ content-addressed snapshots for /back
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
That directory grows. There is no garbage collection.
|
|
219
|
-
|
|
220
|
-
In **your home directory** (`~/.xeno/`, or `$XENO_CONFIG_DIR`):
|
|
221
|
-
|
|
222
|
-
```
|
|
223
|
-
auth.json credentials (0600)
|
|
224
|
-
settings.json theme, thinking, defaults
|
|
225
|
-
trust.json which directories may load project settings
|
|
226
|
-
models.json optional user provider/model configuration
|
|
227
|
-
models-cache.json generated catalog cache (written by `xeno models --refresh`)
|
|
228
|
-
update-check.json when the last update check ran, and the newest version it saw
|
|
229
|
-
keybindings.json optional
|
|
230
|
-
prompts/ skills/ optional
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
A leftover `.xeno/log` from before named sessions is not moved. Continue
|
|
234
|
-
it with `--log .xeno/log`.
|
|
235
|
-
|
|
236
|
-
Add this to the project's `.gitignore`:
|
|
237
|
-
|
|
238
|
-
```
|
|
239
|
-
.xeno/
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## Untrusted work
|
|
243
|
-
|
|
244
|
-
There is no sandbox. See the Isolation section in `README.md`.
|