@crewhaus/continuity-store 0.4.2 → 0.5.0

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.
Files changed (2) hide show
  1. package/dist/trash.js +14 -3
  2. package/package.json +5 -5
package/dist/trash.js CHANGED
@@ -13,7 +13,7 @@
13
13
  */
14
14
  import { existsSync } from "node:fs";
15
15
  import { lstat, mkdir, readdir, rename, rm } from "node:fs/promises";
16
- import { dirname, join, relative, resolve } from "node:path";
16
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
17
17
  import { CrewhausError } from "@crewhaus/errors";
18
18
  export class TrashError extends CrewhausError {
19
19
  name = "TrashError";
@@ -29,7 +29,14 @@ function trashTimestamp(now) {
29
29
  return now().toISOString().slice(0, 19).replace(/:/g, "-");
30
30
  }
31
31
  function assertUnder(absPath, root, what) {
32
- if (absPath !== root && !absPath.startsWith(`${root}/`)) {
32
+ // `relative()`, not a `${root}/` prefix: on Windows `resolve` produces
33
+ // `C:\…\.crewhaus\state\focus.md`, which never startsWith `C:\…\.crewhaus/`,
34
+ // so this refused every path that WAS under the root. It failed closed —
35
+ // it refused to trash rather than trashing something outside — but that
36
+ // made continuity clear/restore unusable on Windows entirely.
37
+ const rel = relative(root, absPath);
38
+ const outside = rel !== "" && (rel.startsWith("..") || isAbsolute(rel));
39
+ if (outside) {
33
40
  throw new TrashError(`${what} "${absPath}" is outside the .crewhaus dir "${root}" — refusing to trash it`);
34
41
  }
35
42
  }
@@ -77,7 +84,11 @@ export async function moveToTrash(paths, crewhausDir, opts = {}) {
77
84
  for (const path of paths) {
78
85
  const abs = resolve(path);
79
86
  assertUnder(abs, root, "path");
80
- if (abs === trashRoot || abs.startsWith(`${trashRoot}/`)) {
87
+ // Same separator bug as `assertUnder`, but this one fails OPEN: on
88
+ // Windows `C:\…\trash\ts\f` never startsWith `C:\…\trash/`, so the guard
89
+ // never fired and the trash could be moved into itself.
90
+ const relToTrash = relative(trashRoot, abs);
91
+ if (relToTrash === "" || !(relToTrash.startsWith("..") || isAbsolute(relToTrash))) {
81
92
  throw new TrashError(`path "${abs}" is inside the trash — refusing to trash the trash`);
82
93
  }
83
94
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewhaus/continuity-store",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "v0.3.0 Goal 1 — focus/plans/goals/handoff stores under .crewhaus/state/ with the claimed→proven proof ladder verified against session event logs, trash/restore clearing, advisory locking, and tenant path fencing.",
6
6
  "main": "dist/index.js",
@@ -15,10 +15,10 @@
15
15
  "test": "bun test src"
16
16
  },
17
17
  "dependencies": {
18
- "@crewhaus/errors": "0.4.2",
19
- "@crewhaus/event-log": "0.4.2",
20
- "@crewhaus/infra-utils": "0.4.2",
21
- "@crewhaus/tenancy": "0.4.2",
18
+ "@crewhaus/errors": "0.5.0",
19
+ "@crewhaus/event-log": "0.5.0",
20
+ "@crewhaus/infra-utils": "0.5.0",
21
+ "@crewhaus/tenancy": "0.5.0",
22
22
  "yaml": "^2.6.0"
23
23
  },
24
24
  "license": "Apache-2.0",