@usabledev/usable-chat 1.217.0 → 1.217.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/cli.js +117 -18
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -176676,6 +176676,9 @@ function isUsableWriteTool(toolName) {
176676
176676
  function extractWorkspaceIds(args) {
176677
176677
  const ids = /* @__PURE__ */ new Set();
176678
176678
  if (typeof args.workspaceId === "string" && args.workspaceId) ids.add(args.workspaceId);
176679
+ if (typeof args.targetWorkspaceId === "string" && args.targetWorkspaceId) {
176680
+ ids.add(args.targetWorkspaceId);
176681
+ }
176679
176682
  if (Array.isArray(args.workspaceIds)) {
176680
176683
  for (const id of args.workspaceIds) if (typeof id === "string" && id) ids.add(id);
176681
176684
  }
@@ -176701,29 +176704,31 @@ function validateUsableToolWorkspace(toolName, args, context3, _isExplicitUserRe
176701
176704
  }
176702
176705
  const workspaceIds = extractWorkspaceIds(args);
176703
176706
  const outsideWorkspaceId = workspaceIds.find((id) => !isWorkspaceAllowed(id, allowedWorkspaces));
176704
- if (usableToolName === USABLE_WRITE_TOOLS.CREATE || usableToolName === USABLE_WRITE_TOOLS.UPLOAD) {
176705
- if (workspaceIds.length === 0) {
176707
+ const workspaceWrite = WORKSPACE_WRITE_WORDING[usableToolName];
176708
+ if (workspaceWrite) {
176709
+ const field = workspaceWrite.field ?? "workspaceId";
176710
+ if (typeof args[field] !== "string" || !args[field]) {
176706
176711
  return {
176707
176712
  valid: false,
176708
- error: `REQUIRED: workspaceId parameter must be specified for ${toolName}. You can only create fragments or upload files in workspaces that are in project or conversation context.`
176713
+ error: `REQUIRED: ${field} parameter must be specified for ${toolName}. You can only ${workspaceWrite.required} in workspaces that are in project or conversation context.`
176709
176714
  };
176710
176715
  }
176711
176716
  if (outsideWorkspaceId) {
176712
176717
  return {
176713
176718
  valid: false,
176714
- error: `BLOCKED: Cannot ${usableToolName === USABLE_WRITE_TOOLS.UPLOAD ? "upload a file to" : "create fragment in"} workspace ${outsideWorkspaceId} because it is not in project or conversation context.
176719
+ error: `BLOCKED: Cannot ${workspaceWrite.cannot} workspace ${outsideWorkspaceId} because it is not in project or conversation context.
176715
176720
 
176716
- **REQUIRED ACTION**: Before ${usableToolName === USABLE_WRITE_TOOLS.UPLOAD ? "uploading files to" : "creating fragments in"} this workspace, you MUST either:
176721
+ **REQUIRED ACTION**: Before ${workspaceWrite.before} this workspace, you MUST either:
176717
176722
  1. Ask the user: "The workspace ${outsideWorkspaceId} is not in the current context. Would you like me to add it to the conversation context?"
176718
176723
  2. OR automatically add it to conversation context first using the 'add-to-conversation-context' tool with contextType='workspace' and contextId='${outsideWorkspaceId}'
176719
176724
 
176720
176725
  **Current allowed workspaces**: ${allowedWorkspaces.length > 0 ? allowedWorkspaces.join(", ") : "None"}
176721
176726
 
176722
- Once the workspace is added to context, you can then ${usableToolName === USABLE_WRITE_TOOLS.UPLOAD ? "upload files to" : "create fragments in"} it.`
176727
+ Once the workspace is added to context, you can then ${workspaceWrite.then} it.`
176723
176728
  };
176724
176729
  }
176725
176730
  }
176726
- if (usableToolName === USABLE_WRITE_TOOLS.UPDATE || usableToolName === USABLE_WRITE_TOOLS.ATTACH) {
176731
+ if (FRAGMENT_ADDRESSED_WRITES[usableToolName]) {
176727
176732
  if (outsideWorkspaceId) {
176728
176733
  return {
176729
176734
  valid: false,
@@ -176751,13 +176756,14 @@ function fragmentWriteRefusal(toolName, reason) {
176751
176756
  **REQUIRED ACTION**: Only fragments in workspaces that are in project or conversation context can be changed. If the user wants this fragment changed, ask them whether to add its workspace to the conversation context (the 'add-to-conversation-context' tool with contextType='workspace'), then retry.`
176752
176757
  };
176753
176758
  }
176754
- async function resolveFragmentWriteTarget(toolName, args, resolveFragmentWorkspace) {
176755
- const fragmentId = typeof args.fragmentId === "string" ? args.fragmentId.trim() : "";
176759
+ async function resolveFragmentWriteTarget(toolName, args, idField, resolveFragmentWorkspace) {
176760
+ const raw = args[idField];
176761
+ const fragmentId = typeof raw === "string" ? raw.trim() : "";
176756
176762
  if (!fragmentId) {
176757
- return fragmentWriteRefusal(toolName, "no fragmentId was given.");
176763
+ return fragmentWriteRefusal(toolName, `no ${idField} was given.`);
176758
176764
  }
176759
176765
  if (!UUID.test(fragmentId)) {
176760
- return fragmentWriteRefusal(toolName, `fragmentId ${JSON.stringify(fragmentId.slice(0, 64))} is not a fragment id (UUID).`);
176766
+ return fragmentWriteRefusal(toolName, `${idField} ${JSON.stringify(fragmentId.slice(0, 64))} is not a fragment id (UUID).`);
176761
176767
  }
176762
176768
  if (!resolveFragmentWorkspace) {
176763
176769
  return fragmentWriteRefusal(toolName, "the fragment's workspace could not be checked.");
@@ -176785,10 +176791,15 @@ async function resolveFragmentWriteTarget(toolName, args, resolveFragmentWorkspa
176785
176791
  }
176786
176792
  async function validateUsableToolWorkspaceFresh(toolName, args, context3, reload, isExplicitUserRequest = false, resolveFragmentWorkspace) {
176787
176793
  const usableToolName = canonicalUsableToolName(toolName);
176788
- const isFragmentWrite = usableToolName === USABLE_WRITE_TOOLS.UPDATE || usableToolName === USABLE_WRITE_TOOLS.ATTACH;
176794
+ const fragmentIdField = usableToolName ? FRAGMENT_ADDRESSED_WRITES[usableToolName] : void 0;
176789
176795
  let fragmentWorkspaceId;
176790
- if (isFragmentWrite && (context3.allowedWorkspaceIds?.length ?? 0) > 0) {
176791
- const target = await resolveFragmentWriteTarget(toolName, args, resolveFragmentWorkspace);
176796
+ if (fragmentIdField && (context3.allowedWorkspaceIds?.length ?? 0) > 0) {
176797
+ const target = await resolveFragmentWriteTarget(
176798
+ toolName,
176799
+ args,
176800
+ fragmentIdField,
176801
+ resolveFragmentWorkspace
176802
+ );
176792
176803
  if ("valid" in target) return target;
176793
176804
  fragmentWorkspaceId = target.workspaceId;
176794
176805
  }
@@ -176836,7 +176847,7 @@ async function recordWorkspaceAddedToContext(context3, toolName, args, result, r
176836
176847
  );
176837
176848
  if (fresh.length > 0) context3.allowedWorkspaceIds = [...current, ...new Set(fresh)];
176838
176849
  }
176839
- var UUID, USABLE_WRITE_TOOLS;
176850
+ var UUID, USABLE_WRITE_TOOLS, WORKSPACE_WRITE_WORDING, FRAGMENT_ADDRESSED_WRITES;
176840
176851
  var init_usable_validation = __esm({
176841
176852
  "src/core/tools/usable-validation.ts"() {
176842
176853
  "use strict";
@@ -176846,7 +176857,74 @@ var init_usable_validation = __esm({
176846
176857
  CREATE: "create-memory-fragment",
176847
176858
  UPDATE: "update-memory-fragment",
176848
176859
  ATTACH: "attach-file-to-fragment",
176849
- UPLOAD: "request-upload-url"
176860
+ UPLOAD: "request-upload-url",
176861
+ IMPORT_IMAGES: "import-image-fragments",
176862
+ IMPORT_FRAGMENT: "request-fragment-import",
176863
+ CREATE_COLLECTION: "create-collection",
176864
+ UPDATE_COLLECTION: "update-collection",
176865
+ CREATE_FRAGMENT_TYPE: "create-fragment-type",
176866
+ UPDATE_FRAGMENT_TYPE: "update-fragment-type",
176867
+ UPDATE_WORKSPACE: "update-workspace",
176868
+ CREATE_SYMLINK: "create-fragment-symlink",
176869
+ REMOVE_SYMLINK: "remove-fragment-symlink",
176870
+ PREPARE_PUBLIC_FRAGMENT: "prepare-public-fragment",
176871
+ PREPARE_PUBLIC_SITE: "prepare-public-site",
176872
+ REQUEST_PUBLICATION: "request-public-site-publication",
176873
+ WITHDRAW_PUBLIC_SITE: "withdraw-public-site"
176874
+ };
176875
+ WORKSPACE_WRITE_WORDING = {
176876
+ [USABLE_WRITE_TOOLS.CREATE]: {
176877
+ required: "create fragments or upload files",
176878
+ cannot: "create fragment in",
176879
+ before: "creating fragments in",
176880
+ then: "create fragments in"
176881
+ },
176882
+ [USABLE_WRITE_TOOLS.UPLOAD]: {
176883
+ required: "create fragments or upload files",
176884
+ cannot: "upload a file to",
176885
+ before: "uploading files to",
176886
+ then: "upload files to"
176887
+ },
176888
+ [USABLE_WRITE_TOOLS.IMPORT_IMAGES]: {
176889
+ required: "import images",
176890
+ cannot: "import images into",
176891
+ before: "importing images into",
176892
+ then: "import images into"
176893
+ },
176894
+ [USABLE_WRITE_TOOLS.IMPORT_FRAGMENT]: {
176895
+ required: "import fragments",
176896
+ cannot: "import a fragment into",
176897
+ before: "importing fragments into",
176898
+ then: "import fragments into"
176899
+ },
176900
+ ...Object.fromEntries(
176901
+ [
176902
+ [USABLE_WRITE_TOOLS.CREATE_COLLECTION, "create collections"],
176903
+ [USABLE_WRITE_TOOLS.UPDATE_COLLECTION, "change collections"],
176904
+ [USABLE_WRITE_TOOLS.CREATE_FRAGMENT_TYPE, "create fragment types"],
176905
+ [USABLE_WRITE_TOOLS.UPDATE_FRAGMENT_TYPE, "change fragment types"],
176906
+ [USABLE_WRITE_TOOLS.UPDATE_WORKSPACE, "change workspace settings"],
176907
+ [USABLE_WRITE_TOOLS.PREPARE_PUBLIC_FRAGMENT, "prepare public pages"],
176908
+ [USABLE_WRITE_TOOLS.PREPARE_PUBLIC_SITE, "prepare public sites"],
176909
+ [USABLE_WRITE_TOOLS.REQUEST_PUBLICATION, "publish"],
176910
+ [USABLE_WRITE_TOOLS.WITHDRAW_PUBLIC_SITE, "withdraw public sites"]
176911
+ ].map(([tool2, action5]) => [
176912
+ tool2,
176913
+ { required: action5, cannot: `${action5} in`, before: `you ${action5} in`, then: `${action5} in` }
176914
+ ])
176915
+ ),
176916
+ [USABLE_WRITE_TOOLS.CREATE_SYMLINK]: {
176917
+ field: "targetWorkspaceId",
176918
+ required: "create symlinks",
176919
+ cannot: "create a symlink in",
176920
+ before: "creating symlinks in",
176921
+ then: "create symlinks in"
176922
+ }
176923
+ };
176924
+ FRAGMENT_ADDRESSED_WRITES = {
176925
+ [USABLE_WRITE_TOOLS.UPDATE]: "fragmentId",
176926
+ [USABLE_WRITE_TOOLS.ATTACH]: "fragmentId",
176927
+ [USABLE_WRITE_TOOLS.REMOVE_SYMLINK]: "childFragmentId"
176850
176928
  };
176851
176929
  }
176852
176930
  });
@@ -289655,6 +289733,24 @@ var init_tool_categories = __esm({
289655
289733
  "request-upload-url",
289656
289734
  "attach-file-to-fragment",
289657
289735
  "save-chat-file-to-fragment",
289736
+ // Usable's other writes. The MCP bridge registers them under their plain names,
289737
+ // which the mutating-name fallback below (mcp_-prefixed only) never sees.
289738
+ "import-image-fragments",
289739
+ "request-fragment-import",
289740
+ "create-collection",
289741
+ "update-collection",
289742
+ "create-fragment-symlink",
289743
+ "remove-fragment-symlink",
289744
+ "update-fragment-type",
289745
+ "create-workspace",
289746
+ "update-workspace",
289747
+ "subscribe-to-workspace",
289748
+ "manage-application",
289749
+ "manage-installation-spend-credential",
289750
+ "prepare-public-fragment",
289751
+ "prepare-public-site",
289752
+ "request-public-site-publication",
289753
+ "withdraw-public-site",
289658
289754
  "create-embed-config",
289659
289755
  "update-embed-config",
289660
289756
  "create-custom-expert",
@@ -289931,6 +290027,7 @@ CRITICAL: You are in DISCUSSION MODE (read-only). This is a hard constraint you
289931
290027
 
289932
290028
  FORBIDDEN \u2014 these tools are REMOVED and do not exist:
289933
290029
  - create-memory-fragment, update-memory-fragment, request-upload-url, attach-file-to-fragment, save-chat-file-to-fragment
290030
+ - import-image-fragments, request-fragment-import, and Usable's collection, workspace, public-site and symlink writes
289934
290031
 
289935
290032
  You MUST NEVER claim or imply you performed any write action. Do NOT hallucinate success.
289936
290033
 
@@ -369861,6 +369958,7 @@ FORBIDDEN actions \u2014 you do NOT have these tools and MUST NOT pretend you do
369861
369958
  - Uploading files (request-upload-url is REMOVED)
369862
369959
  - Attaching files (attach-file-to-fragment is REMOVED)
369863
369960
  - Saving chat files to fragments (save-chat-file-to-fragment is REMOVED)
369961
+ - Importing, publishing or organizing (import-image-fragments, request-fragment-import, collections, workspaces, public sites and symlinks are REMOVED)
369864
369962
 
369865
369963
  You MUST NEVER claim or imply you performed any of these actions. Do NOT hallucinate success. Do NOT say "Done!" for write operations. The tools literally do not exist in your current tool set.
369866
369964
 
@@ -369919,6 +370017,7 @@ FORBIDDEN actions \u2014 these tools are REMOVED and you MUST NOT pretend you ha
369919
370017
  - Uploading files (request-upload-url is REMOVED)
369920
370018
  - Attaching files (attach-file-to-fragment is REMOVED)
369921
370019
  - Saving chat files to fragments (save-chat-file-to-fragment is REMOVED)
370020
+ - Importing, publishing or organizing (import-image-fragments, request-fragment-import, collections, workspaces, public sites and symlinks are REMOVED)
369922
370021
  - Generating images (generate-image is REMOVED)
369923
370022
 
369924
370023
  You MUST NEVER claim or imply you performed any of these actions.
@@ -372484,7 +372583,7 @@ When creating or searching for fragments, use these fragment type IDs:
372484
372583
  theme: {
372485
372584
  primary: "#fcaf2a",
372486
372585
  // Usable orange
372487
- accent: "#347cbf"
372586
+ accent: "#2e70b0"
372488
372587
  // Usable blue
372489
372588
  },
372490
372589
  displayName: "Usable Assistant",
@@ -395068,7 +395167,7 @@ init_tui_select();
395068
395167
  init_model_registry();
395069
395168
 
395070
395169
  // package.json
395071
- var version2 = "1.217.0";
395170
+ var version2 = "1.217.1";
395072
395171
 
395073
395172
  // src/adapters/cli/model-catalog.ts
395074
395173
  init_codex_auth();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usabledev/usable-chat",
3
- "version": "1.217.0",
3
+ "version": "1.217.1",
4
4
  "description": "usable-chat — terminal harness for usable-chat (headless + TUI)",
5
5
  "type": "module",
6
6
  "bin": {