drafted 1.10.2 → 1.11.1

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 +25 -6
  2. package/package.json +1 -1
package/mcp/server.mjs CHANGED
@@ -565,10 +565,14 @@ function reportMcpToolError(tool, error) {
565
565
  });
566
566
  }
567
567
 
568
- function wikiBrowserUrl(path = '') {
568
+ function wikiPageUrl(path = '', org = '') {
569
569
  const normalized = normalizeWikiPath(path || '');
570
- if (!normalized) return `${getServerUrl()}/wiki`;
571
- return `${getServerUrl()}/wiki/${normalized.split('/').map(encodeURIComponent).join('/')}`;
570
+ // Org-qualify so the link resolves to this org's wiki regardless of the
571
+ // viewer's current active org (wiki paths collide across orgs). The /wiki
572
+ // route resolves ?org id-first then slug.
573
+ const q = org ? `?org=${encodeURIComponent(org)}` : '';
574
+ if (!normalized) return `${getServerUrl()}/wiki${q}`;
575
+ return `${getServerUrl()}/wiki/${normalized.split('/').map(encodeURIComponent).join('/')}${q}`;
572
576
  }
573
577
 
574
578
  function getBootstrapSessionId() {
@@ -2679,9 +2683,9 @@ function collectSkillTreeForPush(dir) {
2679
2683
  return out;
2680
2684
  }
2681
2685
 
2682
- tool('skill', 'Manage the Drafted skill library. Skills are reusable prompts/guidelines agents can load and follow. Dispatch by `action`: search/load/list for discovery; add/update/remove for org skills; fork/push for source-only skills; attach/detach for project binding; favorite/unfavorite for personal pins; read_file/update_file for supporting files inside a skill directory.', {
2686
+ tool('skill', 'Manage the Drafted skill library. Skills are reusable prompts/guidelines agents can load and follow. Dispatch by `action`: search/load/list for discovery; history for a skill\'s version git-log; add/update/remove for org skills; fork/push for source-only skills; attach/detach for project binding; favorite/unfavorite for personal pins; read_file/update_file for supporting files inside a skill directory.', {
2683
2687
  action: z.enum([
2684
- 'search', 'load', 'list',
2688
+ 'search', 'load', 'list', 'history',
2685
2689
  'add', 'update', 'remove',
2686
2690
  'fork', 'push',
2687
2691
  'attach', 'detach',
@@ -2694,7 +2698,8 @@ tool('skill', 'Manage the Drafted skill library. Skills are reusable prompts/gui
2694
2698
  limit: z.number().optional().describe('[search|list] max results per page (default 25, max 100)'),
2695
2699
  offset: z.number().optional().describe('[search|list] skip N results for pagination (default 0). Response reports totalAvailable/returned/truncated.'),
2696
2700
  compact: z.boolean().optional().describe('[search|list] return only {slug,name,tags} per skill instead of full summaries — for browsing large catalogs within token budget'),
2697
- skill: z.string().optional().describe('[load] skill ID (UUID) or slug'),
2701
+ skill: z.string().optional().describe('[load|history] skill ID (UUID) or slug'),
2702
+ version: z.number().optional().describe('[history] fetch this version number\'s full snapshot (content included); omit for the reverse-chron version list'),
2698
2703
  skillId: z.string().optional().describe('[update|remove|attach|detach|favorite|unfavorite|read_file|update_file] skill ID'),
2699
2704
  projectId: z.string().optional().describe('[list] project to list skills for (defaults to active project; falls back to org-attached skills if no project)'),
2700
2705
  name: z.string().optional().describe('[add|update] skill name'),
@@ -2732,6 +2737,17 @@ tool('skill', 'Manage the Drafted skill library. Skills are reusable prompts/gui
2732
2737
  if (result?.id) getSessionState().loadedSkillIds.add(result.id);
2733
2738
  return ok(result);
2734
2739
  }
2740
+ case 'history': {
2741
+ // Skill version git-log. Omit `version` for the list; pass it for a
2742
+ // single version's full snapshot (content for view/diff).
2743
+ const { skillId, skill: slugArg, version, org } = args;
2744
+ const extra = org ? { 'X-Drafted-Org': org } : {};
2745
+ let id = skillId;
2746
+ if (!id && slugArg) { const s = await api('GET', `/api/skills/slug/${slugArg}`, undefined, extra); id = s.id; }
2747
+ if (!id) throw new Error('skillId or skill (slug) required for action=history');
2748
+ if (version != null) return ok(await api('GET', `/api/skills/${id}/versions/${version}`, undefined, extra));
2749
+ return ok(await api('GET', `/api/skills/${id}/versions`, undefined, extra));
2750
+ }
2735
2751
  case 'list': {
2736
2752
  if (args.scope || args.tags?.length) {
2737
2753
  const params = new URLSearchParams();
@@ -2934,6 +2950,9 @@ tool('wiki', 'Per-org wiki. Markdown pages with paths as hierarchy. You and othe
2934
2950
  // Mutation responses include `org` so the agent always sees where the
2935
2951
  // write landed — eliminates silent cross-org confusion.
2936
2952
  const withOrg = (result) => ({ ...result, org: orgCtx });
2953
+ // Org-qualify every browser URL this tool emits (shadows the module fn for
2954
+ // all call sites below) so links are portable across the viewer's orgs.
2955
+ const wikiBrowserUrl = (p) => wikiPageUrl(p, orgId);
2937
2956
 
2938
2957
  // ── Skill gate: all mutation actions ──────────────────────────
2939
2958
  // Ensure the wiki-maintainer skill is attached to this org BEFORE the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drafted",
3
- "version": "1.10.2",
3
+ "version": "1.11.1",
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": [