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.
Files changed (54) hide show
  1. package/README.md +818 -712
  2. package/cli/template/app.ts +5 -1
  3. package/cli/template/index.ts +4 -1
  4. package/cli/template/locales/en.json +6 -1
  5. package/cli/template/locales/zh-CN.json +6 -1
  6. package/cli/template/locales/zh-TW.json +6 -1
  7. package/cli/template/locales/zh.json +6 -1
  8. package/cli/template/ui/app/globals.css +1 -1
  9. package/cli/template/ui/app/page.tsx +55 -16
  10. package/cli.ts +148 -104
  11. package/dist/agent/rest.d.ts +1 -1
  12. package/dist/agent/run.d.ts +2 -2
  13. package/dist/ai/workflow.d.ts +1 -1
  14. package/dist/ai-sdk.d.ts +1 -1
  15. package/dist/cli.js +135 -97
  16. package/dist/cookie.d.ts +24 -0
  17. package/dist/fts.d.ts +5 -5
  18. package/dist/iii/index.d.ts +1 -1
  19. package/dist/index.d.ts +5 -5
  20. package/dist/index.js +787 -346
  21. package/dist/live.d.ts +2 -3
  22. package/dist/logdb/rest.d.ts +1 -1
  23. package/dist/mailer.d.ts +1 -1
  24. package/dist/messager/agent.d.ts +2 -2
  25. package/dist/messager/rest.d.ts +3 -3
  26. package/dist/messager/ws.d.ts +3 -3
  27. package/dist/opencode/index.d.ts +1 -1
  28. package/dist/opencode/permissions.d.ts +1 -1
  29. package/dist/opencode/run.d.ts +1 -1
  30. package/dist/opencode/session.d.ts +9 -9
  31. package/dist/opencode/tools/web.d.ts +1 -1
  32. package/dist/opencode/ws.d.ts +1 -2
  33. package/dist/permissions.d.ts +2 -2
  34. package/dist/postgres/module.d.ts +3 -3
  35. package/dist/postgres/schema/index.d.ts +1 -1
  36. package/dist/postgres/schema/table.d.ts +22 -20
  37. package/dist/postgres/types.d.ts +4 -4
  38. package/dist/queue/types.d.ts +1 -1
  39. package/dist/react.d.ts +1 -1
  40. package/dist/react.js +135 -90
  41. package/dist/router.d.ts +10 -10
  42. package/dist/session.d.ts +1 -2
  43. package/dist/tenant/graphql.d.ts +2 -2
  44. package/dist/tenant/index.d.ts +1 -1
  45. package/dist/tenant/rest.d.ts +2 -2
  46. package/dist/test-utils.d.ts +3 -3
  47. package/dist/user/index.d.ts +1 -1
  48. package/dist/user/oauth-login.d.ts +2 -2
  49. package/dist/vendor.d.ts +4 -0
  50. package/opencode/ui/app/globals.css +1 -1
  51. package/opencode/ui/app/layout.tsx +2 -3
  52. package/opencode/ui/app/page.tsx +302 -73
  53. package/package.json +26 -3
  54. 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(dir: string): Router;
4
+ export declare function liveRouter(_dir: string): Router;
6
5
  export declare function liveWatcher(dir: string): {
7
6
  close: () => void;
8
7
  };
@@ -1,4 +1,4 @@
1
- import type { BoundTable } from '../postgres/schema/index.ts';
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
@@ -1,4 +1,4 @@
1
- import type { Transporter } from 'nodemailer';
1
+ import { type Transporter } from 'nodemailer';
2
2
  import type { Closeable } from './types.ts';
3
3
  /** Options for sending an email. */
4
4
  export interface MailOptions {
@@ -1,4 +1,4 @@
1
- import type { Sql } from '../vendor.ts';
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: Sql<{}>, messages: {
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>;
@@ -1,10 +1,10 @@
1
- import type { Sql } from '../vendor.ts';
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 { BoundTable } from '../postgres/schema/index.ts';
5
+ import { type BoundTable } from '../postgres/schema/index.ts';
6
6
  interface RestDeps {
7
- sql: Sql<{}>;
7
+ sql: SqlClient;
8
8
  channels: BoundTable<any>;
9
9
  members: BoundTable<any>;
10
10
  messages: BoundTable<any>;
@@ -1,8 +1,8 @@
1
- import type { Sql } from '../vendor.ts';
1
+ import type { SqlClient } from '../vendor.ts';
2
2
  import type { AgentModule } from '../agent/types.ts';
3
- import type { Hub } from '../hub.ts';
3
+ import { type Hub } from '../hub.ts';
4
4
  interface WSDeps {
5
- sql: Sql<{}>;
5
+ sql: SqlClient;
6
6
  agents?: AgentModule;
7
7
  redis?: import('../vendor.ts').Redis;
8
8
  }
@@ -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, perms?: OpencodePermissions): boolean;
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;
@@ -1,5 +1,5 @@
1
1
  import { type LanguageModel, type Tool } from 'ai';
2
- import type { SessionMessage } from './session.ts';
2
+ import { type SessionMessage } from './session.ts';
3
3
  export interface ExecuteOptions {
4
4
  sessionId: string;
5
5
  input: string;
@@ -1,15 +1,15 @@
1
- import type { Sql } from '../vendor.ts';
1
+ import type { SqlClient } from '../vendor.ts';
2
2
  import type { Session, Message } from './types.ts';
3
- export declare function createSession(sql: Sql<{}>, opts: {
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: Sql<{}>, id: string): Promise<Session | null>;
10
- export declare function listSessions(sql: Sql<{}>, userId?: number): Promise<Session[]>;
11
- export declare function deleteSession(sql: Sql<{}>, id: string): Promise<void>;
12
- export declare function getHistory(sql: Sql<{}>, sessionId: string, limit?: number): Promise<SessionMessage[]>;
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: Sql<{}>, sessionId: string, role: 'user' | 'assistant', content: string, tokensIn?: number, tokensOut?: number): Promise<Message>;
25
- export declare function addToolMessages(sql: Sql<{}>, sessionId: string, toolCalls: unknown[], toolResults: unknown[]): Promise<Message>;
26
- export declare function updateSessionTitle(sql: Sql<{}>, id: string, title: string): Promise<void>;
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>;
@@ -1,5 +1,5 @@
1
1
  import type { ToolContext } from './index.ts';
2
- export declare function createWebTool(ctx: ToolContext): import("ai").Tool<{
2
+ export declare function createWebTool(_ctx: ToolContext): import("ai").Tool<{
3
3
  url: string;
4
4
  }, {
5
5
  content: string;
@@ -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;
@@ -1,4 +1,4 @@
1
- import type { Sql } from './vendor.ts';
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: 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 { Sql } from '../vendor.ts';
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: 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: Sql<{}>) => Promise<T>, retryOpts?: {
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 { Sql } from '../../vendor.ts';
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: Sql<{}>): BoundTable<R>;
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: Sql<{}>, opts?: CreateOptions): Promise<void>;
73
- drop(sql: Sql<{}>, opts?: {
72
+ create(sql: SqlClient, opts?: CreateOptions): Promise<void>;
73
+ drop(sql: SqlClient, opts?: {
74
74
  cascade?: boolean;
75
75
  }): Promise<void>;
76
- createIndex(sql: Sql<{}>, columns: string | string[], opts?: IndexOptions): Promise<void>;
77
- createUniqueIndex(sql: Sql<{}>, columns: string | string[]): Promise<void>;
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: Sql<{}>, data: Partial<R>): Promise<R>;
81
- insertMany(sql: Sql<{}>, data: Partial<R>[]): Promise<R[]>;
82
- read(sql: Sql<{}>, id: string | number, opts?: Pick<FindOptions, 'select' | 'withDeleted'>): Promise<R | undefined>;
83
- readMany(sql: Sql<{}>, where?: Partial<R> | SQL | SQL[], opts?: FindOptions): Promise<{
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: Sql<{}>, id: string | number, data: Partial<R>): Promise<R | undefined>;
88
- updateMany(sql: Sql<{}>, where: Partial<R> | SQL | SQL[], data: Partial<R>): Promise<number>;
89
- delete(sql: Sql<{}>, id: string | number): Promise<R | undefined>;
90
- hardDelete(sql: Sql<{}>, id: string | number): Promise<R | undefined>;
91
- deleteMany(sql: Sql<{}>, where: Partial<R> | SQL | SQL[]): Promise<number>;
92
- hardDeleteMany(sql: Sql<{}>, where: Partial<R> | SQL | SQL[]): Promise<number>;
93
- upsert(sql: Sql<{}>, data: Partial<R>, conflict: string | string[]): Promise<R>;
94
- count(sql: Sql<{}>, where?: Partial<R> | SQL | SQL[]): Promise<number>;
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
- constructor(sql: Sql<{}>, tableName: string, builders: Record<string, ColumnBuilder<unknown>>);
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: Sql<{}>): BoundTable<R>;
123
+ withSql(sql: SqlClient): BoundTable<R>;
122
124
  }
123
125
  /**
124
126
  * Define a type-safe table schema.
@@ -1,13 +1,13 @@
1
- import type { Sql } from '../vendor.ts';
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: Sql<{}>;
6
+ sql: SqlClient;
7
7
  }
8
8
  }
9
9
  export interface PostgresInjected {
10
- sql: 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: 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). */
@@ -22,7 +22,7 @@ export interface QueueOptions {
22
22
  pollInterval?: number;
23
23
  /** PostgreSQL client (required when store: 'pg'). */
24
24
  pg?: {
25
- sql: import('../vendor.ts').Sql<{}>;
25
+ sql: import('../vendor.ts').SqlClient;
26
26
  };
27
27
  }
28
28
  export interface QueueInjected {
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(async (body) => {
99
- setPending(true);
100
- setError(null);
101
- try {
102
- const csrfToken = getCsrfToken();
103
- const hdrs = { ...headers };
104
- if (csrfToken) hdrs["x-csrf-token"] = csrfToken;
105
- if (body && typeof body === "object" && !(body instanceof FormData)) {
106
- hdrs["content-type"] = "application/json";
107
- }
108
- const res = await fetch(url, {
109
- method,
110
- headers: hdrs,
111
- body: body instanceof FormData ? body : body !== void 0 ? JSON.stringify(body) : void 0
112
- });
113
- if (!res.ok) {
114
- const text = await res.text();
115
- throw new Error(text || `HTTP ${res.status}`);
116
- }
117
- const result = res.status === 204 ? void 0 : await res.json();
118
- if (mountedRef.current) {
119
- setData(result);
120
- onSuccess?.(result);
121
- }
122
- return result;
123
- } catch (err) {
124
- const e = err instanceof Error ? err : new Error(String(err));
125
- if (mountedRef.current) {
126
- setError(e);
127
- onError?.(e);
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
- return void 0;
130
- } finally {
131
- if (mountedRef.current) setPending(false);
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 = { params: {}, query: {}, parsed: {}, loaderData: {}, env: {}, user: {}, flash: {} };
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: { params: DEFAULT_CTX.params, query: DEFAULT_CTX.query, user: DEFAULT_CTX.user, parsed: DEFAULT_CTX.parsed, theme: DEFAULT_CTX.theme, i18n: DEFAULT_CTX.i18n, loaderData: DEFAULT_CTX.loaderData, env: DEFAULT_CTX.env },
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 = { params: store._ctx.params, query: store._ctx.query, user: store._ctx.user, parsed: store._ctx.parsed, theme: store._ctx.theme, i18n: store._ctx.i18n, loaderData: store._ctx.loaderData, env: store._ctx.env };
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(Array.from(newMeta).map((m) => m.getAttribute("name") || m.getAttribute("property") || ""));
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) existingEl.setAttribute(attr.name, attr.value);
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(([entry]) => {
349
- if (entry.isIntersecting) prefetchPage(href);
350
- }, { rootMargin: "200px" });
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((e) => {
358
- if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
359
- e.preventDefault();
360
- doNavigate(href);
361
- onClick?.(e);
362
- }, [href, onClick, doNavigate]);
363
- return createElement("a", {
364
- href,
365
- onClick: handleClick,
366
- onMouseEnter: handleMouseEnter,
367
- ...props
368
- }, children);
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) setState({
434
- data: cached.data,
435
- error: cached.error,
436
- loading: false
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(u, fetch(u).then((r) => {
443
- if (!r.ok) throw new Error(r.statusText || `HTTP ${r.status}`);
444
- return r.json();
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((val) => {
505
- if (typeof window === "undefined") return;
506
- const resolved = typeof val === "function" ? val(getSnapshot2()) : val;
507
- const url = new URL(window.location.href);
508
- if (resolved === defaultValue || resolved === "") {
509
- url.searchParams.delete(key);
510
- } else {
511
- url.searchParams.set(key, resolved);
512
- }
513
- window.history.replaceState(null, "", url.toString());
514
- notifyQueryListeners();
515
- }, [key, defaultValue]);
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 = { ...window.__WEIFUWU_CTX, theme: { value: data.theme } };
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
- (agentId) => streams[agentId] || "",
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") return;
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) {