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.
package/dist/client/index.html
CHANGED
|
@@ -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-
|
|
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.
|
|
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",
|
package/src/client/App.tsx
CHANGED
|
@@ -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) } : {}) });
|
package/src/server/share-file.ts
CHANGED
|
@@ -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
|
|
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
|
|
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 }) => {
|