wiki-viewer 1.8.0 → 1.8.2

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 (51) hide show
  1. package/.next/standalone/.github/workflows/publish.yml +1 -1
  2. package/.next/standalone/.next/BUILD_ID +1 -1
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/index.html +1 -1
  21. package/.next/standalone/.next/server/app/index.rsc +2 -2
  22. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  27. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0269d2e._.js +1 -1
  29. package/.next/standalone/.next/server/chunks/ssr/_0pqaawz._.js +1 -1
  30. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  31. package/.next/standalone/.next/server/middleware-manifest.json +1 -1
  32. package/.next/standalone/.next/server/pages/404.html +1 -1
  33. package/.next/standalone/.next/server/pages/500.html +1 -1
  34. package/.next/standalone/.next/static/chunks/{0l4842ez-0_66.js → 16r--8~rpehcz.js} +1 -1
  35. package/.next/standalone/agents/bootstrap-prompt.md +3 -1
  36. package/.next/standalone/agents/wiki-viewer-skill/SKILL.md +38 -11
  37. package/.next/standalone/package.json +1 -1
  38. package/.next/standalone/packages/wiki-viewer-mcp/README.md +6 -5
  39. package/.next/standalone/packages/wiki-viewer-mcp/dist/http-client.js +4 -0
  40. package/.next/standalone/packages/wiki-viewer-mcp/dist/index.js +4 -0
  41. package/.next/standalone/packages/wiki-viewer-mcp/package-lock.json +2 -2
  42. package/.next/standalone/packages/wiki-viewer-mcp/package.json +1 -1
  43. package/.next/standalone/packages/wiki-viewer-mcp/src/http-client.ts +6 -0
  44. package/.next/standalone/packages/wiki-viewer-mcp/src/index.ts +5 -0
  45. package/.next/standalone/src/app/api/agents/install/route.ts +20 -2
  46. package/.next/standalone/src/app/page.tsx +51 -1
  47. package/.next/standalone/tsconfig.tsbuildinfo +1 -1
  48. package/package.json +1 -1
  49. /package/.next/standalone/.next/static/{t7B6nXaoD1jo9f61t3aeK → t_k0ztuf0V-iA-kgeez18}/_buildManifest.js +0 -0
  50. /package/.next/standalone/.next/static/{t7B6nXaoD1jo9f61t3aeK → t_k0ztuf0V-iA-kgeez18}/_clientMiddlewareManifest.js +0 -0
  51. /package/.next/standalone/.next/static/{t7B6nXaoD1jo9f61t3aeK → t_k0ztuf0V-iA-kgeez18}/_ssgManifest.js +0 -0
@@ -74,9 +74,25 @@ export async function GET(req: NextRequest): Promise<NextResponse> {
74
74
  { method: "GET", path: "/api/agent/fs/ls/<path>", auth: "bearer+agent-id", purpose: "Directory listing. ?recursive&limit&depth. Scope-filtered. Excludes .proof/." },
75
75
  { method: "POST", path: "/api/agent/fs/move", auth: "bearer+agent-id", purpose: "Move/rename. Body: {from, to, ifMatch?}. Moves .md sidecar too." },
76
76
  { method: "POST", path: "/api/agent/fs/search", auth: "bearer+agent-id", purpose: "Server-side grep or glob. Body: {kind:'grep'|'glob', query, path?, glob?, limit?}." },
77
+ // Settings (resolved workspace root, rate limit)
78
+ { method: "GET", path: "/api/agent/settings", auth: "bearer+agent-id", purpose: "Returns rateLimit + resolved 'root' (the active workspace's directory for the X-Workspace you send)." },
77
79
  // Human presence (for editor lease — drives active collab-state)
78
80
  { method: "POST", path: "/api/wiki/presence", auth: "session", purpose: "Human editor lease heartbeat. Body: {path, action:'open'|'heartbeat'|'close'}." },
79
81
  ],
82
+ workspaces: {
83
+ description:
84
+ "This instance can serve multiple root directories ('workspaces'). Every agent path is relative to ONE workspace root.",
85
+ header: "X-Workspace: <workspaceId>",
86
+ queryParam: "ws=<workspaceId>",
87
+ default:
88
+ "If omitted, the server resolves to the most-recently-opened workspace. Correct for single-workspace instances; be explicit when several exist.",
89
+ discoverId:
90
+ "Ask the human for the workspace id, read it from the ?ws= param of a pasted wiki-viewer URL, or call GET /api/agent/settings (with X-Workspace) to confirm the resolved 'root'.",
91
+ scoped:
92
+ "A token may be pinned to one workspace (scope.workspaceId at approval). Requests resolving to a different workspace return 403 FORBIDDEN. A token with no pin is wildcard (any workspace).",
93
+ isolation:
94
+ "Paths in one workspace never touch another, even with identical relative paths.",
95
+ },
80
96
  capabilities: {
81
97
  maxFileBytes: MAX_FILE_BYTES,
82
98
  supportsRange: true,
@@ -85,6 +101,8 @@ export async function GET(req: NextRequest): Promise<NextResponse> {
85
101
  search: ["grep", "glob"],
86
102
  globDialect: "**,*,?",
87
103
  scopeOps: ["read", "mutate", "delete"],
104
+ scopeWorkspaceId: true,
105
+ workspaceHeader: "X-Workspace",
88
106
  collabStates: ["active", "tracked", "untracked", "not-markdown"],
89
107
  collabPrecondition: "If-Collab-Match",
90
108
  },
@@ -103,8 +121,8 @@ export async function GET(req: NextRequest): Promise<NextResponse> {
103
121
  mcpAdapter: {
104
122
  package: "wiki-viewer-mcp",
105
123
  invoke: "npx wiki-viewer-mcp",
106
- env: ["WIKI_VIEWER_URL", "WIKI_VIEWER_TOKEN", "WIKI_VIEWER_AGENT_ID"],
107
- description: "Thin MCP adapter mapping standard MCP filesystem tools onto these endpoints. Reads X-Collab-State and blocks or warns on raw writes to active .md files.",
124
+ env: ["WIKI_VIEWER_URL", "WIKI_VIEWER_TOKEN", "WIKI_VIEWER_AGENT_ID", "WIKI_VIEWER_WORKSPACE"],
125
+ description: "Thin MCP adapter mapping standard MCP filesystem tools onto these endpoints. Set WIKI_VIEWER_WORKSPACE to target a specific workspace (sends X-Workspace on every call). Reads X-Collab-State and blocks or warns on raw writes to active .md files.",
108
126
  },
109
127
  ops: [
110
128
  "block.replace",
@@ -230,6 +230,7 @@ export default function Page() {
230
230
  const [workspaces, setWorkspaces] = useState<Array<{id:string;name:string;rootDir:string;lastOpenedAt?:string;createdAt:string}>>([]);
231
231
  const [isWsAdmin, setIsWsAdmin] = useState(false);
232
232
  const [addingWorkspace, setAddingWorkspace] = useState(false);
233
+ const [deletingWorkspaceId, setDeletingWorkspaceId] = useState<string | null>(null);
233
234
 
234
235
  const loadWorkspaces = useCallback(async () => {
235
236
  try {
@@ -678,6 +679,33 @@ export default function Page() {
678
679
  setActiveWorkspaceId(id);
679
680
  }, [activeWorkspaceId, workspaces]);
680
681
 
682
+ const handleDeleteWorkspace = useCallback(async () => {
683
+ if (!deletingWorkspaceId) return;
684
+ try {
685
+ const res = await fetch(`/api/system/workspaces/${deletingWorkspaceId}`, {
686
+ method: "DELETE",
687
+ });
688
+ if (!res.ok) throw new Error("Failed");
689
+ // If deleting the active workspace, switch to first available or picker
690
+ if (deletingWorkspaceId === activeWorkspaceId) {
691
+ const remaining = workspaces.filter((w) => w.id !== deletingWorkspaceId);
692
+ if (remaining.length > 0) {
693
+ const next = [...remaining].sort(
694
+ (a, b) => (b.lastOpenedAt ?? b.createdAt).localeCompare(a.lastOpenedAt ?? a.createdAt)
695
+ )[0];
696
+ await switchWorkspace(next.id);
697
+ } else {
698
+ setRootConfigured(false);
699
+ }
700
+ }
701
+ await loadWorkspaces();
702
+ } catch {
703
+ /* ignore */
704
+ } finally {
705
+ setDeletingWorkspaceId(null);
706
+ }
707
+ }, [deletingWorkspaceId, activeWorkspaceId, workspaces, switchWorkspace, loadWorkspaces]);
708
+
681
709
  async function handleSave() {
682
710
  if (!openFile) return;
683
711
  setSaving(true);
@@ -1477,10 +1505,22 @@ export default function Page() {
1477
1505
  ) : (
1478
1506
  <span className="w-3.5 shrink-0" />
1479
1507
  )}
1480
- <span className="flex flex-col min-w-0">
1508
+ <span className="flex flex-col min-w-0 flex-1">
1481
1509
  <span className="truncate">{w.name}</span>
1482
1510
  <span className="truncate text-[10px] text-muted-foreground font-mono">{w.rootDir}</span>
1483
1511
  </span>
1512
+ {isWsAdmin && (
1513
+ <button
1514
+ className="ml-auto shrink-0 rounded p-0.5 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors"
1515
+ title="Delete workspace (does not delete files)"
1516
+ onClick={(e) => {
1517
+ e.stopPropagation();
1518
+ setDeletingWorkspaceId(w.id);
1519
+ }}
1520
+ >
1521
+ <Trash2 className="h-3.5 w-3.5" />
1522
+ </button>
1523
+ )}
1484
1524
  </DropdownMenuItem>
1485
1525
  ))}
1486
1526
  {isWsAdmin && (
@@ -1891,6 +1931,16 @@ export default function Page() {
1891
1931
  }
1892
1932
  onConfirm={handleDelete}
1893
1933
  />
1934
+
1935
+ <ConfirmDialog
1936
+ open={!!deletingWorkspaceId}
1937
+ onOpenChange={(open) => {
1938
+ if (!open) setDeletingWorkspaceId(null);
1939
+ }}
1940
+ title="Delete workspace?"
1941
+ description={`"${workspaces.find((w) => w.id === deletingWorkspaceId)?.name ?? ""}" will be removed from the workspace list. Files on disk are NOT deleted.`}
1942
+ onConfirm={handleDeleteWorkspace}
1943
+ />
1894
1944
  </>}
1895
1945
  </div>
1896
1946
  );