drafted 1.19.28 → 1.19.30

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/mcp/server.mjs +30 -6
  2. package/package.json +1 -1
package/mcp/server.mjs CHANGED
@@ -3262,13 +3262,37 @@ tool('fs', 'Navigate Drafted like a local filesystem. A FOLDER is the single con
3262
3262
  {
3263
3263
  const orgs = await getOrgList();
3264
3264
  if (searchNeedsOrg({ explicitOrg: org, orgFromPath, orgCount: orgs.length })) {
3265
- const names = orgs.map(o => o.slug || o.name || o.id).filter(Boolean);
3265
+ // Work is almost always org-specific, and this session usually already
3266
+ // knows WHICH — a binding, an open project, or the linked repo of the
3267
+ // checkout you are sitting in. Refusing to SCOPE by that is the whole
3268
+ // point (it would be silent); refusing to NAME it is just unhelpful.
3269
+ // So lead with the likely answer and make the retry a copy-paste.
3270
+ let likelyId = workingOrgId();
3271
+ if (!likelyId) {
3272
+ // workingOrgId()'s repo rung is populated as a SIDE EFFECT of whoami,
3273
+ // so a session that searches before calling it gets no hint — and the
3274
+ // guard fires early, which makes that the common case, not the edge.
3275
+ // Resolve it here instead of depending on call order. getRepoAddress
3276
+ // is process-cached, so this costs nothing after the first hit.
3277
+ const addrNow = await getRepoAddress().catch(() => null);
3278
+ if (addrNow?.state === 'linked' && addrNow.orgId) {
3279
+ getSessionState().repoOrgId = addrNow.orgId; // and stop re-resolving
3280
+ likelyId = addrNow.orgId;
3281
+ }
3282
+ }
3283
+ const likely = likelyId ? orgs.find(o => o.id === likelyId) : null;
3284
+ const addr = (o) => o.slug || o.name || o.id;
3285
+ const others = orgs.filter(o => o.id !== likelyId).map(addr).filter(Boolean);
3266
3286
  return err(new Error(
3267
- `Which org? Search needs one, and you belong to ${orgs.length}: ${names.join(', ')}.\n` +
3268
- `An unaddressed search would scope to whichever org this session inherited and report ` +
3269
- `"no matches" for the others — a false negative you cannot see, which is worse than this error.\n` +
3270
- `Address the org in the PATH: fs(search, path="/o/<org>", query="${q}").\n` +
3271
- `(Or org="<name>" on this call. Searching several orgs = one call each; the results say which org they came from.)`
3287
+ (likely
3288
+ ? `Which org? Search will not guess. This session is working in "${addr(likely)}" (source: ${workingOrgSource()}) — if that is what you meant, say so:\n` +
3289
+ ` fs(search, path="/o/${addr(likely)}", query="${q}")\n` +
3290
+ `Your other ${others.length} org(s): ${others.join(', ')}.\n`
3291
+ : `Which org? Search needs one, and you belong to ${orgs.length}: ${others.join(', ')}.\n` +
3292
+ ` fs(search, path="/o/<org>", query="${q}")\n`) +
3293
+ `Naming it is not overhead — a search that quietly scoped itself reports "no matches" for every ` +
3294
+ `org it skipped, which is indistinguishable from "nowhere" and stops you looking.\n` +
3295
+ `(Or org="<name>" on this call. Several orgs = one call each; every result says which org it came from.)`
3272
3296
  ));
3273
3297
  }
3274
3298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drafted",
3
- "version": "1.19.28",
3
+ "version": "1.19.30",
4
4
  "description": "Drafted — visual thinking surface for humans and AI agents. Renders HTML, markdown, images, and code as frames on a zoomable canvas, with MCP tools for AI agents and real-time sync for humans.",
5
5
  "type": "module",
6
6
  "files": [