@fieldwangai/agentflow 0.1.88 → 0.1.90

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.
@@ -61,6 +61,7 @@ export function isCursorQuotaError(error = "") {
61
61
  /usage\s+limit/i,
62
62
  /limit\s+(?:exceeded|reached)/i,
63
63
  /exceeded\s+(?:your\s+)?limit/i,
64
+ /resource[_\s-]*exhausted/i,
64
65
  /ActionRequiredError/i,
65
66
  ].some((pattern) => pattern.test(text));
66
67
  }
@@ -1617,10 +1617,48 @@ const DISPLAY_SHARE_ALLOWED_EXPIRY_DAYS = new Set([1, 7, 30, 90, 365]);
1617
1617
  const NODE_STUDIO_DRAFTS_DIRNAME = "node-studio/drafts";
1618
1618
  const USER_WORKSPACES_FILENAME = "workspaces.json";
1619
1619
 
1620
- function userWorkspacesPath(userCtx = {}) {
1620
+ function workspacesPath() {
1621
+ return path.join(getAgentflowDataRoot(), USER_WORKSPACES_FILENAME);
1622
+ }
1623
+
1624
+ function legacyUserWorkspacesPath(userCtx = {}) {
1621
1625
  return path.join(getAgentflowUserDataRoot(userCtx.userId || ""), USER_WORKSPACES_FILENAME);
1622
1626
  }
1623
1627
 
1628
+ function defaultWorkspaceGitPath(id) {
1629
+ return path.join(getAgentflowDataRoot(), "workspaces", "repos", id);
1630
+ }
1631
+
1632
+ function legacyDefaultWorkspaceGitPath(userCtx = {}, id = "") {
1633
+ return path.join(getAgentflowUserDataRoot(userCtx.userId || ""), "workspaces", "repos", id);
1634
+ }
1635
+
1636
+ function isLegacyDefaultWorkspaceGitPath(rawPath = "", id = "", userCtx = {}) {
1637
+ const raw = String(rawPath || "").trim();
1638
+ if (!raw || !id) return false;
1639
+ try {
1640
+ return path.resolve(raw.replace(/^~(?=$|\/|\\)/, os.homedir())) === path.resolve(legacyDefaultWorkspaceGitPath(userCtx, id));
1641
+ } catch {
1642
+ return false;
1643
+ }
1644
+ }
1645
+
1646
+ function workspaceRepoNameFromUrl(repoUrl = "") {
1647
+ const raw = String(repoUrl || "").trim();
1648
+ if (!raw) return "";
1649
+ let pathname = raw;
1650
+ try {
1651
+ pathname = new URL(raw).pathname;
1652
+ } catch {
1653
+ pathname = raw.split("?")[0].split("#")[0];
1654
+ }
1655
+ const name = pathname.replace(/\/+$/, "").split("/").filter(Boolean).pop() || "";
1656
+ return name
1657
+ .replace(/\.git$/i, "")
1658
+ .replace(/[^A-Za-z0-9._-]+/g, "_")
1659
+ .replace(/^_+|_+$/g, "");
1660
+ }
1661
+
1624
1662
  function normalizeWorkspaceEntry(entry = {}, index = 0, userCtx = {}) {
1625
1663
  const label = String(entry?.label || entry?.name || "").trim();
1626
1664
  const kindRaw = String(entry?.kind || entry?.source || "").trim().toLowerCase();
@@ -1632,9 +1670,11 @@ function normalizeWorkspaceEntry(entry = {}, index = 0, userCtx = {}) {
1632
1670
  if (!rawPath && kind !== "git") return null;
1633
1671
  const idRaw = String(entry?.id || label || mountPathRaw || repoUrl || rawPath || `workspace_${index + 1}`).trim().toLowerCase();
1634
1672
  const id = idRaw.replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) || `workspace_${index + 1}`;
1635
- const mountPath = (mountPathRaw || id).replace(/^\/+/, "").replace(/\.\.(\/|\\|$)/g, "").trim() || id;
1636
- const defaultGitPath = path.join(getAgentflowUserDataRoot(userCtx.userId || ""), "workspaces", "repos", id);
1637
- const absPath = path.resolve((rawPath || defaultGitPath).replace(/^~(?=$|\/|\\)/, os.homedir()));
1673
+ const suggestedMountPath = kind === "git" ? workspaceRepoNameFromUrl(repoUrl) : "";
1674
+ const mountPath = (mountPathRaw || suggestedMountPath || id).replace(/^\/+/, "").replace(/\.\.(\/|\\|$)/g, "").trim() || id;
1675
+ const defaultGitPath = defaultWorkspaceGitPath(id);
1676
+ const explicitPath = kind === "git" && isLegacyDefaultWorkspaceGitPath(rawPath, id, userCtx) ? "" : rawPath;
1677
+ const absPath = path.resolve((explicitPath || defaultGitPath).replace(/^~(?=$|\/|\\)/, os.homedir()));
1638
1678
  const exists = fs.existsSync(absPath) && fs.statSync(absPath).isDirectory();
1639
1679
  return {
1640
1680
  id,
@@ -1653,8 +1693,7 @@ function normalizeWorkspaceEntry(entry = {}, index = 0, userCtx = {}) {
1653
1693
  };
1654
1694
  }
1655
1695
 
1656
- function readUserWorkspaces(userCtx = {}) {
1657
- const p = userWorkspacesPath(userCtx);
1696
+ function readWorkspacesFromPath(p, userCtx = {}) {
1658
1697
  if (!fs.existsSync(p)) return [];
1659
1698
  try {
1660
1699
  const data = JSON.parse(fs.readFileSync(p, "utf-8"));
@@ -1665,6 +1704,49 @@ function readUserWorkspaces(userCtx = {}) {
1665
1704
  }
1666
1705
  }
1667
1706
 
1707
+ function readLegacyAdminWorkspaces(userCtx = {}) {
1708
+ const users = readAuthUsers();
1709
+ const candidates = [];
1710
+ for (const [userId, user] of Object.entries(users || {})) {
1711
+ if (user?.isAdmin) candidates.push(String(userId || ""));
1712
+ }
1713
+ if (userCtx?.isAdmin && userCtx.userId) candidates.unshift(String(userCtx.userId));
1714
+ const seenPaths = new Set();
1715
+ const seenEntries = new Set();
1716
+ const out = [];
1717
+ for (const userId of candidates) {
1718
+ const p = legacyUserWorkspacesPath({ userId });
1719
+ const resolved = path.resolve(p);
1720
+ if (seenPaths.has(resolved) || resolved === path.resolve(workspacesPath())) continue;
1721
+ seenPaths.add(resolved);
1722
+ for (const entry of readWorkspacesFromPath(p, { userId })) {
1723
+ const key = entry.id || entry.path || entry.repoUrl;
1724
+ if (seenEntries.has(key)) continue;
1725
+ seenEntries.add(key);
1726
+ out.push(entry);
1727
+ }
1728
+ }
1729
+ return out;
1730
+ }
1731
+
1732
+ function readUserWorkspaces(userCtx = {}) {
1733
+ const globalPath = workspacesPath();
1734
+ const globalWorkspaces = fs.existsSync(globalPath) ? readWorkspacesFromPath(globalPath, userCtx) : [];
1735
+ const adminLegacy = readLegacyAdminWorkspaces(userCtx);
1736
+ if (globalWorkspaces.length || adminLegacy.length) {
1737
+ const seen = new Set();
1738
+ const out = [];
1739
+ for (const entry of [...globalWorkspaces, ...adminLegacy]) {
1740
+ const key = entry.id || entry.path || entry.repoUrl;
1741
+ if (seen.has(key)) continue;
1742
+ seen.add(key);
1743
+ out.push(entry);
1744
+ }
1745
+ return out;
1746
+ }
1747
+ return readWorkspacesFromPath(legacyUserWorkspacesPath(userCtx), userCtx);
1748
+ }
1749
+
1668
1750
  function writeUserWorkspaces(userCtx = {}, entries = []) {
1669
1751
  const seen = new Set();
1670
1752
  const workspaces = (Array.isArray(entries) ? entries : [])
@@ -1676,7 +1758,7 @@ function writeUserWorkspaces(userCtx = {}, entries = []) {
1676
1758
  seen.add(key);
1677
1759
  return true;
1678
1760
  });
1679
- const p = userWorkspacesPath(userCtx);
1761
+ const p = workspacesPath();
1680
1762
  fs.mkdirSync(path.dirname(p), { recursive: true });
1681
1763
  fs.writeFileSync(p, JSON.stringify({ version: 1, workspaces }, null, 2) + "\n", "utf-8");
1682
1764
  return workspaces;
@@ -7752,7 +7834,7 @@ export function startUiServer({
7752
7834
  }, userCtx);
7753
7835
  const scopedRoot = scoped.error ? root : scoped.root;
7754
7836
  json(res, 200, {
7755
- path: userWorkspacesPath(userCtx),
7837
+ path: workspacesPath(),
7756
7838
  workspaces: listConfiguredWorkspaces(root, scopedRoot, userCtx),
7757
7839
  customWorkspaces: readUserWorkspaces(userCtx),
7758
7840
  });
@@ -7767,7 +7849,7 @@ export function startUiServer({
7767
7849
  const payload = JSON.parse(await readBody(req));
7768
7850
  const customWorkspaces = writeUserWorkspaces(userCtx, payload?.workspaces || payload?.customWorkspaces || []);
7769
7851
  json(res, 200, {
7770
- path: userWorkspacesPath(userCtx),
7852
+ path: workspacesPath(),
7771
7853
  workspaces: listConfiguredWorkspaces(root, root, userCtx),
7772
7854
  customWorkspaces,
7773
7855
  });