@visual-z/xeno 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/core/progress.ts +25 -0
- package/src/runtime/oauth.ts +1 -1
- package/src/runtime/tools.ts +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ is ever summarized by a model, and nothing is ever rewritten in place.
|
|
|
17
17
|
messages[] frozen system prefix + handoff + this node's events
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Version **0.1.
|
|
20
|
+
Version **0.1.3**. The on-disk session format will still change; `0.x` is that
|
|
21
21
|
statement. Published as `@visual-z/xeno`; the license is `UNLICENSED` (readable and installable, no reuse granted).
|
|
22
22
|
|
|
23
23
|
## Install
|
package/package.json
CHANGED
package/src/core/progress.ts
CHANGED
|
@@ -27,6 +27,12 @@ function hasUnseenLines(requested: readonly LineRange[], observed: readonly Line
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* A file version's fingerprint in the observation set. Keyed by digest alone:
|
|
32
|
+
* the same bytes under another path are not new work either.
|
|
33
|
+
*/
|
|
34
|
+
const versionKey = (_path: string, sha256: string): string => `version:${sha256}`;
|
|
35
|
+
|
|
30
36
|
export function deriveProgress(
|
|
31
37
|
previous: readonly ProgressEvidence[], events: readonly LogEvent[], node: number,
|
|
32
38
|
eligibleChecks: ReadonlySet<string>,
|
|
@@ -45,6 +51,8 @@ export function deriveProgress(
|
|
|
45
51
|
seen.push(item);
|
|
46
52
|
reads.set(item.sha256, seen);
|
|
47
53
|
if (item.observation_sha256 !== undefined) observations.add(item.observation_sha256);
|
|
54
|
+
// A version read before a cut is as known as one read in this segment.
|
|
55
|
+
observations.add(versionKey("", item.sha256));
|
|
48
56
|
} else if (item.kind === "observation") observations.add(item.sha256);
|
|
49
57
|
else checks.add(checkKey(item.command, item.gate, item.workspace_sha256));
|
|
50
58
|
}
|
|
@@ -61,6 +69,7 @@ export function deriveProgress(
|
|
|
61
69
|
const source = { node, event_id: event.id };
|
|
62
70
|
const effect = event.effect;
|
|
63
71
|
const observation = event.observation_sha256 ?? event.content_ref?.sha256 ?? event.content_sha256;
|
|
72
|
+
if (effect?.kind === "read" && effect.sha256 !== "") observations.add(versionKey(effect.path, effect.sha256));
|
|
64
73
|
if (effect?.kind === "read" && effect.sha256 !== "") {
|
|
65
74
|
const seen = reads.get(effect.sha256) ?? [];
|
|
66
75
|
const novel = !seen.some((r) => r.ranges === undefined) &&
|
|
@@ -89,6 +98,22 @@ export function deriveProgress(
|
|
|
89
98
|
// rerun of old evidence into a fresh completion by giving it a new name.
|
|
90
99
|
if (eligibleChecks.has(event.id)) progressed = true;
|
|
91
100
|
}
|
|
101
|
+
} else if (effect?.kind === "edit") {
|
|
102
|
+
// D9 revision (2026-09-29, user-approved): a file version no one has
|
|
103
|
+
// seen before is new evidence -- it is how implementation work shows up.
|
|
104
|
+
// Versions already seen anywhere (read, or either side of an edit) do
|
|
105
|
+
// not count, so an A->B->A rewrite loop still stalls.
|
|
106
|
+
// Both sides become durable evidence: the ledger is all a later
|
|
107
|
+
// derivation sees, and a version seen only as "before" must still be
|
|
108
|
+
// recognised when the file is edited back to it.
|
|
109
|
+
for (const [sha, isAfter] of [[effect.sha256_before, false], [effect.sha256_after, true]] as const) {
|
|
110
|
+
if (sha === null) continue;
|
|
111
|
+
const key = versionKey(effect.path, sha);
|
|
112
|
+
if (observations.has(key)) continue;
|
|
113
|
+
observations.add(key);
|
|
114
|
+
evidence.push({ kind: "observation", sha256: key, source });
|
|
115
|
+
if (isAfter) progressed = true;
|
|
116
|
+
}
|
|
92
117
|
} else if ((name === "grep" || name === "find" || name === "ls" || name === "query") &&
|
|
93
118
|
observation !== undefined && (event.content_ref?.bytes ?? event.content.length) > 0 &&
|
|
94
119
|
!observations.has(observation)) {
|
package/src/runtime/oauth.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { createServer, type Server } from "node:http";
|
|
|
17
17
|
import { pollDeviceCode } from "./oauth-device.ts";
|
|
18
18
|
|
|
19
19
|
/** Matches package.json. Sent as User-Agent so the server can see who we are (D18). */
|
|
20
|
-
export const XENO_VERSION = "0.1.
|
|
20
|
+
export const XENO_VERSION = "0.1.3";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Minutes subtracted from server expiry so a request issued at the edge
|
package/src/runtime/tools.ts
CHANGED
|
@@ -135,7 +135,7 @@ export type ApprovalChoice = "once" | "command" | "tool" | "deny";
|
|
|
135
135
|
export const DEFAULT_TOOL_CONTEXT: Omit<ToolContext, "root"> = {
|
|
136
136
|
// Runner prefixes are resolved in command position so `python3 -m pytest`
|
|
137
137
|
// works without letting `echo pytest` forge a gate (D11 / M.2).
|
|
138
|
-
gates: { pytest: "pytest", tsc: "typecheck", cargo: "cargo", jest: "test", vitest: "test" },
|
|
138
|
+
gates: { pytest: "pytest", tsc: "typecheck", cargo: "cargo", jest: "test", vitest: "test", go: "go" },
|
|
139
139
|
// Five minutes covers typical compiles and installs; longer work asks for
|
|
140
140
|
// its own `timeout` up to the hour ceiling (omp uses the same 300 / 3600).
|
|
141
141
|
// Approved change from 120s (2026-09-28): 120s hard-killed real builds.
|