dsh-continual-evolve 0.14.2 → 0.15.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.
@@ -1,149 +0,0 @@
1
- /**
2
- * The card's workspace catalog — which workspaces the card may read, and which
3
- * of them it lists.
4
- *
5
- * The list comes from the host's workspace registry (`ctx.workspaceRegistry`,
6
- * the durable records the workspace picker itself renders), not from the
7
- * sessions this process happened to serve: a card that only knows its own
8
- * session history can never offer ZCode's workspace switching — with one
9
- * served root the selector has nothing to switch to. The served-roots map
10
- * stays as a source (a session in a workspace the registry does not know about
11
- * still shows up), and `storages/workspace.json` is read only when the
12
- * registry service yields nothing: that file is an internal format, so it is a
13
- * fallback, never the primary.
14
- *
15
- * Two questions, deliberately answered by two methods. `known()` is the read
16
- * fence: can this root be read at all? `list()` is the display projection:
17
- * which workspaces have a memory directory right now? ZCode's viewer lists
18
- * only workspaces that have one, but the fence cannot be that filter — a store
19
- * deleted between listing and read must degrade to the empty state on its own
20
- * entry, not turn the read into a 404.
21
- */
22
- import { lstatSync, readFileSync, realpathSync } from "node:fs";
23
- import { basename, join, resolve } from "node:path";
24
- import { memoryDirFor } from "./memory-section.js";
25
- /** The registry stores `fs.realpath` already; resolve the rest the same way. */
26
- function canonicalPath(path) {
27
- try {
28
- return realpathSync(path);
29
- }
30
- catch {
31
- // A vanished or unreadable directory keeps its resolved spelling: the
32
- // registry itself never rewrites a record when its directory disappears.
33
- return resolve(path);
34
- }
35
- }
36
- /** One catalogue entry from a path/title pair, or undefined when unusable. */
37
- function entryOf(path, title) {
38
- if (typeof path !== "string" || path.trim().length === 0) {
39
- return undefined;
40
- }
41
- const root = canonicalPath(path);
42
- const label = typeof title === "string" && title.trim().length > 0 ? title.trim() : basename(root);
43
- return { root, label };
44
- }
45
- /** Records from the live registry service. */
46
- function registryEntries(registry) {
47
- if (registry === undefined) {
48
- return [];
49
- }
50
- let records;
51
- try {
52
- records = registry.list();
53
- }
54
- catch {
55
- // A registry that throws is a host fault the card must not inherit:
56
- // the next source still fills the list.
57
- return [];
58
- }
59
- if (!Array.isArray(records)) {
60
- return [];
61
- }
62
- const entries = [];
63
- for (const record of records) {
64
- if (typeof record !== "object" || record === null) {
65
- continue;
66
- }
67
- const entry = entryOf(record.path, record.title);
68
- if (entry !== undefined) {
69
- entries.push(entry);
70
- }
71
- }
72
- return entries;
73
- }
74
- /** Records from the registry's own durable file, for hosts without the service. */
75
- function fileEntries(homeDir) {
76
- if (homeDir === undefined || homeDir.trim().length === 0) {
77
- return [];
78
- }
79
- let parsed;
80
- try {
81
- parsed = JSON.parse(readFileSync(join(homeDir, "storages", "workspace.json"), "utf8"));
82
- }
83
- catch {
84
- // Missing or unreadable file: no workspaces from this source, no throw.
85
- return [];
86
- }
87
- const table = parsed?.tables?.workspaces;
88
- if (typeof table !== "object" || table === null || Array.isArray(table)) {
89
- return [];
90
- }
91
- const entries = [];
92
- for (const record of Object.values(table)) {
93
- if (typeof record !== "object" || record === null) {
94
- continue;
95
- }
96
- const entry = entryOf(record.path, record.title);
97
- if (entry !== undefined) {
98
- entries.push(entry);
99
- }
100
- }
101
- return entries;
102
- }
103
- /** Records from the roots this process served, most recent first. */
104
- function servedEntries(served) {
105
- return served.list().map(({ root }) => {
106
- const canonical = canonicalPath(root);
107
- return { root: canonical, label: basename(canonical) };
108
- });
109
- }
110
- /** ZCode's memory-directory rule: a plain directory, never a symlink. */
111
- function hasMemoryDirectory(root) {
112
- try {
113
- const stat = lstatSync(memoryDirFor(root));
114
- return stat.isDirectory() && !stat.isSymbolicLink();
115
- }
116
- catch {
117
- return false;
118
- }
119
- }
120
- /** Deduplicate by canonical root, keeping the first (highest-precedence) entry. */
121
- function dedupe(entries) {
122
- const seen = new Set();
123
- const unique = [];
124
- for (const entry of entries) {
125
- if (seen.has(entry.root)) {
126
- continue;
127
- }
128
- seen.add(entry.root);
129
- unique.push(entry);
130
- }
131
- return unique;
132
- }
133
- /** Create the catalog over the given sources. */
134
- export function createWorkspaceCatalog(options) {
135
- const known = () => {
136
- const live = registryEntries(options.registry?.());
137
- if (live.length > 0) {
138
- return dedupe([...live, ...servedEntries(options.served)]);
139
- }
140
- return dedupe([...fileEntries(options.homeDir), ...servedEntries(options.served)]);
141
- };
142
- return {
143
- known,
144
- list() {
145
- return known().filter((entry) => hasMemoryDirectory(entry.root));
146
- },
147
- };
148
- }
149
- //# sourceMappingURL=workspace-catalog.js.map