shraga 0.1.116 → 0.1.118

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.
@@ -13,7 +13,7 @@
13
13
  <link rel="preconnect" href="https://fonts.googleapis.com" />
14
14
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15
15
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
16
- <script type="module" crossorigin src="/assets/index-Dtb440uD.js"></script>
16
+ <script type="module" crossorigin src="/assets/index-Cy5kfZ66.js"></script>
17
17
  <link rel="stylesheet" crossorigin href="/assets/index-CFxKc8dH.css">
18
18
  </head>
19
19
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shraga",
3
- "version": "0.1.116",
3
+ "version": "0.1.118",
4
4
  "description": "The teammate you delegate coding to — a self-hostable, multi-user AI coding agent web UI (Claude Code, with a pluggable engine seam).",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -72,7 +72,7 @@ function AppInner() {
72
72
  const slots = useSlots();
73
73
  const { dark, toggle: toggleDark } = useDarkMode();
74
74
  const { user, token, getToken, loading, mode, needsSetup, loginLocal, registerLocal, logout } = useAuth();
75
- const { isOwner, call: ownerCall } = useOwner(getToken);
75
+ const { isOwner, call: ownerCall } = useOwner(getToken, !!user); // re-checks once signed in — App mounts before the token exists
76
76
  const [sidebarOpen, _setSidebarOpen] = useState(() => localStorage.getItem('shraga:sidebarOpen') !== 'false');
77
77
  const setSidebarOpen = useCallback((v: boolean | ((prev: boolean) => boolean)) => {
78
78
  _setSidebarOpen((prev) => {
@@ -8,7 +8,7 @@ export function useIsOwner(getToken: () => Promise<string | null>, enabled = tru
8
8
  const [isOwner, setIsOwner] = useState<boolean>();
9
9
 
10
10
  useEffect(() => {
11
- if (!enabled) return;
11
+ if (!enabled) { setIsOwner(undefined); return; }
12
12
  let alive = true;
13
13
  getToken().then((token) => {
14
14
  if (!token || !alive) return;
@@ -6,8 +6,8 @@ import { useIsOwner } from './useIsOwner';
6
6
  export type OwnerCall = <T = any>(path: string, method?: string, body?: unknown) => Promise<T>;
7
7
 
8
8
  /** Owner Console access: `isOwner` (UI hint — the server enforces) + an authenticated caller for `/api/owner/*`. */
9
- export function useOwner(getToken: () => Promise<string | null>) {
10
- const isOwner = useIsOwner(getToken);
9
+ export function useOwner(getToken: () => Promise<string | null>, enabled = true) {
10
+ const isOwner = useIsOwner(getToken, enabled);
11
11
  const call = useCallback<OwnerCall>(async (path, method = 'GET', body) => {
12
12
  try {
13
13
  return await api(`/api/owner${path}`, getToken, { method, ...(body !== undefined ? { body: JSON.stringify(body) } : {}) });
@@ -6,7 +6,6 @@ import { mkdirSync, realpathSync, statSync } from 'node:fs';
6
6
  import { copyFile, stat, unlink } from 'node:fs/promises';
7
7
  import type { ServerResponse } from 'node:http';
8
8
  import { randomBytes } from 'node:crypto';
9
- import { tmpdir } from 'node:os';
10
9
  import path from 'node:path';
11
10
  import { z } from 'zod/v4';
12
11
  import { DATA_DIR } from './paths.ts';
@@ -21,7 +20,7 @@ export class FileSharerOptions {
21
20
  dataDir: string = DATA_DIR;
22
21
  /** ALLOWLIST of dirs agents write deliverables to (resolved by realpath). Never the whole data dir: it holds tokens,
23
22
  * config and other sessions' auth-protected uploads. */
24
- roots: () => string[] = () => [WORKSPACE_DIR, tmpdir(), '/tmp'];
23
+ roots: () => string[] = () => [WORKSPACE_DIR]; // not tmp: other processes' task outputs/credentials live there
25
24
  /** Largest file that may be published. */
26
25
  maxBytes: number = MAX_SHARE_BYTES;
27
26
  origin: () => string = getPublicOrigin;
@@ -103,7 +102,7 @@ export function shareMcpServer(sharer = new FileSharer()) {
103
102
  SHARE_TOOL,
104
103
  'Publish a local file (video, image, PDF, …) and get a public link to send the user. The ONLY valid way to make a file link — never construct share URLs by hand. Anyone with the link can open it (no login).',
105
104
  {
106
- file_path: z.string().min(1).describe('Absolute path of the file (under the workspace or tmp).'),
105
+ file_path: z.string().min(1).describe('Absolute path of the file (must be under the workspace; move deliverables there first).'),
107
106
  name: z.string().max(200).optional().describe('Download name, e.g. "ad-v2.mp4". Defaults to the file name.'),
108
107
  },
109
108
  async ({ file_path, name }) => {