weifuwu 0.24.1 → 0.24.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.
- package/README.md +818 -712
- package/cli/template/app.ts +5 -1
- package/cli/template/index.ts +4 -1
- package/cli/template/locales/en.json +6 -1
- package/cli/template/locales/zh-CN.json +6 -1
- package/cli/template/locales/zh-TW.json +6 -1
- package/cli/template/locales/zh.json +6 -1
- package/cli/template/ui/app/globals.css +1 -1
- package/cli/template/ui/app/page.tsx +55 -16
- package/cli.ts +148 -104
- package/dist/agent/rest.d.ts +1 -1
- package/dist/agent/run.d.ts +2 -2
- package/dist/ai/workflow.d.ts +1 -1
- package/dist/ai-sdk.d.ts +1 -1
- package/dist/cli.js +135 -97
- package/dist/cookie.d.ts +24 -0
- package/dist/fts.d.ts +5 -5
- package/dist/iii/index.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +787 -346
- package/dist/live.d.ts +2 -3
- package/dist/logdb/rest.d.ts +1 -1
- package/dist/mailer.d.ts +1 -1
- package/dist/messager/agent.d.ts +2 -2
- package/dist/messager/rest.d.ts +3 -3
- package/dist/messager/ws.d.ts +3 -3
- package/dist/opencode/index.d.ts +1 -1
- package/dist/opencode/permissions.d.ts +1 -1
- package/dist/opencode/run.d.ts +1 -1
- package/dist/opencode/session.d.ts +9 -9
- package/dist/opencode/tools/web.d.ts +1 -1
- package/dist/opencode/ws.d.ts +1 -2
- package/dist/permissions.d.ts +2 -2
- package/dist/postgres/module.d.ts +3 -3
- package/dist/postgres/schema/index.d.ts +1 -1
- package/dist/postgres/schema/table.d.ts +22 -20
- package/dist/postgres/types.d.ts +4 -4
- package/dist/queue/types.d.ts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +135 -90
- package/dist/router.d.ts +10 -10
- package/dist/session.d.ts +1 -2
- package/dist/tenant/graphql.d.ts +2 -2
- package/dist/tenant/index.d.ts +1 -1
- package/dist/tenant/rest.d.ts +2 -2
- package/dist/test-utils.d.ts +3 -3
- package/dist/user/index.d.ts +1 -1
- package/dist/user/oauth-login.d.ts +2 -2
- package/dist/vendor.d.ts +4 -0
- package/opencode/ui/app/globals.css +1 -1
- package/opencode/ui/app/layout.tsx +2 -3
- package/opencode/ui/app/page.tsx +302 -73
- package/package.json +26 -3
- package/cli/template/.weifuwu/ssr/2e3a7e60.js +0 -112
package/dist/live.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Router } from './router.ts';
|
|
2
|
-
import type { WebSocketHandler } from './router.ts';
|
|
1
|
+
import { Router, type WebSocketHandler } from './router.ts';
|
|
3
2
|
export declare function broadcastReload(): void;
|
|
4
3
|
export declare function liveWs(): WebSocketHandler;
|
|
5
|
-
export declare function liveRouter(
|
|
4
|
+
export declare function liveRouter(_dir: string): Router;
|
|
6
5
|
export declare function liveWatcher(dir: string): {
|
|
7
6
|
close: () => void;
|
|
8
7
|
};
|
package/dist/logdb/rest.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type BoundTable } from '../postgres/schema/index.ts';
|
|
2
2
|
import type { Context } from '../types.ts';
|
|
3
3
|
export declare function createHandler(entries: BoundTable<any>): (req: Request, ctx: Context) => Promise<Response>;
|
|
4
4
|
export declare function listHandler(entries: BoundTable<any>): (req: Request) => Promise<Response>;
|
package/dist/mailer.d.ts
CHANGED
package/dist/messager/agent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import type { AgentModule } from '../agent/types.ts';
|
|
3
3
|
import type { Hub } from '../hub.ts';
|
|
4
4
|
/**
|
|
@@ -6,6 +6,6 @@ import type { Hub } from '../hub.ts';
|
|
|
6
6
|
* - Streaming: broadcasts SSE text tokens in real-time
|
|
7
7
|
* - Multi-round: passes recent channel history as conversation context
|
|
8
8
|
*/
|
|
9
|
-
export declare function runAgentRouting(sql:
|
|
9
|
+
export declare function runAgentRouting(sql: SqlClient, messages: {
|
|
10
10
|
insert: (data: any) => Promise<any>;
|
|
11
11
|
}, agents: AgentModule | undefined, hub: Hub, channelId: number, content: string, stream?: boolean, contextMessages?: number): Promise<void>;
|
package/dist/messager/rest.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import { Router } from '../router.ts';
|
|
3
3
|
import type { AgentModule } from '../agent/types.ts';
|
|
4
4
|
import type { Hub } from '../hub.ts';
|
|
5
|
-
import type
|
|
5
|
+
import { type BoundTable } from '../postgres/schema/index.ts';
|
|
6
6
|
interface RestDeps {
|
|
7
|
-
sql:
|
|
7
|
+
sql: SqlClient;
|
|
8
8
|
channels: BoundTable<any>;
|
|
9
9
|
members: BoundTable<any>;
|
|
10
10
|
messages: BoundTable<any>;
|
package/dist/messager/ws.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import type { AgentModule } from '../agent/types.ts';
|
|
3
|
-
import type
|
|
3
|
+
import { type Hub } from '../hub.ts';
|
|
4
4
|
interface WSDeps {
|
|
5
|
-
sql:
|
|
5
|
+
sql: SqlClient;
|
|
6
6
|
agents?: AgentModule;
|
|
7
7
|
redis?: import('../vendor.ts').Redis;
|
|
8
8
|
}
|
package/dist/opencode/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { opencode } from './client.ts';
|
|
2
|
-
export type { OpencodeOptions, OpencodeModule, SkillDef, SkillRegistry, OpencodePermissions, Session } from './types.ts';
|
|
2
|
+
export type { OpencodeOptions, OpencodeModule, SkillDef, SkillRegistry, OpencodePermissions, Session, } from './types.ts';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OpencodePermissions } from './types.ts';
|
|
2
2
|
export declare function isCommandAllowed(command: string): boolean;
|
|
3
|
-
export declare function isPathAllowed(resolvedPath: string, workspace: string,
|
|
3
|
+
export declare function isPathAllowed(resolvedPath: string, workspace: string, _perms?: OpencodePermissions): boolean;
|
|
4
4
|
export declare function isToolEnabled(name: string, perms?: OpencodePermissions): boolean;
|
|
5
5
|
export declare function isSkillAllowed(name: string, perms?: OpencodePermissions): boolean;
|
package/dist/opencode/run.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import type { Session, Message } from './types.ts';
|
|
3
|
-
export declare function createSession(sql:
|
|
3
|
+
export declare function createSession(sql: SqlClient, opts: {
|
|
4
4
|
userId?: number;
|
|
5
5
|
title?: string;
|
|
6
6
|
model?: string;
|
|
7
7
|
systemPrompt?: string;
|
|
8
8
|
}, cwd: string, mountPath: string): Promise<Session>;
|
|
9
|
-
export declare function getSession(sql:
|
|
10
|
-
export declare function listSessions(sql:
|
|
11
|
-
export declare function deleteSession(sql:
|
|
12
|
-
export declare function getHistory(sql:
|
|
9
|
+
export declare function getSession(sql: SqlClient, id: string): Promise<Session | null>;
|
|
10
|
+
export declare function listSessions(sql: SqlClient, userId?: number): Promise<Session[]>;
|
|
11
|
+
export declare function deleteSession(sql: SqlClient, id: string): Promise<void>;
|
|
12
|
+
export declare function getHistory(sql: SqlClient, sessionId: string, limit?: number): Promise<SessionMessage[]>;
|
|
13
13
|
export interface SessionMessage {
|
|
14
14
|
id: number;
|
|
15
15
|
session_id: string;
|
|
@@ -21,6 +21,6 @@ export interface SessionMessage {
|
|
|
21
21
|
tokens_out: number;
|
|
22
22
|
created_at: string;
|
|
23
23
|
}
|
|
24
|
-
export declare function addTextMessage(sql:
|
|
25
|
-
export declare function addToolMessages(sql:
|
|
26
|
-
export declare function updateSessionTitle(sql:
|
|
24
|
+
export declare function addTextMessage(sql: SqlClient, sessionId: string, role: 'user' | 'assistant', content: string, tokensIn?: number, tokensOut?: number): Promise<Message>;
|
|
25
|
+
export declare function addToolMessages(sql: SqlClient, sessionId: string, toolCalls: unknown[], toolResults: unknown[]): Promise<Message>;
|
|
26
|
+
export declare function updateSessionTitle(sql: SqlClient, id: string, title: string): Promise<void>;
|
package/dist/opencode/ws.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { WebSocket } from '../vendor.ts';
|
|
2
2
|
import type { LanguageModel } from 'ai';
|
|
3
3
|
import type { Context } from '../types.ts';
|
|
4
|
-
import type { PendingQuestion, SkillDef, SkillRegistry } from './types.ts';
|
|
5
|
-
import type { OpencodePermissions } from './types.ts';
|
|
4
|
+
import type { PendingQuestion, SkillDef, SkillRegistry, OpencodePermissions } from './types.ts';
|
|
6
5
|
interface WsDeps {
|
|
7
6
|
sql: any;
|
|
8
7
|
model: LanguageModel;
|
package/dist/permissions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from './vendor.ts';
|
|
2
2
|
import type { Middleware, Context, Handler } from './types.ts';
|
|
3
3
|
declare module './types.ts' {
|
|
4
4
|
interface Context {
|
|
@@ -11,7 +11,7 @@ declare module './types.ts' {
|
|
|
11
11
|
export interface PermissionsOptions {
|
|
12
12
|
/** PostgreSQL client. */
|
|
13
13
|
pg: {
|
|
14
|
-
sql:
|
|
14
|
+
sql: SqlClient;
|
|
15
15
|
};
|
|
16
16
|
/** Table prefix (default: '' → _roles, _user_roles, _role_permissions). */
|
|
17
17
|
prefix?: string;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { PostgresClient } from './types.ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SqlClient } from '../vendor.ts';
|
|
3
3
|
import type { ColumnBuilder, BoundTable, Table } from './schema/index.ts';
|
|
4
4
|
import type { Closeable } from '../types.ts';
|
|
5
5
|
export declare class PgModule implements Closeable {
|
|
6
|
-
protected sql:
|
|
6
|
+
protected sql: SqlClient;
|
|
7
7
|
protected pg: PostgresClient;
|
|
8
8
|
constructor(pg: PostgresClient);
|
|
9
9
|
table<R extends Record<string, unknown>>(tableOrSchema: string | Table<R>, builders?: {
|
|
10
10
|
[K in keyof R]: ColumnBuilder<R[K]>;
|
|
11
11
|
}): BoundTable<R>;
|
|
12
|
-
transaction<T>(fn: (sql:
|
|
12
|
+
transaction<T>(fn: (sql: SqlClient) => Promise<T>, retryOpts?: {
|
|
13
13
|
maxRetries?: number;
|
|
14
14
|
}): Promise<T>;
|
|
15
15
|
migrate(): Promise<void>;
|
|
@@ -3,4 +3,4 @@ export { ColumnBuilder, serial, uuid, text, integer, boolean as boolean, boolean
|
|
|
3
3
|
export type { PartitionByDef } from './columns.ts';
|
|
4
4
|
export { pgTable, Table, BoundTable } from './table.ts';
|
|
5
5
|
export type { IndexOptions, FindOptions, CreateOptions } from './table.ts';
|
|
6
|
-
export { eq, ne, gt, gte, lt, lte, isNull, isNotNull, like, contains, in_, and, or, not } from './where.ts';
|
|
6
|
+
export { eq, ne, gt, gte, lt, lte, isNull, isNotNull, like, contains, in_, and, or, not, } from './where.ts';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../../vendor.ts';
|
|
2
2
|
import { ColumnBuilder, type PartitionByDef } from './columns.ts';
|
|
3
3
|
import { SQL } from './sql.ts';
|
|
4
4
|
/** Options for table index creation. */
|
|
@@ -64,39 +64,41 @@ export declare class Table<R extends Record<string, unknown>> {
|
|
|
64
64
|
* Bind this table schema to a SQL connection, returning a `BoundTable`
|
|
65
65
|
* that can run queries without passing `sql` to every call.
|
|
66
66
|
*/
|
|
67
|
-
bind(sql:
|
|
67
|
+
bind(sql: SqlClient): BoundTable<R>;
|
|
68
68
|
/** Returns the primary key column name (DB name), or 'id' as fallback. */
|
|
69
69
|
private get pkColumn();
|
|
70
70
|
/** Adds `deleted_at IS NULL` condition if the table has soft delete and not explicitly excluded. */
|
|
71
71
|
private _softDeleteFilter;
|
|
72
|
-
create(sql:
|
|
73
|
-
drop(sql:
|
|
72
|
+
create(sql: SqlClient, opts?: CreateOptions): Promise<void>;
|
|
73
|
+
drop(sql: SqlClient, opts?: {
|
|
74
74
|
cascade?: boolean;
|
|
75
75
|
}): Promise<void>;
|
|
76
|
-
createIndex(sql:
|
|
77
|
-
createUniqueIndex(sql:
|
|
76
|
+
createIndex(sql: SqlClient, columns: string | string[], opts?: IndexOptions): Promise<void>;
|
|
77
|
+
createUniqueIndex(sql: SqlClient, columns: string | string[]): Promise<void>;
|
|
78
78
|
private _buildConditions;
|
|
79
79
|
private _buildSET;
|
|
80
|
-
insert(sql:
|
|
81
|
-
insertMany(sql:
|
|
82
|
-
read(sql:
|
|
83
|
-
readMany(sql:
|
|
80
|
+
insert(sql: SqlClient, data: Partial<R>): Promise<R>;
|
|
81
|
+
insertMany(sql: SqlClient, data: Partial<R>[]): Promise<R[]>;
|
|
82
|
+
read(sql: SqlClient, id: string | number, opts?: Pick<FindOptions, 'select' | 'withDeleted'>): Promise<R | undefined>;
|
|
83
|
+
readMany(sql: SqlClient, where?: Partial<R> | SQL | SQL[], opts?: FindOptions): Promise<{
|
|
84
84
|
count: number;
|
|
85
85
|
data: R[];
|
|
86
86
|
}>;
|
|
87
|
-
update(sql:
|
|
88
|
-
updateMany(sql:
|
|
89
|
-
delete(sql:
|
|
90
|
-
hardDelete(sql:
|
|
91
|
-
deleteMany(sql:
|
|
92
|
-
hardDeleteMany(sql:
|
|
93
|
-
upsert(sql:
|
|
94
|
-
count(sql:
|
|
87
|
+
update(sql: SqlClient, id: string | number, data: Partial<R>): Promise<R | undefined>;
|
|
88
|
+
updateMany(sql: SqlClient, where: Partial<R> | SQL | SQL[], data: Partial<R>): Promise<number>;
|
|
89
|
+
delete(sql: SqlClient, id: string | number): Promise<R | undefined>;
|
|
90
|
+
hardDelete(sql: SqlClient, id: string | number): Promise<R | undefined>;
|
|
91
|
+
deleteMany(sql: SqlClient, where: Partial<R> | SQL | SQL[]): Promise<number>;
|
|
92
|
+
hardDeleteMany(sql: SqlClient, where: Partial<R> | SQL | SQL[]): Promise<number>;
|
|
93
|
+
upsert(sql: SqlClient, data: Partial<R>, conflict: string | string[]): Promise<R>;
|
|
94
|
+
count(sql: SqlClient, where?: Partial<R> | SQL | SQL[]): Promise<number>;
|
|
95
95
|
}
|
|
96
96
|
export declare class BoundTable<R extends Record<string, unknown>> {
|
|
97
97
|
private inner;
|
|
98
98
|
private sql;
|
|
99
|
-
|
|
99
|
+
/** The underlying table name. */
|
|
100
|
+
get tableName(): string;
|
|
101
|
+
constructor(sql: SqlClient, tableName: string, builders: Record<string, ColumnBuilder<unknown>>);
|
|
100
102
|
create(opts?: CreateOptions): Promise<void>;
|
|
101
103
|
drop(opts?: {
|
|
102
104
|
cascade?: boolean;
|
|
@@ -118,7 +120,7 @@ export declare class BoundTable<R extends Record<string, unknown>> {
|
|
|
118
120
|
hardDeleteMany(where: Partial<R> | SQL | SQL[]): Promise<number>;
|
|
119
121
|
upsert(data: Partial<R>, conflict: string | string[]): Promise<R>;
|
|
120
122
|
count(where?: Partial<R> | SQL | SQL[]): Promise<number>;
|
|
121
|
-
withSql(sql:
|
|
123
|
+
withSql(sql: SqlClient): BoundTable<R>;
|
|
122
124
|
}
|
|
123
125
|
/**
|
|
124
126
|
* Define a type-safe table schema.
|
package/dist/postgres/types.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import type { Context, Middleware, Closeable } from '../types.ts';
|
|
3
3
|
import type { ColumnBuilder, BoundTable, Table } from './schema/index.ts';
|
|
4
4
|
declare module '../types.ts' {
|
|
5
5
|
interface Context {
|
|
6
|
-
sql:
|
|
6
|
+
sql: SqlClient;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
export interface PostgresInjected {
|
|
10
|
-
sql:
|
|
10
|
+
sql: SqlClient;
|
|
11
11
|
}
|
|
12
12
|
export interface PostgresOptions {
|
|
13
13
|
connection?: string | Record<string, unknown>;
|
|
@@ -23,7 +23,7 @@ export interface PostgresOptions {
|
|
|
23
23
|
onQuery?: (query: string, durationMs: number, rowCount: number) => void;
|
|
24
24
|
}
|
|
25
25
|
export interface PostgresClient extends Middleware<Context, Context & PostgresInjected>, Closeable {
|
|
26
|
-
sql:
|
|
26
|
+
sql: SqlClient;
|
|
27
27
|
/** Creates the migration tracking table (_weifuwu_migrations). Called once at startup. */
|
|
28
28
|
migrate: () => Promise<void>;
|
|
29
29
|
/** Record that a module's migration has been applied (idempotent). */
|
package/dist/queue/types.d.ts
CHANGED
package/dist/react.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ export { useLocale } from './client-locale.ts';
|
|
|
11
11
|
export { useTheme, applyTheme } from './client-theme.ts';
|
|
12
12
|
export { useFlashMessage } from './use-flash-message.ts';
|
|
13
13
|
export { useAgentStream } from './use-agent-stream.ts';
|
|
14
|
-
export type { UseAgentStreamOptions, UseAgentStreamReturn, AgentStreamState } from './use-agent-stream.ts';
|
|
14
|
+
export type { UseAgentStreamOptions, UseAgentStreamReturn, AgentStreamState, } from './use-agent-stream.ts';
|
package/dist/react.js
CHANGED
|
@@ -95,42 +95,45 @@ function useAction(url, options) {
|
|
|
95
95
|
const [error, setError] = useState2(null);
|
|
96
96
|
const [pending, setPending] = useState2(false);
|
|
97
97
|
const mountedRef = useRef2(true);
|
|
98
|
-
const submit = useCallback2(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
98
|
+
const submit = useCallback2(
|
|
99
|
+
async (body) => {
|
|
100
|
+
setPending(true);
|
|
101
|
+
setError(null);
|
|
102
|
+
try {
|
|
103
|
+
const csrfToken = getCsrfToken();
|
|
104
|
+
const hdrs = { ...headers };
|
|
105
|
+
if (csrfToken) hdrs["x-csrf-token"] = csrfToken;
|
|
106
|
+
if (body && typeof body === "object" && !(body instanceof FormData)) {
|
|
107
|
+
hdrs["content-type"] = "application/json";
|
|
108
|
+
}
|
|
109
|
+
const res = await fetch(url, {
|
|
110
|
+
method,
|
|
111
|
+
headers: hdrs,
|
|
112
|
+
body: body instanceof FormData ? body : body !== void 0 ? JSON.stringify(body) : void 0
|
|
113
|
+
});
|
|
114
|
+
if (!res.ok) {
|
|
115
|
+
const text = await res.text();
|
|
116
|
+
throw new Error(text || `HTTP ${res.status}`);
|
|
117
|
+
}
|
|
118
|
+
const result = res.status === 204 ? void 0 : await res.json();
|
|
119
|
+
if (mountedRef.current) {
|
|
120
|
+
setData(result);
|
|
121
|
+
onSuccess?.(result);
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
} catch (err) {
|
|
125
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
126
|
+
if (mountedRef.current) {
|
|
127
|
+
setError(e);
|
|
128
|
+
onError?.(e);
|
|
129
|
+
}
|
|
130
|
+
return void 0;
|
|
131
|
+
} finally {
|
|
132
|
+
if (mountedRef.current) setPending(false);
|
|
128
133
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
}, [url, method, headers, onSuccess, onError]);
|
|
134
|
+
},
|
|
135
|
+
[url, method, headers, onSuccess, onError]
|
|
136
|
+
);
|
|
134
137
|
const reset = useCallback2(() => {
|
|
135
138
|
setData(null);
|
|
136
139
|
setError(null);
|
|
@@ -155,7 +158,15 @@ async function runInterceptors(url) {
|
|
|
155
158
|
|
|
156
159
|
// tsx-context.ts
|
|
157
160
|
import { useSyncExternalStore, createContext } from "react";
|
|
158
|
-
var DEFAULT_CTX = {
|
|
161
|
+
var DEFAULT_CTX = {
|
|
162
|
+
params: {},
|
|
163
|
+
query: {},
|
|
164
|
+
parsed: {},
|
|
165
|
+
loaderData: {},
|
|
166
|
+
env: {},
|
|
167
|
+
user: {},
|
|
168
|
+
flash: {}
|
|
169
|
+
};
|
|
159
170
|
var KEY = "__WEIFUWU_CTX_STORE";
|
|
160
171
|
function getStore() {
|
|
161
172
|
if (typeof globalThis !== "undefined" && globalThis[KEY]) {
|
|
@@ -163,12 +174,22 @@ function getStore() {
|
|
|
163
174
|
}
|
|
164
175
|
const s = {
|
|
165
176
|
_ctx: DEFAULT_CTX,
|
|
166
|
-
_snapshot: {
|
|
177
|
+
_snapshot: {
|
|
178
|
+
params: DEFAULT_CTX.params,
|
|
179
|
+
query: DEFAULT_CTX.query,
|
|
180
|
+
user: DEFAULT_CTX.user,
|
|
181
|
+
parsed: DEFAULT_CTX.parsed,
|
|
182
|
+
theme: DEFAULT_CTX.theme,
|
|
183
|
+
i18n: DEFAULT_CTX.i18n,
|
|
184
|
+
loaderData: DEFAULT_CTX.loaderData,
|
|
185
|
+
env: DEFAULT_CTX.env
|
|
186
|
+
},
|
|
167
187
|
_listeners: /* @__PURE__ */ new Set(),
|
|
168
188
|
_rebuilders: [],
|
|
169
189
|
_alsGetStore: null
|
|
170
190
|
};
|
|
171
191
|
if (typeof globalThis !== "undefined") {
|
|
192
|
+
;
|
|
172
193
|
globalThis[KEY] = s;
|
|
173
194
|
}
|
|
174
195
|
return s;
|
|
@@ -192,7 +213,16 @@ function setCtx(value) {
|
|
|
192
213
|
}
|
|
193
214
|
}
|
|
194
215
|
store._ctx = { ...store._ctx, ...value };
|
|
195
|
-
store._snapshot = {
|
|
216
|
+
store._snapshot = {
|
|
217
|
+
params: store._ctx.params,
|
|
218
|
+
query: store._ctx.query,
|
|
219
|
+
user: store._ctx.user,
|
|
220
|
+
parsed: store._ctx.parsed,
|
|
221
|
+
theme: store._ctx.theme,
|
|
222
|
+
i18n: store._ctx.i18n,
|
|
223
|
+
loaderData: store._ctx.loaderData,
|
|
224
|
+
env: store._ctx.env
|
|
225
|
+
};
|
|
196
226
|
if (typeof window !== "undefined") {
|
|
197
227
|
;
|
|
198
228
|
window.__WEIFUWU_CTX = { ...window.__WEIFUWU_CTX, ...value };
|
|
@@ -290,7 +320,9 @@ function applyHead(html) {
|
|
|
290
320
|
const doc = new DOMParser().parseFromString(headHtml, "text/html");
|
|
291
321
|
const newMeta = doc.querySelectorAll("meta");
|
|
292
322
|
const existing = document.querySelectorAll("head meta");
|
|
293
|
-
const newNames = new Set(
|
|
323
|
+
const newNames = new Set(
|
|
324
|
+
Array.from(newMeta).map((m) => m.getAttribute("name") || m.getAttribute("property") || "")
|
|
325
|
+
);
|
|
294
326
|
for (const el of existing) {
|
|
295
327
|
const key = el.getAttribute("name") || el.getAttribute("property") || "";
|
|
296
328
|
if (!newNames.has(key)) el.remove();
|
|
@@ -307,7 +339,8 @@ function applyHead(html) {
|
|
|
307
339
|
}
|
|
308
340
|
}
|
|
309
341
|
if (existingEl) {
|
|
310
|
-
for (const attr of el.attributes)
|
|
342
|
+
for (const attr of el.attributes)
|
|
343
|
+
existingEl.setAttribute(attr.name, attr.value);
|
|
311
344
|
} else {
|
|
312
345
|
document.head.appendChild(el.cloneNode());
|
|
313
346
|
}
|
|
@@ -345,27 +378,37 @@ function Link({ href, children, onClick, prefetch, ...props }) {
|
|
|
345
378
|
}
|
|
346
379
|
}
|
|
347
380
|
if (!el) return;
|
|
348
|
-
const observer = new IntersectionObserver(
|
|
349
|
-
|
|
350
|
-
|
|
381
|
+
const observer = new IntersectionObserver(
|
|
382
|
+
([entry]) => {
|
|
383
|
+
if (entry.isIntersecting) prefetchPage(href);
|
|
384
|
+
},
|
|
385
|
+
{ rootMargin: "200px" }
|
|
386
|
+
);
|
|
351
387
|
observer.observe(el);
|
|
352
388
|
return () => observer.disconnect();
|
|
353
389
|
}, [href, prefetch]);
|
|
354
390
|
const handleMouseEnter = useCallback3(() => {
|
|
355
391
|
if (prefetch) prefetchPage(href);
|
|
356
392
|
}, [href, prefetch]);
|
|
357
|
-
const handleClick = useCallback3(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
href,
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
393
|
+
const handleClick = useCallback3(
|
|
394
|
+
(e) => {
|
|
395
|
+
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
396
|
+
e.preventDefault();
|
|
397
|
+
doNavigate(href);
|
|
398
|
+
onClick?.(e);
|
|
399
|
+
},
|
|
400
|
+
[href, onClick, doNavigate]
|
|
401
|
+
);
|
|
402
|
+
return createElement(
|
|
403
|
+
"a",
|
|
404
|
+
{
|
|
405
|
+
href,
|
|
406
|
+
onClick: handleClick,
|
|
407
|
+
onMouseEnter: handleMouseEnter,
|
|
408
|
+
...props
|
|
409
|
+
},
|
|
410
|
+
children
|
|
411
|
+
);
|
|
369
412
|
}
|
|
370
413
|
async function prefetchPage(href) {
|
|
371
414
|
const cached = prefetchCache.get(href);
|
|
@@ -400,10 +443,7 @@ function createStore(initial) {
|
|
|
400
443
|
listeners.delete(listener);
|
|
401
444
|
};
|
|
402
445
|
};
|
|
403
|
-
const useStore = ((selector) => useSyncExternalStore2(
|
|
404
|
-
subscribe2,
|
|
405
|
-
() => selector ? selector(state) : state
|
|
406
|
-
));
|
|
446
|
+
const useStore = ((selector) => useSyncExternalStore2(subscribe2, () => selector ? selector(state) : state));
|
|
407
447
|
useStore.getState = getState;
|
|
408
448
|
useStore.setState = setState;
|
|
409
449
|
useStore.subscribe = subscribe2;
|
|
@@ -430,19 +470,23 @@ function useFetch(url, options) {
|
|
|
430
470
|
let cancelled = false;
|
|
431
471
|
const cached = dataCache.get(u);
|
|
432
472
|
if (cached && Date.now() - cached.timestamp < ttl) {
|
|
433
|
-
if (!cancelled)
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
473
|
+
if (!cancelled)
|
|
474
|
+
setState({
|
|
475
|
+
data: cached.data,
|
|
476
|
+
error: cached.error,
|
|
477
|
+
loading: false
|
|
478
|
+
});
|
|
438
479
|
return;
|
|
439
480
|
}
|
|
440
481
|
async function doFetch() {
|
|
441
482
|
if (!inflight.has(u)) {
|
|
442
|
-
inflight.set(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
483
|
+
inflight.set(
|
|
484
|
+
u,
|
|
485
|
+
fetch(u).then((r) => {
|
|
486
|
+
if (!r.ok) throw new Error(r.statusText || `HTTP ${r.status}`);
|
|
487
|
+
return r.json();
|
|
488
|
+
})
|
|
489
|
+
);
|
|
446
490
|
}
|
|
447
491
|
const promise = inflight.get(u);
|
|
448
492
|
try {
|
|
@@ -501,18 +545,21 @@ function useQueryState(key, defaultValue = "") {
|
|
|
501
545
|
getSnapshot2,
|
|
502
546
|
() => defaultValue
|
|
503
547
|
);
|
|
504
|
-
const setValue = useCallback4(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
548
|
+
const setValue = useCallback4(
|
|
549
|
+
(val) => {
|
|
550
|
+
if (typeof window === "undefined") return;
|
|
551
|
+
const resolved = typeof val === "function" ? val(getSnapshot2()) : val;
|
|
552
|
+
const url = new URL(window.location.href);
|
|
553
|
+
if (resolved === defaultValue || resolved === "") {
|
|
554
|
+
url.searchParams.delete(key);
|
|
555
|
+
} else {
|
|
556
|
+
url.searchParams.set(key, resolved);
|
|
557
|
+
}
|
|
558
|
+
window.history.replaceState(null, "", url.toString());
|
|
559
|
+
notifyQueryListeners();
|
|
560
|
+
},
|
|
561
|
+
[key, defaultValue]
|
|
562
|
+
);
|
|
516
563
|
return [value, setValue];
|
|
517
564
|
}
|
|
518
565
|
|
|
@@ -593,7 +640,10 @@ addInterceptor(async (url) => {
|
|
|
593
640
|
headers: { accept: "application/json" }
|
|
594
641
|
});
|
|
595
642
|
const data = await res.json();
|
|
596
|
-
window.__WEIFUWU_CTX = {
|
|
643
|
+
window.__WEIFUWU_CTX = {
|
|
644
|
+
...window.__WEIFUWU_CTX,
|
|
645
|
+
theme: { value: data.theme }
|
|
646
|
+
};
|
|
597
647
|
setCtx({ theme: { value: data.theme } });
|
|
598
648
|
applyTheme(data.theme);
|
|
599
649
|
} catch {
|
|
@@ -633,20 +683,15 @@ function useAgentStream(opts) {
|
|
|
633
683
|
const [streams, setStreams] = useState6({});
|
|
634
684
|
const activeRef = useRef4(/* @__PURE__ */ new Set());
|
|
635
685
|
const streamsRef = useRef4({});
|
|
636
|
-
const getAgentText = useCallback5(
|
|
637
|
-
|
|
638
|
-
[streams]
|
|
639
|
-
);
|
|
640
|
-
const isAgentStreaming = useCallback5(
|
|
641
|
-
(agentId) => activeRef.current.has(agentId),
|
|
642
|
-
[]
|
|
643
|
-
);
|
|
686
|
+
const getAgentText = useCallback5((agentId) => streams[agentId] || "", [streams]);
|
|
687
|
+
const isAgentStreaming = useCallback5((agentId) => activeRef.current.has(agentId), []);
|
|
644
688
|
const streaming = activeRef.current.size > 0;
|
|
645
689
|
useWebsocket(wsPath, {
|
|
646
690
|
onMessage: (raw) => {
|
|
647
691
|
try {
|
|
648
692
|
const msg = JSON.parse(raw);
|
|
649
|
-
if (msg.type !== "agent_stream" && msg.type !== "agent_stream_end" && msg.type !== "agent_error")
|
|
693
|
+
if (msg.type !== "agent_stream" && msg.type !== "agent_stream_end" && msg.type !== "agent_error")
|
|
694
|
+
return;
|
|
650
695
|
const agentId = msg.data?.agent_id;
|
|
651
696
|
if (agentId === void 0 || agentId === null) return;
|
|
652
697
|
switch (msg.type) {
|