@almadar/workspace 0.11.4 → 0.11.6
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/dist/__tests__/append-json-line.test.d.ts +1 -0
- package/dist/__tests__/workspace-ledger.test.d.ts +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +263 -68
- package/dist/index.js.map +1 -1
- package/dist/internal/backends/local.d.ts +1 -0
- package/dist/internal/backends/memory.d.ts +1 -0
- package/dist/internal/memory-files.d.ts +6 -0
- package/dist/internal/path-layout.d.ts +7 -1
- package/dist/internal/types.d.ts +6 -0
- package/dist/service.d.ts +12 -1
- package/dist/types.d.ts +27 -0
- package/dist/workspace-index/fingerprint.d.ts +1 -2
- package/dist/workspace-index/index-impl.d.ts +1 -5
- package/dist/workspace-index/index.d.ts +2 -2
- package/dist/workspace-index/types.d.ts +0 -49
- package/dist/workspace-ledger/index.d.ts +9 -0
- package/dist/workspace-ledger/ledger-impl.d.ts +42 -0
- package/dist/workspace-ledger/persistence.d.ts +18 -0
- package/dist/workspace-ledger/types.d.ts +38 -0
- package/package.json +4 -4
- package/dist/__tests__/workspace-index-real-embedder.test.d.ts +0 -14
|
@@ -4,6 +4,7 @@ export declare class LocalBackend implements WorkspaceBackend {
|
|
|
4
4
|
readFileSync(absPath: string): string;
|
|
5
5
|
writeFile(absPath: string, content: string): Promise<void>;
|
|
6
6
|
writeFileSync(absPath: string, content: string): void;
|
|
7
|
+
appendFile(absPath: string, content: string): Promise<void>;
|
|
7
8
|
readFileBytes(absPath: string): Promise<Uint8Array>;
|
|
8
9
|
writeFileBytes(absPath: string, bytes: Uint8Array): Promise<void>;
|
|
9
10
|
exists(absPath: string): boolean;
|
|
@@ -10,6 +10,7 @@ export declare class MemoryBackend implements WorkspaceBackend {
|
|
|
10
10
|
readFileSync(absPath: string): string;
|
|
11
11
|
writeFile(absPath: string, content: string): Promise<void>;
|
|
12
12
|
writeFileSync(absPath: string, content: string): void;
|
|
13
|
+
appendFile(absPath: string, content: string): Promise<void>;
|
|
13
14
|
readFileBytes(absPath: string): Promise<Uint8Array>;
|
|
14
15
|
writeFileBytes(absPath: string, bytes: Uint8Array): Promise<void>;
|
|
15
16
|
exists(absPath: string): boolean;
|
|
@@ -22,5 +22,11 @@ export declare function readJsonLines<T extends JsonObject>(backend: WorkspaceBa
|
|
|
22
22
|
* Append a single JSON value as a line. Used for trace + history streams.
|
|
23
23
|
* Caller is responsible for any per-path serialization (the service's
|
|
24
24
|
* write queue handles that).
|
|
25
|
+
*
|
|
26
|
+
* Must be a REAL append (O_APPEND), never read-concat-rewrite: a rewrite
|
|
27
|
+
* truncates first, so a process killed mid-write zeroes the entire stream
|
|
28
|
+
* (C-TRACE-APPEND-TRUNCATE — the 0-byte trace.jsonl class). This function is
|
|
29
|
+
* the sole writer of these streams, so every line it writes ends in `\n` and
|
|
30
|
+
* the file never needs a separator probe.
|
|
25
31
|
*/
|
|
26
32
|
export declare function appendJsonLine<T extends JsonObject>(backend: WorkspaceBackend, absPath: string, value: T): Promise<void>;
|
|
@@ -46,11 +46,17 @@ export declare function compiledFile(workDir: string, relPath: string): string;
|
|
|
46
46
|
export declare function appMarkerFile(workDir: string): string;
|
|
47
47
|
/** Workspace-level index manifest path. */
|
|
48
48
|
export declare function workspaceIndexManifestFile(workDir: string): string;
|
|
49
|
+
/** Workspace-level identity-ledger path. */
|
|
50
|
+
export declare function workspaceLedgerFile(workDir: string): string;
|
|
49
51
|
/**
|
|
50
52
|
* Resolve a user-supplied relative path within the sandbox. Rejects
|
|
51
53
|
* absolute paths, `..` traversal, and any path that resolves outside
|
|
52
54
|
* `workDir`. Returns the absolute resolved path on success.
|
|
55
|
+
*
|
|
56
|
+
* When `mounts` is supplied, path prefixes like `@std/…` resolve against
|
|
57
|
+
* the mount's absolute root instead of `workDir`. Mounts bypass the
|
|
58
|
+
* `workDir` traversal guard but enforce their own.
|
|
53
59
|
*/
|
|
54
|
-
export declare function sandboxedPath(workDir: string, relPath: string): string;
|
|
60
|
+
export declare function sandboxedPath(workDir: string, relPath: string, mounts?: ReadonlyMap<string, string>): string;
|
|
55
61
|
/** Validate an orbital logical name — no path separators, no `..`. */
|
|
56
62
|
export declare function assertOrbitalName(name: string): void;
|
package/dist/internal/types.d.ts
CHANGED
|
@@ -13,6 +13,12 @@ export interface WorkspaceBackend {
|
|
|
13
13
|
readFileSync(absPath: string): string;
|
|
14
14
|
writeFile(absPath: string, content: string): Promise<void>;
|
|
15
15
|
writeFileSync(absPath: string, content: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Append to a file (create if absent) without truncating — O_APPEND on real
|
|
18
|
+
* filesystems. Required for line streams (trace/history): a truncate-rewrite
|
|
19
|
+
* "append" zeroes the whole stream when the process is killed mid-write.
|
|
20
|
+
*/
|
|
21
|
+
appendFile(absPath: string, content: string): Promise<void>;
|
|
16
22
|
/** Binary read/write — for git bundle artifacts (durable archive bytes). */
|
|
17
23
|
readFileBytes(absPath: string): Promise<Uint8Array>;
|
|
18
24
|
writeFileBytes(absPath: string, bytes: Uint8Array): Promise<void>;
|
package/dist/service.d.ts
CHANGED
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
9
|
import type { JsonObject, JsonValue } from '@almadar/core';
|
|
10
|
-
import type { FileTreeNode, GitHubConfig, GitStatusInfo, InstantiateWorkspaceSeed, SnapshotMeta, WorkspaceArchiveBackend, WorkspaceObserver, WorkspaceService, WorkspaceWatchEvent } from './types.js';
|
|
10
|
+
import type { FileTreeNode, GitHubConfig, GitStatusInfo, InstantiateWorkspaceSeed, MountEntry, SnapshotMeta, WorkspaceArchiveBackend, WorkspaceObserver, WorkspaceService, WorkspaceWatchEvent } from './types.js';
|
|
11
11
|
import type { WorkspaceBackend } from './internal/types.js';
|
|
12
12
|
import { SinkManager } from './internal/sink-manager.js';
|
|
13
13
|
import { GitClient } from './internal/git-client.js';
|
|
14
14
|
import type { EmbedderPort, WorkspaceIndex } from './workspace-index/types.js';
|
|
15
|
+
import type { WorkspaceLedger } from './workspace-ledger/types.js';
|
|
15
16
|
interface ServiceCtorArgs {
|
|
16
17
|
workDir: string;
|
|
17
18
|
backend: WorkspaceBackend;
|
|
@@ -21,6 +22,7 @@ interface ServiceCtorArgs {
|
|
|
21
22
|
git?: GitClient;
|
|
22
23
|
github?: GitHubConfig;
|
|
23
24
|
archiveBackend?: WorkspaceArchiveBackend;
|
|
25
|
+
mounts?: MountEntry[];
|
|
24
26
|
}
|
|
25
27
|
export declare class WorkspaceServiceImpl implements WorkspaceService {
|
|
26
28
|
readonly workDir: string;
|
|
@@ -32,7 +34,10 @@ export declare class WorkspaceServiceImpl implements WorkspaceService {
|
|
|
32
34
|
private readonly archiveBackend;
|
|
33
35
|
/** Per-absolute-path serial queue. */
|
|
34
36
|
private readonly writeQueue;
|
|
37
|
+
/** Mount prefix → resolved absolute directory. Built from constructor `mounts` + runtime `mountReadonly`. */
|
|
38
|
+
private readonly mountMap;
|
|
35
39
|
readonly index: WorkspaceIndex;
|
|
40
|
+
readonly ledger: WorkspaceLedger;
|
|
36
41
|
constructor(args: ServiceCtorArgs);
|
|
37
42
|
get appId(): string | undefined;
|
|
38
43
|
setAppId(id: string): void;
|
|
@@ -86,6 +91,12 @@ export declare class WorkspaceServiceImpl implements WorkspaceService {
|
|
|
86
91
|
removeFile(relPath: string): Promise<void>;
|
|
87
92
|
listTree(relPath?: string): Promise<FileTreeNode[]>;
|
|
88
93
|
exists(relPath: string): Promise<boolean>;
|
|
94
|
+
mountReadonly(prefix: string, absPath: string): void;
|
|
95
|
+
isMounted(relPath: string): boolean;
|
|
96
|
+
/** Resolve a sandboxed path through mounts. */
|
|
97
|
+
private sandbox;
|
|
98
|
+
/** Throw if relPath resolves to a mount (write/remove are blocked). */
|
|
99
|
+
private assertNotMounted;
|
|
89
100
|
commitAndPush(opts: {
|
|
90
101
|
message: string;
|
|
91
102
|
tags?: string[];
|
package/dist/types.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { JsonObject, JsonValue, OrbitalSchema } from '@almadar/core';
|
|
10
10
|
import type { ProviderConfig } from '@almadar/llm';
|
|
11
11
|
import type { EmbedderPort, WorkspaceIndex } from './workspace-index/types.js';
|
|
12
|
+
import type { WorkspaceLedger } from './workspace-ledger/types.js';
|
|
12
13
|
/**
|
|
13
14
|
* The only extension point. Consumers register one observer via
|
|
14
15
|
* `service.subscribe(observer)`; every workspace write fans out
|
|
@@ -100,6 +101,9 @@ export type WorkspaceWriteEvent = {
|
|
|
100
101
|
} | {
|
|
101
102
|
kind: 'workspace-index-manifest';
|
|
102
103
|
content: JsonObject;
|
|
104
|
+
} | {
|
|
105
|
+
kind: 'workspace-ledger';
|
|
106
|
+
content: JsonObject;
|
|
103
107
|
};
|
|
104
108
|
/**
|
|
105
109
|
* Emitted by {@link WorkspaceService.watch} when storage changes underneath the
|
|
@@ -173,6 +177,13 @@ export interface FileTreeNode {
|
|
|
173
177
|
/** Byte size for files; `0` for directories. */
|
|
174
178
|
size: number;
|
|
175
179
|
}
|
|
180
|
+
/** Read-only mount entry — makes an external absolute directory available under a workspace-prefix path. */
|
|
181
|
+
export interface MountEntry {
|
|
182
|
+
/** Workspace-relative prefix, e.g. `@std`. Must not contain path separators or `..`. */
|
|
183
|
+
prefix: string;
|
|
184
|
+
/** Absolute path to the backing directory on the local filesystem. */
|
|
185
|
+
absPath: string;
|
|
186
|
+
}
|
|
176
187
|
/**
|
|
177
188
|
* Factory input. Lifecycle resolution order: `adopt` → resume-from-disk →
|
|
178
189
|
* `restore` backend → `github` clone → mint fresh.
|
|
@@ -213,6 +224,13 @@ export interface OpenWorkspaceOptions {
|
|
|
213
224
|
create?: boolean;
|
|
214
225
|
/** Storage selector. `'memory'` is for tests; `'local'` is default. */
|
|
215
226
|
backend?: 'local' | 'memory';
|
|
227
|
+
/**
|
|
228
|
+
* Read-only mounts — expose external absolute directories under
|
|
229
|
+
* workspace-relative path prefixes (e.g. `@std` → `/path/to/std`).
|
|
230
|
+
* ReadFile / listTree / exists resolve through mounts transparently;
|
|
231
|
+
* writeFile / removeFile reject mounted paths.
|
|
232
|
+
*/
|
|
233
|
+
mounts?: MountEntry[];
|
|
216
234
|
/** Optional project name baked into the mint-time schema template. */
|
|
217
235
|
projectName?: string;
|
|
218
236
|
/**
|
|
@@ -329,6 +347,14 @@ export interface WorkspaceService {
|
|
|
329
347
|
removeFile(relPath: string): Promise<void>;
|
|
330
348
|
listTree(relPath?: string): Promise<FileTreeNode[]>;
|
|
331
349
|
exists(relPath: string): Promise<boolean>;
|
|
350
|
+
/**
|
|
351
|
+
* Add a read-only mount at runtime — makes an external absolute directory
|
|
352
|
+
* available under a workspace-path prefix. ReadFile / listTree / exists
|
|
353
|
+
* resolve through the mount transparently; writeFile / removeFile reject it.
|
|
354
|
+
*/
|
|
355
|
+
mountReadonly(prefix: string, absPath: string): void;
|
|
356
|
+
/** True when `relPath` resolves to a read-only mount. */
|
|
357
|
+
isMounted(relPath: string): boolean;
|
|
332
358
|
commitAndPush(opts: {
|
|
333
359
|
message: string;
|
|
334
360
|
tags?: string[];
|
|
@@ -361,6 +387,7 @@ export interface WorkspaceService {
|
|
|
361
387
|
*/
|
|
362
388
|
watch(relPath: string, onChange: (event: WorkspaceWatchEvent) => void): () => void;
|
|
363
389
|
readonly index: WorkspaceIndex;
|
|
390
|
+
readonly ledger: WorkspaceLedger;
|
|
364
391
|
dispose(): Promise<void>;
|
|
365
392
|
}
|
|
366
393
|
/**
|
|
@@ -45,8 +45,7 @@ export declare function composeExtraTraitIdentityFingerprint(emit: {
|
|
|
45
45
|
/**
|
|
46
46
|
* Derive the alias an entry would canonically be referenced by. Used by
|
|
47
47
|
* the sidecar baker to store the `alias` field next to each extraTrait
|
|
48
|
-
* identity vector
|
|
49
|
-
* `coercedTo` when a match fires.
|
|
48
|
+
* identity vector.
|
|
50
49
|
*/
|
|
51
50
|
export declare function deriveExtraTraitAlias(emit: {
|
|
52
51
|
ref: string;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { JsonObject } from '@almadar/core';
|
|
10
10
|
import type { WorkspaceBackend } from '../internal/types.js';
|
|
11
11
|
import type { SinkManager } from '../internal/sink-manager.js';
|
|
12
|
-
import type { EmbedderPort, EntityBinding, EventEdge, RecentlyEditedOptions,
|
|
12
|
+
import type { EmbedderPort, EntityBinding, EventEdge, RecentlyEditedOptions, RetrievalOptions, RetrievalResult, RuleBinding, WorkspaceIndex, WorkspaceIndexStats } from './types.js';
|
|
13
13
|
export interface WorkspaceIndexDeps {
|
|
14
14
|
workDir: string;
|
|
15
15
|
backend: WorkspaceBackend;
|
|
@@ -42,10 +42,6 @@ export declare class WorkspaceIndexImpl implements WorkspaceIndex {
|
|
|
42
42
|
constructor(deps: WorkspaceIndexDeps);
|
|
43
43
|
private onWorkspaceWrite;
|
|
44
44
|
warm(): Promise<void>;
|
|
45
|
-
resolveOrbitalName(name: string, opts?: ResolveOptions): Promise<ResolveResult>;
|
|
46
|
-
resolveTraitRef(emit: TraitRefEmit, orbitalContext: {
|
|
47
|
-
orbitalName: string;
|
|
48
|
-
}, opts?: ResolveOptions): Promise<ResolveResult>;
|
|
49
45
|
stats(): WorkspaceIndexStats;
|
|
50
46
|
retrieveOrbitalsForPrompt(prompt: string, opts?: RetrievalOptions): Promise<readonly RetrievalResult[]>;
|
|
51
47
|
findByToken(query: string): readonly string[];
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @packageDocumentation
|
|
6
6
|
*/
|
|
7
|
-
export type { EmbedderPort, ExtraTraitIdentity, OrbitalIndexEntry,
|
|
8
|
-
export {
|
|
7
|
+
export type { EmbedderPort, ExtraTraitIdentity, OrbitalIndexEntry, WorkspaceIndex, WorkspaceIndexStats, } from './types.js';
|
|
8
|
+
export { WORKSPACE_INDEX_SCHEMA_VERSION, } from './types.js';
|
|
9
9
|
export { WorkspaceIndexImpl } from './index-impl.js';
|
|
10
10
|
export type { WorkspaceIndexDeps } from './index-impl.js';
|
|
11
11
|
export { createDefaultEmbedder } from './embedder.js';
|
|
@@ -14,8 +14,6 @@ import type { JsonObject } from '@almadar/core';
|
|
|
14
14
|
* Existing v1 sidecars get re-baked transparently on next openWorkspace.
|
|
15
15
|
*/
|
|
16
16
|
export declare const WORKSPACE_INDEX_SCHEMA_VERSION: 2;
|
|
17
|
-
/** Default coercion threshold per the doc's locked decision. */
|
|
18
|
-
export declare const DEFAULT_COERCION_THRESHOLD: 0.85;
|
|
19
17
|
/** RRF fusion constant (Elastic / OpenSearch convention). */
|
|
20
18
|
export declare const RRF_K: 60;
|
|
21
19
|
/** Default top-K for retrieveOrbitalsForPrompt. */
|
|
@@ -68,33 +66,6 @@ export interface OrbitalIndexEntry {
|
|
|
68
66
|
/** Epoch ms at bake time — debugging only. */
|
|
69
67
|
bakedAt: number;
|
|
70
68
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Input to `resolveTraitRef` — the LLM's emitted extraTraits entry,
|
|
73
|
-
* narrowed to the fields the coercion needs to see. Mirrors the
|
|
74
|
-
* `RawExtraTraitRef` shape rabit's analyzer constructs.
|
|
75
|
-
*/
|
|
76
|
-
export interface TraitRefEmit {
|
|
77
|
-
ref: string;
|
|
78
|
-
name?: string;
|
|
79
|
-
linkedEntity?: string;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Common result shape for both `resolveOrbitalName` and
|
|
83
|
-
* `resolveTraitRef`. `coercedTo` is null when no existing entity
|
|
84
|
-
* exceeded the threshold — the emit is genuinely new.
|
|
85
|
-
*/
|
|
86
|
-
export interface ResolveResult {
|
|
87
|
-
coercedTo: string | null;
|
|
88
|
-
similarity: number;
|
|
89
|
-
method: 'identity-vector';
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Options for both `resolveOrbitalName` and `resolveTraitRef`. The
|
|
93
|
-
* default threshold (0.85) lives in `DEFAULT_COERCION_THRESHOLD`.
|
|
94
|
-
*/
|
|
95
|
-
export interface ResolveOptions {
|
|
96
|
-
threshold?: number;
|
|
97
|
-
}
|
|
98
69
|
/**
|
|
99
70
|
* Stats surface for diagnostics. Cheap to compute (read in-memory
|
|
100
71
|
* state).
|
|
@@ -116,26 +87,6 @@ export interface WorkspaceIndex {
|
|
|
116
87
|
* already-warm sidecar is a no-op (checksum matches).
|
|
117
88
|
*/
|
|
118
89
|
warm(): Promise<void>;
|
|
119
|
-
/**
|
|
120
|
-
* R-10 coercion. Embed `name`, cosine-match against every orbital's
|
|
121
|
-
* identity vector, return the best match if it exceeds the
|
|
122
|
-
* threshold. Returns `{ coercedTo: null, ... }` when below threshold
|
|
123
|
-
* or when no orbitals exist in the workspace.
|
|
124
|
-
*/
|
|
125
|
-
resolveOrbitalName(name: string, opts?: ResolveOptions): Promise<ResolveResult>;
|
|
126
|
-
/**
|
|
127
|
-
* R-8 coercion. Embed an LLM-emitted trait emit, cosine-match against
|
|
128
|
-
* the existing `extraTraits[]` identity vectors on the named orbital.
|
|
129
|
-
* Returns the existing entry's `ref` (or its `name` rename) as
|
|
130
|
-
* `coercedTo` when match exceeds threshold; null when the emit is a
|
|
131
|
-
* genuinely new addition.
|
|
132
|
-
*
|
|
133
|
-
* Scoped per orbital — the same trait import on two different orbitals
|
|
134
|
-
* is structurally legitimate, so we don't cross-coerce.
|
|
135
|
-
*/
|
|
136
|
-
resolveTraitRef(emit: TraitRefEmit, orbitalContext: {
|
|
137
|
-
orbitalName: string;
|
|
138
|
-
}, opts?: ResolveOptions): Promise<ResolveResult>;
|
|
139
90
|
/**
|
|
140
91
|
* Phase B — RRF-hybrid prompt retrieval. Embed the prompt, run sparse
|
|
141
92
|
* BM25 against the workspace token table, fuse via Reciprocal Rank
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface of the workspace identity-ledger module. Re-exported from
|
|
3
|
+
* the top-level `@almadar/workspace` barrel.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
export type { WorkspaceLedger } from './types.js';
|
|
8
|
+
export { WorkspaceLedgerImpl } from './ledger-impl.js';
|
|
9
|
+
export type { WorkspaceLedgerDeps } from './ledger-impl.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `WorkspaceLedgerImpl` — the runtime holding one `IdentityLedger` per
|
|
3
|
+
* workspace. A sibling of `WorkspaceIndexImpl`: it subscribes to the
|
|
4
|
+
* `SinkManager` to auto-ingest `.orb` ledger slices on `orbital` writes, and
|
|
5
|
+
* persists to `.almadar/ledger.json`, emitting a `workspace-ledger` mirror
|
|
6
|
+
* event after each persist.
|
|
7
|
+
*
|
|
8
|
+
* The workspace ledger is runtime-owned and authoritative: `ingestOrbSlice`
|
|
9
|
+
* only ever introduces NEW ids; an id already present keeps its row. Renames
|
|
10
|
+
* flow through explicit `rename()` calls (from rabit), never inferred from
|
|
11
|
+
* file events.
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
import type { IdKind, IdentityLedger, LedgerEntry, LedgerKind } from '@almadar/core';
|
|
16
|
+
import type { WorkspaceBackend } from '../internal/types.js';
|
|
17
|
+
import type { SinkManager } from '../internal/sink-manager.js';
|
|
18
|
+
import type { WorkspaceLedger } from './types.js';
|
|
19
|
+
export interface WorkspaceLedgerDeps {
|
|
20
|
+
workDir: string;
|
|
21
|
+
backend: WorkspaceBackend;
|
|
22
|
+
sinks: SinkManager;
|
|
23
|
+
listOrbitals: () => string[];
|
|
24
|
+
readOrbital: (name: string) => string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare class WorkspaceLedgerImpl implements WorkspaceLedger {
|
|
27
|
+
private readonly deps;
|
|
28
|
+
private ledger;
|
|
29
|
+
/** Serialized persists so concurrent writes don't race the file. */
|
|
30
|
+
private persistQueue;
|
|
31
|
+
constructor(deps: WorkspaceLedgerDeps);
|
|
32
|
+
private onWorkspaceWrite;
|
|
33
|
+
resolve(kind: LedgerKind, name: string): string | null;
|
|
34
|
+
mint(kind: IdKind, name: string): string;
|
|
35
|
+
rename(id: string, to: string, at: number): void;
|
|
36
|
+
curName(id: string): string | null;
|
|
37
|
+
entry(id: string): LedgerEntry | null;
|
|
38
|
+
snapshot(): IdentityLedger;
|
|
39
|
+
ingestOrbSlice(slice: IdentityLedger): void;
|
|
40
|
+
warm(): Promise<void>;
|
|
41
|
+
private persist;
|
|
42
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity-ledger persistence — the single JSON file `.almadar/ledger.json`.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `workspace-index/manifest.ts`: same file helpers, same path-layout
|
|
5
|
+
* discipline. Reads validate against the core `IdentityLedgerSchema`; an
|
|
6
|
+
* unparseable / wrong-version file reads as `null` (the caller substitutes an
|
|
7
|
+
* empty ledger), matching the sidecar null-on-mismatch posture.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
import type { JsonObject } from '@almadar/core';
|
|
12
|
+
import type { IdentityLedger } from '@almadar/core';
|
|
13
|
+
import type { WorkspaceBackend } from '../internal/types.js';
|
|
14
|
+
export declare function ledgerPath(workDir: string): string;
|
|
15
|
+
export declare function readLedger(backend: WorkspaceBackend, workDir: string): Promise<IdentityLedger | null>;
|
|
16
|
+
export declare function writeLedger(backend: WorkspaceBackend, workDir: string, ledger: IdentityLedger): Promise<void>;
|
|
17
|
+
/** Project the ledger into a plain `JsonObject` for persistence + the mirror event. */
|
|
18
|
+
export declare function serializeLedger(ledger: IdentityLedger): JsonObject;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface of the workspace identity ledger (Rabit V4, Phase 6).
|
|
3
|
+
*
|
|
4
|
+
* One `IdentityLedger` (the core type, schemaVersion 1) per workspace — the
|
|
5
|
+
* runtime-owned, authoritative name↔id map. Resolution is exact within a kind;
|
|
6
|
+
* there is no similarity, no threshold, no fallback. Baked/emitted `.orb`
|
|
7
|
+
* slices only ever introduce NEW ids (row-level merge); an id already present
|
|
8
|
+
* keeps its workspace row.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import type { IdKind, IdentityLedger, LedgerEntry, LedgerKind } from '@almadar/core';
|
|
13
|
+
export interface WorkspaceLedger {
|
|
14
|
+
/** Exact `curName` match within `kind`, else null. No similarity. */
|
|
15
|
+
resolve(kind: LedgerKind, name: string): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Mint a fresh id, insert a workspace-owned row, persist. Throws when
|
|
18
|
+
* `resolve(kind, name)` already returns an id (duplicate curName within a
|
|
19
|
+
* kind is a caller bug) or when `kind` is `'palette'` (manifest-owned).
|
|
20
|
+
*/
|
|
21
|
+
mint(kind: IdKind, name: string): string;
|
|
22
|
+
/** Rename an id's `curName` + append rename history, persist. Throws if id unknown. */
|
|
23
|
+
rename(id: string, to: string, at: number): void;
|
|
24
|
+
/** Current display name for an id, or null when unknown. */
|
|
25
|
+
curName(id: string): string | null;
|
|
26
|
+
/** The row for an id, or null when unknown. */
|
|
27
|
+
entry(id: string): LedgerEntry | null;
|
|
28
|
+
/** A deep clone of the ledger — no aliasing of internal state. */
|
|
29
|
+
snapshot(): IdentityLedger;
|
|
30
|
+
/**
|
|
31
|
+
* Row-level merge of a baked/emitted `.orb` ledger slice: add rows whose id
|
|
32
|
+
* is NOT already present; present ids keep the workspace row untouched.
|
|
33
|
+
* Persists once when the merge changed anything.
|
|
34
|
+
*/
|
|
35
|
+
ingestOrbSlice(slice: IdentityLedger): void;
|
|
36
|
+
/** Load `.almadar/ledger.json`, then ingest every existing `orbitals/*.orb` slice. */
|
|
37
|
+
warm(): Promise<void>;
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/workspace",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.6",
|
|
4
4
|
"description": "Storage-agnostic workspace primitives shared by Almadar consumers. One service, six exports, hidden paths, single observer. See docs/Almadar_Workspace.md.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
},
|
|
26
26
|
"license": "BUSL-1.1",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@almadar/core": "
|
|
29
|
-
"@almadar/llm": "^2.
|
|
28
|
+
"@almadar/core": "^10.31.0",
|
|
29
|
+
"@almadar/llm": "^2.35.0",
|
|
30
30
|
"dugite": "^3.2.2",
|
|
31
31
|
"typescript": "^5.4.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@almadar/eslint-plugin": "
|
|
34
|
+
"@almadar/eslint-plugin": "^2.14.0",
|
|
35
35
|
"@types/node": "^22.0.0",
|
|
36
36
|
"@typescript-eslint/parser": "8.56.0",
|
|
37
37
|
"eslint": "^10.0.0",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* End-to-end retrieval spec on the REAL `@almadar/llm` EmbeddingClient
|
|
3
|
-
* (bge-base-en-v1.5, 768-d). Skipped automatically when
|
|
4
|
-
* `OPEN_ROUTER_API_KEY` is not set in the environment.
|
|
5
|
-
*
|
|
6
|
-
* Purpose: validate before consumer integration that the workspace
|
|
7
|
-
* index actually catches the R-10 (orbital name drift) and R-8
|
|
8
|
-
* (extraTraits[] duplicate-ref) failure modes the design doc targets.
|
|
9
|
-
* Mock-embedder tests prove the wiring; this spec proves the geometry.
|
|
10
|
-
*
|
|
11
|
-
* Also reports per-fixture cosine to confirm
|
|
12
|
-
* `DEFAULT_COERCION_THRESHOLD = 0.85` is in the right ballpark.
|
|
13
|
-
*/
|
|
14
|
-
export {};
|