dreamteamer 0.13.2 → 0.13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dreamteamer",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "A workspace compiler for coding agents — schema-validated records as plain files over git, compiled into every harness",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Gilad Khen <giladkhen@gmail.com>",
@@ -5,6 +5,7 @@
5
5
  // ref traversal (tier 1). serves `dreamteamer commands for`, GET /api/commands/:name,
6
6
  // and (through the extension's api.ts port) the studio's Commands tab.
7
7
  import { matchesFilter } from './filter.js';
8
+ import { parseRef } from './namespace.js';
8
9
 
9
10
  // memoized `<collection>/<id>` → parsed fields (or null) for ONE evaluation pass:
10
11
  // overlapping refs across a 50-record selection parse once, and filter.js stays
@@ -14,11 +15,20 @@ export function recordResolver(store) {
14
15
  return (ref) => {
15
16
  if (memo.has(ref)) return memo.get(ref);
16
17
  let target = null;
17
- const slash = typeof ref === 'string' ? ref.indexOf('/') : -1;
18
- if (slash > 0) {
18
+ // `parseRef`, NEVER `ref.indexOf('/')`. This split at the first slash until 0.13.3, which
19
+ // made `family/people/gilad` the collection `family` (a NAMESPACE, not a collection) holding
20
+ // the id `people/gilad`. `store.read` threw, the catch below swallowed it, and the caller got
21
+ // null — which filter.js is documented to treat as NARROWING. So every one-hop relational
22
+ // filter over a namespaced collection matched ZERO records, with no error anywhere, while the
23
+ // identical filter over a default-namespace ref worked. Measured on a real vault: 151 rows via
24
+ // `companies/<id>`, 0 rows via `family/people/<id>`, 273 for the same records addressed flat.
25
+ // The blast radius was not only filtering — this resolver also evaluates `can-enter`/`can-exit`
26
+ // below, so a binding predicate hopping a namespaced ref reported "not available".
27
+ const parsed = parseRef(ref, store.namespaces);
28
+ if (parsed) {
19
29
  try {
20
- const { fields } = store.read(ref.slice(0, slash), ref.slice(slash + 1));
21
- target = { ...fields, id: ref.slice(slash + 1) };
30
+ const { fields } = store.read(parsed.collection, parsed.id);
31
+ target = { ...fields, id: parsed.id };
22
32
  } catch { /* dangling ref or unknown collection — narrows, never widens */ }
23
33
  }
24
34
  memo.set(ref, target);