pi-posthorse 0.10.17 → 0.10.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-posthorse",
3
- "version": "0.10.17",
3
+ "version": "0.10.18",
4
4
  "type": "module",
5
5
  "description": "Posthorse: fresh context, same journey. No-summary context rollover for Pi, with sparse budget reminders, handoffs, notes, and history.",
6
6
  "keywords": [
@@ -7,6 +7,7 @@ import { parseSessionLine } from "./session-files.ts";
7
7
  import { sessionNoteTouches } from "./note-evidence.ts";
8
8
  import { mapBatch, readManifest, snapshot, type SnapshotNote } from "./note-snapshots.ts";
9
9
  import {
10
+ addressIn,
10
11
  addressOf,
11
12
  bindingsOf,
12
13
  canonicalPath,
@@ -130,7 +131,7 @@ export async function resolveReference(
130
131
  }
131
132
  visited.add(directory);
132
133
  if (existsSync(notePath(current, path))) {
133
- return { ...current, path };
134
+ return addressIn(current, path);
134
135
  }
135
136
  // A manifest includes later adoptions; the journal includes later writes and deletions.
136
137
  const binding: NoteBinding | undefined =
@@ -204,7 +205,7 @@ function seedCandidates(
204
205
  ) {
205
206
  selected.set(seed.path, {
206
207
  ...seed,
207
- source: { root: binding.root, scope: binding.scope, path: seed.path },
208
+ source: addressIn(binding, seed.path),
208
209
  cleared: false,
209
210
  });
210
211
  }
@@ -83,6 +83,13 @@ export function forkScope(owner: NoteOwner): string {
83
83
  export function scopeDirectory(scope: NoteScope): string {
84
84
  return join(scope.root, scope.scope);
85
85
  }
86
+ /**
87
+ * An address is stored in the journal, and a scope value is often a whole binding. Build an
88
+ * address here, never by spreading a scope, so it holds the two location fields and nothing else.
89
+ */
90
+ export function addressIn(scope: NoteScope, path: string): NoteAddress {
91
+ return { root: scope.root, scope: scope.scope, path };
92
+ }
86
93
  export function sameScope(left: NoteScope, right: NoteScope): boolean {
87
94
  return left.root === right.root && left.scope === right.scope;
88
95
  }
@@ -278,7 +285,7 @@ export function addressOf(path: string, scopes: readonly NoteScope[]): NoteAddre
278
285
  ? undefined
279
286
  : candidates.find((item) => item.directory === match.directory);
280
287
  if (match !== undefined && candidate !== undefined) {
281
- return { ...candidate.scope, path: match.path };
288
+ return addressIn(candidate.scope, match.path);
282
289
  }
283
290
  if (
284
291
  scopes.some(
@@ -18,6 +18,7 @@ import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
18
18
  import { isRecord } from "./contracts.ts";
19
19
  import { publishFile } from "./files.ts";
20
20
  import {
21
+ addressIn,
21
22
  notePath,
22
23
  parseBinding,
23
24
  sameOwner,
@@ -127,7 +128,19 @@ async function copyNote(note: SnapshotNote, destination: string): Promise<CopyRe
127
128
  }
128
129
  await utimes(destination, before.atimeMs / 1000, before.mtimeMs / 1000);
129
130
  const [digest, destInfo] = await Promise.all([fileDigest(destination), stat(destination)]);
130
- return { kind: "verified", seed: { ...note, digest, identity: fileIdentity(destInfo) } };
131
+ return {
132
+ kind: "verified",
133
+ // Journals written by 0.10.4 through 0.10.17 hold whole bindings in seed addresses.
134
+ // A new seed keeps each location only, so that data is not copied into this fork.
135
+ seed: {
136
+ path: note.path,
137
+ source: addressIn(note.source, note.source.path),
138
+ lineage: addressIn(note.lineage, note.lineage.path),
139
+ digest,
140
+ identity: fileIdentity(destInfo),
141
+ anchors: note.anchors,
142
+ },
143
+ };
131
144
  } catch (error) {
132
145
  return {
133
146
  kind: "unverified",
package/src/note-store.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  import {
14
14
  NOTES_BINDING,
15
15
  NOTES_TOUCH,
16
+ addressIn,
16
17
  bindingsOf,
17
18
  canonicalPath,
18
19
  inside,
@@ -154,7 +155,7 @@ export class SessionNotes {
154
155
  if (options.scope !== undefined) {
155
156
  const scope = await this.selectScope(options.scope);
156
157
  return {
157
- address: { ...scope, path: relative },
158
+ address: addressIn(scope, relative),
158
159
  path: notePath(scope, relative),
159
160
  writable: sameScope(scope, this.binding),
160
161
  };
@@ -162,11 +163,7 @@ export class SessionNotes {
162
163
  const reference = this.owns(relative)
163
164
  ? undefined
164
165
  : await this.#reference(relative, options.signal);
165
- const address = reference ?? {
166
- root: this.binding.root,
167
- scope: this.binding.scope,
168
- path: relative,
169
- };
166
+ const address = reference ?? addressIn(this.binding, relative);
170
167
  return { address, path: notePath(address, relative), writable: reference === undefined };
171
168
  }
172
169
  async adopt(path: string, call: NoteCall): Promise<Adoption> {