@fieldwangai/agentflow 0.1.89 → 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.
package/bin/lib/ui-server.mjs
CHANGED
|
@@ -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
|
|
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
|
|
1636
|
-
const
|
|
1637
|
-
const
|
|
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
|
|
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 =
|
|
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:
|
|
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:
|
|
7852
|
+
path: workspacesPath(),
|
|
7771
7853
|
workspaces: listConfiguredWorkspaces(root, root, userCtx),
|
|
7772
7854
|
customWorkspaces,
|
|
7773
7855
|
});
|