ultracontext 1.2.0 → 1.3.0

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/index.d.mts CHANGED
@@ -52,6 +52,16 @@ type GetContextResponse<T = unknown> = {
52
52
  version: number;
53
53
  versions?: Version[];
54
54
  };
55
+ type ListContextsInput = {
56
+ limit?: number;
57
+ source?: string;
58
+ user_id?: string;
59
+ host?: string;
60
+ project_path?: string;
61
+ session_id?: string;
62
+ after?: string;
63
+ before?: string;
64
+ };
55
65
  type ListContextsResponse = {
56
66
  data: Array<{
57
67
  id: string;
@@ -106,14 +116,12 @@ declare class UltraContext {
106
116
  constructor(cfg: UltraContextConfig);
107
117
  create(input?: CreateContextInput): Promise<CreateContextResponse>;
108
118
  append<T = unknown>(contextId: string, input: AppendInput): Promise<AppendResponse<T>>;
109
- get(options?: {
110
- limit?: number;
111
- }): Promise<ListContextsResponse>;
119
+ get(options?: ListContextsInput): Promise<ListContextsResponse>;
112
120
  get<T = unknown>(id: string, options?: GetContextInput): Promise<GetContextResponse<T>>;
113
121
  update<T = unknown>(contextId: string, input: UpdateInput, options?: MutationOptions): Promise<UpdateResponse<T>>;
114
122
  delete<T = unknown>(contextId: string, ids: DeleteInput, options?: MutationOptions): Promise<DeleteResponse<T>>;
115
123
  private request;
116
124
  }
117
125
  //#endregion
118
- export { AppendInput, AppendMessage, AppendResponse, CreateContextInput, CreateContextResponse, DeleteInput, DeleteResponse, GetContextInput, GetContextResponse, ListContextsResponse, MutationOptions, UltraContext, UltraContextConfig, UltraContextHttpError, UpdateInput, UpdateMessageInput, UpdateResponse, Version };
126
+ export { AppendInput, AppendMessage, AppendResponse, CreateContextInput, CreateContextResponse, DeleteInput, DeleteResponse, GetContextInput, GetContextResponse, ListContextsInput, ListContextsResponse, MutationOptions, UltraContext, UltraContextConfig, UltraContextHttpError, UpdateInput, UpdateMessageInput, UpdateResponse, Version };
119
127
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,kBAAA;EACR,MAAA;EACA,OAAA;EACA,KAAA,UAAe,KAAA;EACf,OAAA,GAAU,MAAA;EACV,SAAA;AAAA;AAAA,KAGQ,OAAA;EACR,OAAA;EACA,UAAA;EACA,SAAA;EACA,QAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,KAGH,kBAAA;EACR,IAAA;EACA,OAAA;EACA,EAAA;EACA,MAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,KAGH,qBAAA;EACR,EAAA;EACA,QAAA,EAAU,MAAA;EACV,UAAA;AAAA;AAAA,KAGQ,aAAA,GAAgB,IAAA,CAAK,MAAA;EAAyC,QAAA,GAAW,MAAA;AAAA;AAAA,KACzE,WAAA,GAAc,aAAA,GAAgB,aAAA;AAAA,KAE9B,cAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;AAAA;AAAA,KAGQ,eAAA;EACR,OAAA;EACA,EAAA;EACA,MAAA;EACA,OAAA;AAAA;AAAA,KAGQ,kBAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;EACA,QAAA,GAAW,OAAA;AAAA;AAAA,KAGH,oBAAA;EACR,IAAA,EAAM,KAAA;IACF,EAAA;IACA,QAAA,EAAU,MAAA;IACV,UAAA;EAAA;AAAA;AAAA,KAII,eAAA;EACR,QAAA,GAAW,MAAA;AAAA;AAAA,KAGH,kBAAA;EACH,EAAA;EAAY,KAAA;AAAA,IAAkB,MAAA;EAC9B,KAAA;EAAe,EAAA;AAAA,IAAe,MAAA;AAAA,KAC3B,WAAA,GAAc,kBAAA,GAAqB,kBAAA;AAAA,KAEnC,cAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;AAAA;AAAA,KAGQ,WAAA;AAAA,KAEA,cAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;AAAA;AAAA,cAGS,qBAAA,SAA8B,KAAA;EAAA,SAC9B,MAAA;EAAA,SACA,GAAA;EAAA,SACA,QAAA;cAEG,IAAA;IAAQ,MAAA;IAAgB,GAAA;IAAa,QAAA;EAAA;AAAA;AAAA,cASxC,YAAA;EAAA,iBACQ,OAAA;EAAA,iBACA,MAAA;EAAA,iBACA,OAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;cAEL,GAAA,EAAK,kBAAA;EAQX,MAAA,CAAO,KAAA,GAAO,kBAAA,GAA0B,OAAA,CAAQ,qBAAA;EAOhD,MAAA,aAAA,CAAoB,SAAA,UAAmB,KAAA,EAAO,WAAA,GAAc,OAAA,CAAQ,cAAA,CAAe,CAAA;EAOnF,GAAA,CAAI,OAAA;IAAY,KAAA;EAAA,IAAmB,OAAA,CAAQ,oBAAA;EAC3C,GAAA,aAAA,CAAiB,EAAA,UAAY,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,kBAAA,CAAmB,CAAA;EAqBpF,MAAA,aAAA,CAAoB,SAAA,UAAmB,KAAA,EAAO,WAAA,EAAa,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,CAAA;EAW9G,MAAA,aAAA,CAAoB,SAAA,UAAmB,GAAA,EAAK,WAAA,EAAa,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,CAAA;EAAA,QAOpG,OAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,kBAAA;EACR,MAAA;EACA,OAAA;EACA,KAAA,UAAe,KAAA;EACf,OAAA,GAAU,MAAA;EACV,SAAA;AAAA;AAAA,KAGQ,OAAA;EACR,OAAA;EACA,UAAA;EACA,SAAA;EACA,QAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,KAGH,kBAAA;EACR,IAAA;EACA,OAAA;EACA,EAAA;EACA,MAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,KAGH,qBAAA;EACR,EAAA;EACA,QAAA,EAAU,MAAA;EACV,UAAA;AAAA;AAAA,KAGQ,aAAA,GAAgB,IAAA,CAAK,MAAA;EAAyC,QAAA,GAAW,MAAA;AAAA;AAAA,KACzE,WAAA,GAAc,aAAA,GAAgB,aAAA;AAAA,KAE9B,cAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;AAAA;AAAA,KAGQ,eAAA;EACR,OAAA;EACA,EAAA;EACA,MAAA;EACA,OAAA;AAAA;AAAA,KAGQ,kBAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;EACA,QAAA,GAAW,OAAA;AAAA;AAAA,KAGH,iBAAA;EACR,KAAA;EACA,MAAA;EACA,OAAA;EACA,IAAA;EACA,YAAA;EACA,UAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,KAGQ,oBAAA;EACR,IAAA,EAAM,KAAA;IACF,EAAA;IACA,QAAA,EAAU,MAAA;IACV,UAAA;EAAA;AAAA;AAAA,KAII,eAAA;EACR,QAAA,GAAW,MAAA;AAAA;AAAA,KAGH,kBAAA;EACH,EAAA;EAAY,KAAA;AAAA,IAAkB,MAAA;EAC9B,KAAA;EAAe,EAAA;AAAA,IAAe,MAAA;AAAA,KAC3B,WAAA,GAAc,kBAAA,GAAqB,kBAAA;AAAA,KAEnC,cAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;AAAA;AAAA,KAGQ,WAAA;AAAA,KAEA,cAAA;EACR,IAAA,EAAM,KAAA;IAAQ,EAAA;IAAY,KAAA;IAAe,QAAA,EAAU,MAAA;EAAA,IAA4B,CAAA;EAC/E,OAAA;AAAA;AAAA,cAGS,qBAAA,SAA8B,KAAA;EAAA,SAC9B,MAAA;EAAA,SACA,GAAA;EAAA,SACA,QAAA;cAEG,IAAA;IAAQ,MAAA;IAAgB,GAAA;IAAa,QAAA;EAAA;AAAA;AAAA,cASxC,YAAA;EAAA,iBACQ,OAAA;EAAA,iBACA,MAAA;EAAA,iBACA,OAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;cAEL,GAAA,EAAK,kBAAA;EAQX,MAAA,CAAO,KAAA,GAAO,kBAAA,GAA0B,OAAA,CAAQ,qBAAA;EAOhD,MAAA,aAAA,CAAoB,SAAA,UAAmB,KAAA,EAAO,WAAA,GAAc,OAAA,CAAQ,cAAA,CAAe,CAAA;EAOnF,GAAA,CAAI,OAAA,GAAU,iBAAA,GAAoB,OAAA,CAAQ,oBAAA;EAC1C,GAAA,aAAA,CAAiB,EAAA,UAAY,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,kBAAA,CAAmB,CAAA;EA8BpF,MAAA,aAAA,CAAoB,SAAA,UAAmB,KAAA,EAAO,WAAA,EAAa,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,CAAA;EAW9G,MAAA,aAAA,CAAoB,SAAA,UAAmB,GAAA,EAAK,WAAA,EAAa,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,CAAA;EAAA,QAOpG,OAAA;AAAA"}
package/dist/index.mjs CHANGED
@@ -31,7 +31,16 @@ var UltraContext = class {
31
31
  async get(idOrOptions, options) {
32
32
  if (!idOrOptions || typeof idOrOptions === "object") {
33
33
  const params = new URLSearchParams();
34
- if (typeof idOrOptions === "object" && idOrOptions.limit) params.set("limit", String(idOrOptions.limit));
34
+ if (typeof idOrOptions === "object") {
35
+ if (idOrOptions.limit) params.set("limit", String(idOrOptions.limit));
36
+ if (idOrOptions.source) params.set("source", idOrOptions.source);
37
+ if (idOrOptions.user_id) params.set("user_id", idOrOptions.user_id);
38
+ if (idOrOptions.host) params.set("host", idOrOptions.host);
39
+ if (idOrOptions.project_path) params.set("project_path", idOrOptions.project_path);
40
+ if (idOrOptions.session_id) params.set("session_id", idOrOptions.session_id);
41
+ if (idOrOptions.after) params.set("after", idOrOptions.after);
42
+ if (idOrOptions.before) params.set("before", idOrOptions.before);
43
+ }
35
44
  const query = params.toString();
36
45
  return this.request(`/contexts${query ? `?${query}` : ""}`, { method: "GET" });
37
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type UltraContextConfig = {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n headers?: Record<string, string>;\n timeoutMs?: number;\n};\n\nexport type Version = {\n version: number;\n created_at: string;\n operation: 'create' | 'update' | 'delete';\n affected: string[] | null;\n metadata?: Record<string, unknown>;\n};\n\nexport type CreateContextInput = {\n from?: string;\n version?: number;\n at?: number;\n before?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type CreateContextResponse = {\n id: string;\n metadata: Record<string, unknown>;\n created_at: string;\n};\n\nexport type AppendMessage = Omit<Record<string, unknown>, 'metadata'> & { metadata?: Record<string, unknown> };\nexport type AppendInput = AppendMessage | AppendMessage[];\n\nexport type AppendResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n};\n\nexport type GetContextInput = {\n version?: number;\n at?: number;\n before?: string;\n history?: boolean;\n};\n\nexport type GetContextResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n versions?: Version[];\n};\n\nexport type ListContextsResponse = {\n data: Array<{\n id: string;\n metadata: Record<string, unknown>;\n created_at: string;\n }>;\n};\n\nexport type MutationOptions = {\n metadata?: Record<string, unknown>;\n};\n\nexport type UpdateMessageInput =\n | ({ id: string; index?: never } & Record<string, unknown>)\n | ({ index: number; id?: never } & Record<string, unknown>);\nexport type UpdateInput = UpdateMessageInput | UpdateMessageInput[];\n\nexport type UpdateResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n};\n\nexport type DeleteInput = (string | number) | (string | number)[];\n\nexport type DeleteResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n};\n\nexport class UltraContextHttpError extends Error {\n readonly status: number;\n readonly url: string;\n readonly bodyText?: string;\n\n constructor(args: { status: number; url: string; bodyText?: string }) {\n super(`UltraContext request failed: ${args.status} ${args.url}`);\n this.name = 'UltraContextHttpError';\n this.status = args.status;\n this.url = args.url;\n this.bodyText = args.bodyText;\n }\n}\n\nexport class UltraContext {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly fetchFn: typeof fetch;\n private readonly headers?: Record<string, string>;\n private readonly timeoutMs?: number;\n\n constructor(cfg: UltraContextConfig) {\n this.baseUrl = (cfg.baseUrl ?? 'https://api.ultracontext.ai').replace(/\\/+$/, '');\n this.apiKey = cfg.apiKey;\n this.fetchFn = cfg.fetch ?? fetch;\n this.headers = cfg.headers;\n this.timeoutMs = cfg.timeoutMs;\n }\n\n async create(input: CreateContextInput = {}): Promise<CreateContextResponse> {\n return this.request<CreateContextResponse>('/contexts', {\n method: 'POST',\n body: input,\n });\n }\n\n async append<T = unknown>(contextId: string, input: AppendInput): Promise<AppendResponse<T>> {\n return this.request<AppendResponse<T>>(`/contexts/${encodeURIComponent(contextId)}`, {\n method: 'POST',\n body: input,\n });\n }\n\n async get(options?: { limit?: number }): Promise<ListContextsResponse>;\n async get<T = unknown>(id: string, options?: GetContextInput): Promise<GetContextResponse<T>>;\n async get<T = unknown>(\n idOrOptions?: string | { limit?: number },\n options?: GetContextInput\n ): Promise<GetContextResponse<T> | ListContextsResponse> {\n if (!idOrOptions || typeof idOrOptions === 'object') {\n const params = new URLSearchParams();\n if (typeof idOrOptions === 'object' && idOrOptions.limit) params.set('limit', String(idOrOptions.limit));\n const query = params.toString();\n return this.request<ListContextsResponse>(`/contexts${query ? `?${query}` : ''}`, { method: 'GET' });\n }\n\n const params = new URLSearchParams();\n if (options?.version !== undefined) params.set('version', String(options.version));\n if (options?.at !== undefined) params.set('at', String(options.at));\n if (options?.before) params.set('before', options.before);\n if (options?.history) params.set('history', 'true');\n const query = params.toString();\n return this.request<GetContextResponse<T>>(`/contexts/${encodeURIComponent(idOrOptions)}${query ? `?${query}` : ''}`, { method: 'GET' });\n }\n\n async update<T = unknown>(contextId: string, input: UpdateInput, options?: MutationOptions): Promise<UpdateResponse<T>> {\n const body = options?.metadata\n ? { updates: Array.isArray(input) ? input : [input], metadata: options.metadata }\n : input;\n\n return this.request<UpdateResponse<T>>(`/contexts/${encodeURIComponent(contextId)}`, {\n method: 'PATCH',\n body,\n });\n }\n\n async delete<T = unknown>(contextId: string, ids: DeleteInput, options?: MutationOptions): Promise<DeleteResponse<T>> {\n return this.request<DeleteResponse<T>>(`/contexts/${encodeURIComponent(contextId)}`, {\n method: 'DELETE',\n body: { ids, metadata: options?.metadata },\n });\n }\n\n private async request<T>(path: string, init: { method: string; body?: unknown; headers?: Record<string, string> }): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n ...(this.headers ?? {}),\n ...(init.headers ?? {}),\n };\n\n let body: BodyInit | undefined;\n if (init.body !== undefined) {\n headers['Content-Type'] = headers['Content-Type'] ?? 'application/json';\n body = JSON.stringify(init.body);\n }\n\n const ac = this.timeoutMs ? new AbortController() : undefined;\n const timeout = this.timeoutMs ? setTimeout(() => ac?.abort(), this.timeoutMs) : undefined;\n\n try {\n const res = await this.fetchFn(url, {\n method: init.method,\n headers,\n body,\n signal: ac?.signal,\n });\n\n if (!res.ok) {\n const bodyText = await safeReadText(res);\n throw new UltraContextHttpError({ status: res.status, url, bodyText });\n }\n\n if (res.status === 204) return undefined as unknown as T;\n\n const contentType = res.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) return (await res.json()) as T;\n return (await res.text()) as unknown as T;\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n }\n}\n\nasync function safeReadText(res: Response) {\n try {\n return await res.text();\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type UltraContextConfig = {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n headers?: Record<string, string>;\n timeoutMs?: number;\n};\n\nexport type Version = {\n version: number;\n created_at: string;\n operation: 'create' | 'update' | 'delete';\n affected: string[] | null;\n metadata?: Record<string, unknown>;\n};\n\nexport type CreateContextInput = {\n from?: string;\n version?: number;\n at?: number;\n before?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type CreateContextResponse = {\n id: string;\n metadata: Record<string, unknown>;\n created_at: string;\n};\n\nexport type AppendMessage = Omit<Record<string, unknown>, 'metadata'> & { metadata?: Record<string, unknown> };\nexport type AppendInput = AppendMessage | AppendMessage[];\n\nexport type AppendResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n};\n\nexport type GetContextInput = {\n version?: number;\n at?: number;\n before?: string;\n history?: boolean;\n};\n\nexport type GetContextResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n versions?: Version[];\n};\n\nexport type ListContextsInput = {\n limit?: number;\n source?: string;\n user_id?: string;\n host?: string;\n project_path?: string;\n session_id?: string;\n after?: string;\n before?: string;\n};\n\nexport type ListContextsResponse = {\n data: Array<{\n id: string;\n metadata: Record<string, unknown>;\n created_at: string;\n }>;\n};\n\nexport type MutationOptions = {\n metadata?: Record<string, unknown>;\n};\n\nexport type UpdateMessageInput =\n | ({ id: string; index?: never } & Record<string, unknown>)\n | ({ index: number; id?: never } & Record<string, unknown>);\nexport type UpdateInput = UpdateMessageInput | UpdateMessageInput[];\n\nexport type UpdateResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n};\n\nexport type DeleteInput = (string | number) | (string | number)[];\n\nexport type DeleteResponse<T = unknown> = {\n data: Array<{ id: string; index: number; metadata: Record<string, unknown> } & T>;\n version: number;\n};\n\nexport class UltraContextHttpError extends Error {\n readonly status: number;\n readonly url: string;\n readonly bodyText?: string;\n\n constructor(args: { status: number; url: string; bodyText?: string }) {\n super(`UltraContext request failed: ${args.status} ${args.url}`);\n this.name = 'UltraContextHttpError';\n this.status = args.status;\n this.url = args.url;\n this.bodyText = args.bodyText;\n }\n}\n\nexport class UltraContext {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly fetchFn: typeof fetch;\n private readonly headers?: Record<string, string>;\n private readonly timeoutMs?: number;\n\n constructor(cfg: UltraContextConfig) {\n this.baseUrl = (cfg.baseUrl ?? 'https://api.ultracontext.ai').replace(/\\/+$/, '');\n this.apiKey = cfg.apiKey;\n this.fetchFn = cfg.fetch ?? fetch;\n this.headers = cfg.headers;\n this.timeoutMs = cfg.timeoutMs;\n }\n\n async create(input: CreateContextInput = {}): Promise<CreateContextResponse> {\n return this.request<CreateContextResponse>('/contexts', {\n method: 'POST',\n body: input,\n });\n }\n\n async append<T = unknown>(contextId: string, input: AppendInput): Promise<AppendResponse<T>> {\n return this.request<AppendResponse<T>>(`/contexts/${encodeURIComponent(contextId)}`, {\n method: 'POST',\n body: input,\n });\n }\n\n async get(options?: ListContextsInput): Promise<ListContextsResponse>;\n async get<T = unknown>(id: string, options?: GetContextInput): Promise<GetContextResponse<T>>;\n async get<T = unknown>(\n idOrOptions?: string | ListContextsInput,\n options?: GetContextInput\n ): Promise<GetContextResponse<T> | ListContextsResponse> {\n if (!idOrOptions || typeof idOrOptions === 'object') {\n const params = new URLSearchParams();\n if (typeof idOrOptions === 'object') {\n if (idOrOptions.limit) params.set('limit', String(idOrOptions.limit));\n if (idOrOptions.source) params.set('source', idOrOptions.source);\n if (idOrOptions.user_id) params.set('user_id', idOrOptions.user_id);\n if (idOrOptions.host) params.set('host', idOrOptions.host);\n if (idOrOptions.project_path) params.set('project_path', idOrOptions.project_path);\n if (idOrOptions.session_id) params.set('session_id', idOrOptions.session_id);\n if (idOrOptions.after) params.set('after', idOrOptions.after);\n if (idOrOptions.before) params.set('before', idOrOptions.before);\n }\n const query = params.toString();\n return this.request<ListContextsResponse>(`/contexts${query ? `?${query}` : ''}`, { method: 'GET' });\n }\n\n const params = new URLSearchParams();\n if (options?.version !== undefined) params.set('version', String(options.version));\n if (options?.at !== undefined) params.set('at', String(options.at));\n if (options?.before) params.set('before', options.before);\n if (options?.history) params.set('history', 'true');\n const query = params.toString();\n return this.request<GetContextResponse<T>>(`/contexts/${encodeURIComponent(idOrOptions)}${query ? `?${query}` : ''}`, { method: 'GET' });\n }\n\n async update<T = unknown>(contextId: string, input: UpdateInput, options?: MutationOptions): Promise<UpdateResponse<T>> {\n const body = options?.metadata\n ? { updates: Array.isArray(input) ? input : [input], metadata: options.metadata }\n : input;\n\n return this.request<UpdateResponse<T>>(`/contexts/${encodeURIComponent(contextId)}`, {\n method: 'PATCH',\n body,\n });\n }\n\n async delete<T = unknown>(contextId: string, ids: DeleteInput, options?: MutationOptions): Promise<DeleteResponse<T>> {\n return this.request<DeleteResponse<T>>(`/contexts/${encodeURIComponent(contextId)}`, {\n method: 'DELETE',\n body: { ids, metadata: options?.metadata },\n });\n }\n\n private async request<T>(path: string, init: { method: string; body?: unknown; headers?: Record<string, string> }): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n ...(this.headers ?? {}),\n ...(init.headers ?? {}),\n };\n\n let body: BodyInit | undefined;\n if (init.body !== undefined) {\n headers['Content-Type'] = headers['Content-Type'] ?? 'application/json';\n body = JSON.stringify(init.body);\n }\n\n const ac = this.timeoutMs ? new AbortController() : undefined;\n const timeout = this.timeoutMs ? setTimeout(() => ac?.abort(), this.timeoutMs) : undefined;\n\n try {\n const res = await this.fetchFn(url, {\n method: init.method,\n headers,\n body,\n signal: ac?.signal,\n });\n\n if (!res.ok) {\n const bodyText = await safeReadText(res);\n throw new UltraContextHttpError({ status: res.status, url, bodyText });\n }\n\n if (res.status === 204) return undefined as unknown as T;\n\n const contentType = res.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) return (await res.json()) as T;\n return (await res.text()) as unknown as T;\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n }\n}\n\nasync function safeReadText(res: Response) {\n try {\n return await res.text();\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { i as expandHome, n as resolveLockPath } from "./lock-H7LKrRSb.mjs";
2
- import { c as resolveDaemonWsInfoFile } from "./src-NyDFgJXL.mjs";
1
+ import { i as expandHome, n as resolveLockPath } from "./lock-Q6z0l6Mr.mjs";
2
+ import { c as resolveDaemonWsInfoFile } from "./src-Xh68VkBy.mjs";
3
3
  import process from "node:process";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import path from "node:path";
@@ -56,7 +56,7 @@ async function resolveRunningProcess(lockPath) {
56
56
  if (isPidAlive(lockPid)) return {
57
57
  pid: lockPid,
58
58
  startedAt: String(lock?.startedAt ?? ""),
59
- engineerId: String(lock?.engineerId ?? ""),
59
+ userId: String(lock?.userId ?? ""),
60
60
  host: String(lock?.host ?? "")
61
61
  };
62
62
  return null;
@@ -138,4 +138,4 @@ if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/.*\//,
138
138
 
139
139
  //#endregion
140
140
  export { launchDaemon };
141
- //# sourceMappingURL=launcher-VTbHuuaQ.mjs.map
141
+ //# sourceMappingURL=launcher-DXUM0K-z.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher-DXUM0K-z.mjs","names":["fs","fsSync"],"sources":["../../daemon/src/launcher.mjs"],"sourcesContent":["// daemon launcher — spawns daemon in background, exported as launchDaemon()\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { resolveDaemonWsInfoFile } from \"@ultracontext/protocol\";\n\nimport { resolveLockPath } from \"./lock.mjs\";\nimport { expandHome } from \"./utils.mjs\";\n\nconst DEFAULT_LOG_FILE = \"~/.ultracontext/daemon.log\";\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst reset = esc(0);\nconst bold = esc(1);\nconst dim = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst cyan = esc(\"38;2;126;195;255\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst gray = esc(\"38;5;245\");\n\n// ── process helpers ─────────────────────────────────────────────\n\nfunction isPidAlive(pid) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if (error?.code === \"EPERM\") return true;\n if (error?.code === \"ESRCH\") return false;\n return false;\n }\n}\n\nasync function readJsonFile(filePath) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? parsed : null;\n } catch {\n return null;\n }\n}\n\nasync function readLogTail(logPath, lines = 12) {\n try {\n const raw = await fs.readFile(logPath, \"utf8\");\n const allLines = raw.split(\"\\n\").map((l) => l.trimEnd()).filter(Boolean);\n return allLines.length === 0 ? [] : allLines.slice(-Math.max(lines, 1));\n } catch {\n return [];\n }\n}\n\nfunction resolveDaemonLogFile(env = process.env) {\n return expandHome(env.ULTRACONTEXT_DAEMON_LOG_FILE ?? DEFAULT_LOG_FILE);\n}\n\nasync function resolveRunningProcess(lockPath) {\n const lock = await readJsonFile(lockPath);\n const lockPid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (isPidAlive(lockPid)) {\n return { pid: lockPid, startedAt: String(lock?.startedAt ?? \"\"), userId: String(lock?.userId ?? \"\"), host: String(lock?.host ?? \"\") };\n }\n return null;\n}\n\nasync function resolveWritableLogPath(preferredPath) {\n const primary = path.resolve(preferredPath);\n try {\n await fs.mkdir(path.dirname(primary), { recursive: true });\n fsSync.accessSync(path.dirname(primary), fsSync.constants.W_OK);\n return primary;\n } catch {\n const fallback = path.resolve(process.cwd(), \".ultracontext-daemon.log\");\n await fs.mkdir(path.dirname(fallback), { recursive: true });\n return fallback;\n }\n}\n\n// ── exported entry point ────────────────────────────────────────\n\nexport async function launchDaemon({ entryPath, diagnosticsHint } = {}) {\n const resolvedEntry = entryPath ?? fileURLToPath(new URL(\"./index.mjs\", import.meta.url));\n const hint = diagnosticsHint ?? \"pnpm --filter @ultracontext/daemon run start:verbose\";\n\n const lockPath = path.resolve(resolveLockPath(process.env));\n const infoPath = path.resolve(resolveDaemonWsInfoFile(process.env));\n const preferredLogPath = resolveDaemonLogFile(process.env);\n\n console.log(\"\");\n console.log(` ${blue}${bold}UltraContext${reset} ${dim}Daemon${reset}`);\n console.log(\"\");\n\n // already running\n const running = await resolveRunningProcess(lockPath);\n if (running) {\n console.log(` ${cyan}●${reset} ${bold}Already running${reset} ${gray}PID ${running.pid}${reset}`);\n console.log(\"\");\n process.exit(2);\n return;\n }\n\n // spawn daemon\n const logPath = await resolveWritableLogPath(preferredLogPath);\n const outFd = fsSync.openSync(logPath, \"a\");\n const errFd = fsSync.openSync(logPath, \"a\");\n\n let child;\n try {\n child = spawn(process.execPath, [resolvedEntry, \"--daemon\"], {\n env: process.env,\n detached: true,\n stdio: [\"ignore\", outFd, errFd],\n });\n child.unref();\n } finally {\n try { fsSync.closeSync(outFd); } catch { /* ignore */ }\n try { fsSync.closeSync(errFd); } catch { /* ignore */ }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 350));\n\n // failed\n if (!isPidAlive(child.pid)) {\n console.log(` ${red}✕${reset} ${bold}Failed to start${reset}`);\n const tail = await readLogTail(logPath);\n if (tail.length > 0) {\n console.log(\"\");\n for (const line of tail) console.error(` ${gray}${line}${reset}`);\n }\n console.log(\"\");\n console.log(` ${dim}Try: ${hint}${reset}`);\n console.log(\"\");\n process.exit(1);\n return;\n }\n\n // success\n console.log(` ${green}✓${reset} ${bold}Started${reset} ${gray}PID ${child.pid}${reset}`);\n console.log(` ${gray}${logPath}${reset}`);\n console.log(\"\");\n}\n\n// auto-exec when run directly\nconst isDirectRun = process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/.*\\//, \"\"));\nif (isDirectRun) {\n launchDaemon().catch((error) => {\n console.error(` ${red}✕${reset} ${error instanceof Error ? error.message : String(error)}`);\n console.error(\"\");\n process.exit(1);\n });\n}\n"],"mappings":"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"}
@@ -52,6 +52,11 @@ function extractSessionIdFromPath(filePath) {
52
52
  if (uuidMatch) return uuidMatch[1];
53
53
  return path.basename(filePath, ".jsonl") || "unknown-session";
54
54
  }
55
+ function extractProjectPathFromFile(filePath) {
56
+ const match = filePath.match(/\.claude\/projects\/([^/]+)/);
57
+ if (!match) return null;
58
+ return match[1].replace(/-/g, "/");
59
+ }
55
60
 
56
61
  //#endregion
57
62
  //#region ../daemon/src/lock.mjs
@@ -79,7 +84,7 @@ async function readExistingLock(lockPath) {
79
84
  function resolveLockPath(env = process.env) {
80
85
  return expandHome(env.ULTRACONTEXT_LOCK_FILE ?? DEFAULT_LOCK_PATH);
81
86
  }
82
- async function acquireFileLock({ lockPath = resolveLockPath(process.env), engineerId = "", host = "" } = {}) {
87
+ async function acquireFileLock({ lockPath = resolveLockPath(process.env), userId = "", host = "" } = {}) {
83
88
  const resolved = path.resolve(lockPath);
84
89
  await fs.mkdir(path.dirname(resolved), { recursive: true });
85
90
  let handle;
@@ -105,7 +110,7 @@ async function acquireFileLock({ lockPath = resolveLockPath(process.env), engine
105
110
  const payload = {
106
111
  pid: process.pid,
107
112
  host: String(host ?? ""),
108
- engineerId: String(engineerId ?? ""),
113
+ userId: String(userId ?? ""),
109
114
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
110
115
  };
111
116
  await handle.writeFile(`${JSON.stringify(payload, null, 2)}\n`, "utf8");
@@ -128,5 +133,5 @@ async function acquireFileLock({ lockPath = resolveLockPath(process.env), engine
128
133
  }
129
134
 
130
135
  //#endregion
131
- export { extractSessionIdFromPath as a, toInt as c, expandHome as i, truncateString as l, resolveLockPath as n, safeJsonParse as o, boolFromEnv as r, sha256 as s, acquireFileLock as t };
132
- //# sourceMappingURL=lock-H7LKrRSb.mjs.map
136
+ export { extractProjectPathFromFile as a, sha256 as c, expandHome as i, toInt as l, resolveLockPath as n, extractSessionIdFromPath as o, boolFromEnv as r, safeJsonParse as s, acquireFileLock as t, truncateString as u };
137
+ //# sourceMappingURL=lock-Q6z0l6Mr.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-Q6z0l6Mr.mjs","names":[],"sources":["../../daemon/src/utils.mjs","../../daemon/src/lock.mjs"],"sourcesContent":["import crypto from \"node:crypto\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport function sha256(value) {\n return crypto.createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nexport function expandHome(inputPath) {\n if (!inputPath || !inputPath.startsWith(\"~\")) return inputPath;\n if (inputPath === \"~\") return os.homedir();\n if (inputPath.startsWith(\"~/\")) return path.join(os.homedir(), inputPath.slice(2));\n return inputPath;\n}\n\nexport function toInt(value, fallback) {\n const parsed = Number.parseInt(String(value ?? \"\"), 10);\n return Number.isFinite(parsed) ? parsed : fallback;\n}\n\nexport function boolFromEnv(value, fallback = false) {\n if (value === undefined) return fallback;\n const normalized = String(value).trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return fallback;\n}\n\nexport function truncateString(value, maxLen = 4000) {\n if (typeof value !== \"string\") return value;\n if (value.length <= maxLen) return value;\n return `${value.slice(0, maxLen)}... [truncated ${value.length - maxLen} chars]`;\n}\n\nexport function safeJsonParse(line) {\n try {\n return JSON.parse(line);\n } catch {\n return null;\n }\n}\n\nexport function extractSessionIdFromPath(filePath) {\n const uuidMatch = filePath.match(\n /([0-9a-f]{8}-[0-9a-f]{4,}-[0-9a-f]{4,}-[0-9a-f]{4,}-[0-9a-f]{8,})/i\n );\n if (uuidMatch) return uuidMatch[1];\n\n const fileName = path.basename(filePath, \".jsonl\");\n return fileName || \"unknown-session\";\n}\n\n// extract project path from JSONL file location\n// claude: ~/.claude/projects/-Users-fabio-Code-foo/session.jsonl → /Users/fabio/Code/foo\n// codex: ~/.codex/sessions/<uuid>.jsonl → null (cwd comes from session_meta)\n// openclaw: ~/.openclaw/agents/<name>/sessions/<uuid>.jsonl → null\nexport function extractProjectPathFromFile(filePath) {\n const match = filePath.match(/\\.claude\\/projects\\/([^/]+)/);\n if (!match) return null;\n\n // convert dash-separated path back to real path (leading dash = leading /)\n const encoded = match[1];\n return encoded.replace(/-/g, \"/\");\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport process from \"node:process\";\n\nimport { expandHome } from \"./utils.mjs\";\n\nconst DEFAULT_LOCK_PATH = \"~/.ultracontext/daemon.lock\";\n\nfunction isPidAlive(pid) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if (error?.code === \"EPERM\") return true;\n if (error?.code === \"ESRCH\") return false;\n return false;\n }\n}\n\nasync function readExistingLock(lockPath) {\n try {\n const raw = await fs.readFile(lockPath, \"utf8\");\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? parsed : null;\n } catch {\n return null;\n }\n}\n\nexport function resolveLockPath(env = process.env) {\n return expandHome(env.ULTRACONTEXT_LOCK_FILE ?? DEFAULT_LOCK_PATH);\n}\n\nexport async function acquireFileLock({\n lockPath = resolveLockPath(process.env),\n userId = \"\",\n host = \"\",\n} = {}) {\n const resolved = path.resolve(lockPath);\n await fs.mkdir(path.dirname(resolved), { recursive: true });\n\n let handle;\n try {\n handle = await fs.open(resolved, \"wx\");\n } catch (error) {\n if (error?.code !== \"EEXIST\") throw error;\n\n const existing = await readExistingLock(resolved);\n const existingPid = Number.parseInt(String(existing?.pid ?? \"\"), 10);\n if (!isPidAlive(existingPid)) {\n try {\n await fs.unlink(resolved);\n } catch {\n // ignore\n }\n handle = await fs.open(resolved, \"wx\");\n } else {\n const reason = existingPid\n ? `UltraContext daemon already running (PID: ${existingPid})`\n : \"UltraContext daemon already running\";\n const lockError = new Error(reason);\n lockError.code = \"ELOCKED\";\n lockError.pid = existingPid;\n throw lockError;\n }\n }\n\n const payload = {\n pid: process.pid,\n host: String(host ?? \"\"),\n userId: String(userId ?? \"\"),\n startedAt: new Date().toISOString(),\n };\n await handle.writeFile(`${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n\n let released = false;\n const release = async () => {\n if (released) return;\n released = true;\n try {\n await handle.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(resolved);\n } catch {\n // ignore\n }\n };\n\n return {\n lockPath: resolved,\n payload,\n release,\n };\n}\n"],"mappings":"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"}
@@ -40,9 +40,9 @@ function resolveDaemonWsPort(env = process.env) {
40
40
  function resolveDaemonWsInfoFile(env = process.env) {
41
41
  return expandHome(env.ULTRACONTEXT_DAEMON_INFO_FILE ?? env.ULTRACONTEXT_DAEMON_WS_PORT_FILE ?? env.ULTRACONTEXT_WS_INFO_FILE ?? DEFAULT_DAEMON_INFO_FILE);
42
42
  }
43
- function createBootstrapStateKey({ host, engineerId, sourceNames }) {
43
+ function createBootstrapStateKey({ host, userId, sourceNames }) {
44
44
  const namesKey = (Array.isArray(sourceNames) ? sourceNames.map((name) => String(name ?? "").trim()).filter(Boolean) : []).sort().join(",");
45
- return `uc:daemon:bootstrap:${VERSION}:${norm(host)}:${norm(engineerId)}:${namesKey}`;
45
+ return `uc:daemon:bootstrap:${VERSION}:${norm(host)}:${norm(userId)}:${namesKey}`;
46
46
  }
47
47
  function normalizeBootstrapMode(raw, { allowPrompt = false } = {}) {
48
48
  const value = String(raw ?? "").trim().toLowerCase();
@@ -80,4 +80,4 @@ function parseDaemonWsMessage(raw, fallback = null) {
80
80
 
81
81
  //#endregion
82
82
  export { parseDaemonWsMessage as a, resolveDaemonWsInfoFile as c, normalizeBootstrapMode as i, resolveDaemonWsPort as l, buildDaemonWsMessage as n, parseProtocolJson as o, createBootstrapStateKey as r, resolveDaemonWsHost as s, DAEMON_WS_MESSAGE_TYPES as t };
83
- //# sourceMappingURL=src-NyDFgJXL.mjs.map
83
+ //# sourceMappingURL=src-Xh68VkBy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-Xh68VkBy.mjs","names":[],"sources":["../../../packages/protocol/src/index.mjs"],"sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\n\nconst VERSION = \"v1\";\nconst DEFAULT_DAEMON_WS_HOST = \"127.0.0.1\";\nconst DEFAULT_DAEMON_WS_PORT = 0;\nconst DEFAULT_DAEMON_INFO_FILE = \"~/.ultracontext/daemon.info\";\n\nexport const DAEMON_WS_MESSAGE_TYPES = Object.freeze({\n SNAPSHOT: \"snapshot\",\n STATE: \"state\",\n LOG: \"log\",\n CONTEXT_EVENT: \"context:event\",\n CONFIG_STATE: \"config:state\",\n REQUEST_ACK: \"ack\",\n PING: \"ping\",\n PONG: \"pong\",\n CONFIG_GET: \"config:get\",\n CONFIG_SET: \"config:set\",\n BOOTSTRAP_RESET: \"bootstrap:reset\",\n});\n\nfunction norm(value, fallback = \"unknown\") {\n const trimmed = String(value ?? \"\").trim();\n return trimmed || fallback;\n}\n\nfunction expandHome(inputPath) {\n const raw = String(inputPath ?? \"\");\n if (!raw || !raw.startsWith(\"~\")) return raw;\n if (raw === \"~\") return os.homedir();\n if (raw.startsWith(\"~/\")) return path.join(os.homedir(), raw.slice(2));\n return raw;\n}\n\nexport function resolveDaemonWsHost(env = process.env) {\n const raw = String(env.ULTRACONTEXT_DAEMON_WS_HOST ?? env.ULTRACONTEXT_WS_HOST ?? \"\").trim();\n return raw || DEFAULT_DAEMON_WS_HOST;\n}\n\nexport function resolveDaemonWsPort(env = process.env) {\n const raw = Number.parseInt(String(env.ULTRACONTEXT_DAEMON_WS_PORT ?? env.ULTRACONTEXT_WS_PORT ?? \"\"), 10);\n if (Number.isInteger(raw) && raw >= 0 && raw <= 65535) return raw;\n return DEFAULT_DAEMON_WS_PORT;\n}\n\nexport function resolveDaemonWsInfoFile(env = process.env) {\n return expandHome(\n env.ULTRACONTEXT_DAEMON_INFO_FILE ??\n env.ULTRACONTEXT_DAEMON_WS_PORT_FILE ??\n env.ULTRACONTEXT_WS_INFO_FILE ??\n DEFAULT_DAEMON_INFO_FILE\n );\n}\n\nexport function resolveDaemonWsPortFile(env = process.env) {\n return resolveDaemonWsInfoFile(env);\n}\n\nexport function createBootstrapStateKey({ host, userId, sourceNames }) {\n const names = Array.isArray(sourceNames) ? sourceNames.map((name) => String(name ?? \"\").trim()).filter(Boolean) : [];\n const namesKey = names.sort().join(\",\");\n return `uc:daemon:bootstrap:${VERSION}:${norm(host)}:${norm(userId)}:${namesKey}`;\n}\n\nexport function normalizeBootstrapMode(raw, { allowPrompt = false } = {}) {\n const value = String(raw ?? \"\").trim().toLowerCase();\n if (allowPrompt && value === \"prompt\") return \"prompt\";\n if (value === \"new\" || value === \"new_only\" || value === \"latest\") return \"new_only\";\n if (value === \"24h\" || value === \"last_24h\" || value === \"last24h\") return \"last_24h\";\n if (value === \"all\" || value === \"full\") return \"all\";\n return \"\";\n}\n\nexport function parseProtocolJson(raw, fallback) {\n if (!raw) return fallback;\n try {\n return JSON.parse(raw);\n } catch {\n return fallback;\n }\n}\n\nexport function buildDaemonWsMessage(type, data = {}) {\n return { type: String(type ?? \"\"), data: data ?? {} };\n}\n\nexport function parseDaemonWsMessage(raw, fallback = null) {\n const parsed = typeof raw === \"string\" ? parseProtocolJson(raw, fallback) : raw;\n if (!parsed || typeof parsed !== \"object\") return fallback;\n const type = String(parsed.type ?? \"\").trim();\n if (!type) return fallback;\n return {\n ...parsed,\n type,\n data: parsed.data ?? {},\n };\n}\n"],"mappings":";;;;AAGA,MAAM,UAAU;AAChB,MAAM,yBAAyB;AAC/B,MAAM,yBAAyB;AAC/B,MAAM,2BAA2B;AAEjC,MAAa,0BAA0B,OAAO,OAAO;CACnD,UAAU;CACV,OAAO;CACP,KAAK;CACL,eAAe;CACf,cAAc;CACd,aAAa;CACb,MAAM;CACN,MAAM;CACN,YAAY;CACZ,YAAY;CACZ,iBAAiB;CAClB,CAAC;AAEF,SAAS,KAAK,OAAO,WAAW,WAAW;AAEzC,QADgB,OAAO,SAAS,GAAG,CAAC,MAAM,IACxB;;AAGpB,SAAS,WAAW,WAAW;CAC7B,MAAM,MAAM,OAAO,aAAa,GAAG;AACnC,KAAI,CAAC,OAAO,CAAC,IAAI,WAAW,IAAI,CAAE,QAAO;AACzC,KAAI,QAAQ,IAAK,QAAO,GAAG,SAAS;AACpC,KAAI,IAAI,WAAW,KAAK,CAAE,QAAO,KAAK,KAAK,GAAG,SAAS,EAAE,IAAI,MAAM,EAAE,CAAC;AACtE,QAAO;;AAGT,SAAgB,oBAAoB,MAAM,QAAQ,KAAK;AAErD,QADY,OAAO,IAAI,+BAA+B,IAAI,wBAAwB,GAAG,CAAC,MAAM,IAC9E;;AAGhB,SAAgB,oBAAoB,MAAM,QAAQ,KAAK;CACrD,MAAM,MAAM,OAAO,SAAS,OAAO,IAAI,+BAA+B,IAAI,wBAAwB,GAAG,EAAE,GAAG;AAC1G,KAAI,OAAO,UAAU,IAAI,IAAI,OAAO,KAAK,OAAO,MAAO,QAAO;AAC9D,QAAO;;AAGT,SAAgB,wBAAwB,MAAM,QAAQ,KAAK;AACzD,QAAO,WACL,IAAI,iCACF,IAAI,oCACJ,IAAI,6BACJ,yBACH;;AAOH,SAAgB,wBAAwB,EAAE,MAAM,QAAQ,eAAe;CAErE,MAAM,YADQ,MAAM,QAAQ,YAAY,GAAG,YAAY,KAAK,SAAS,OAAO,QAAQ,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,QAAQ,GAAG,EAAE,EAC7F,MAAM,CAAC,KAAK,IAAI;AACvC,QAAO,uBAAuB,QAAQ,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG;;AAGzE,SAAgB,uBAAuB,KAAK,EAAE,cAAc,UAAU,EAAE,EAAE;CACxE,MAAM,QAAQ,OAAO,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa;AACpD,KAAI,eAAe,UAAU,SAAU,QAAO;AAC9C,KAAI,UAAU,SAAS,UAAU,cAAc,UAAU,SAAU,QAAO;AAC1E,KAAI,UAAU,SAAS,UAAU,cAAc,UAAU,UAAW,QAAO;AAC3E,KAAI,UAAU,SAAS,UAAU,OAAQ,QAAO;AAChD,QAAO;;AAGT,SAAgB,kBAAkB,KAAK,UAAU;AAC/C,KAAI,CAAC,IAAK,QAAO;AACjB,KAAI;AACF,SAAO,KAAK,MAAM,IAAI;SAChB;AACN,SAAO;;;AAIX,SAAgB,qBAAqB,MAAM,OAAO,EAAE,EAAE;AACpD,QAAO;EAAE,MAAM,OAAO,QAAQ,GAAG;EAAE,MAAM,QAAQ,EAAE;EAAE;;AAGvD,SAAgB,qBAAqB,KAAK,WAAW,MAAM;CACzD,MAAM,SAAS,OAAO,QAAQ,WAAW,kBAAkB,KAAK,SAAS,GAAG;AAC5E,KAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;CAClD,MAAM,OAAO,OAAO,OAAO,QAAQ,GAAG,CAAC,MAAM;AAC7C,KAAI,CAAC,KAAM,QAAO;AAClB,QAAO;EACL,GAAG;EACH;EACA,MAAM,OAAO,QAAQ,EAAE;EACxB"}
@@ -1,5 +1,5 @@
1
1
  import { a as UC_CLAUDE_ORANGE, c as heroArtForWidth, i as UC_BRAND_BLUE, n as MENU_TABS, o as UC_CODEX_BLUE, r as UC_BLUE_LIGHT, s as UC_OPENCLAW_RED, t as Spinner } from "./Spinner-C_38udz8.mjs";
2
- import { a as parseDaemonWsMessage, c as resolveDaemonWsInfoFile, i as normalizeBootstrapMode, s as resolveDaemonWsHost, t as DAEMON_WS_MESSAGE_TYPES } from "./src-NyDFgJXL.mjs";
2
+ import { a as parseDaemonWsMessage, c as resolveDaemonWsInfoFile, i as normalizeBootstrapMode, s as resolveDaemonWsHost, t as DAEMON_WS_MESSAGE_TYPES } from "./src-Xh68VkBy.mjs";
3
3
  import process$1 from "node:process";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import path from "node:path";
@@ -748,7 +748,7 @@ function sparklineFromLag(history) {
748
748
  }).join("");
749
749
  }
750
750
  function clientLabel(client) {
751
- return `${compact(client.engineerId ?? "-", 12)}@${compact(client.host ?? "-", 20)}`;
751
+ return `${compact(client.userId ?? "-", 12)}@${compact(client.host ?? "-", 20)}`;
752
752
  }
753
753
  function compactClientLine(client, lagMs, sparkline, maxCols) {
754
754
  return fitToWidth(`● ${clientLabel(client)} lag ${formatLag(lagMs)} ${sparkline}`, maxCols);
@@ -760,7 +760,7 @@ function ClientsPanel({ clients, now, height, width }) {
760
760
  const historyRef = React.useRef(/* @__PURE__ */ new Map());
761
761
  const list = (Array.isArray(clients) ? clients : []).map((client) => ({
762
762
  ...client,
763
- id: `${String(client?.engineerId ?? "-")}@${String(client?.host ?? "-")}`,
763
+ id: `${String(client?.userId ?? "-")}@${String(client?.host ?? "-")}`,
764
764
  lagMs: Math.max(nowTs - Number(client?.ts ?? nowTs), 0)
765
765
  })).sort((a, b) => a.lagMs - b.lagMs);
766
766
  const activeClientIds = /* @__PURE__ */ new Set();
@@ -1210,7 +1210,7 @@ function ContextsContent({ snapshot, viewFocused, maxRows, maxCols }) {
1210
1210
  const rowColor = viewFocused && rowSelected ? UC_BLUE_LIGHT : "white";
1211
1211
  const sourceInfo = contextBadge(md.source || "unknown");
1212
1212
  const createdAt = formatContextDate(ctx?.created_at);
1213
- const engineer = compact(md.engineer_id ?? "-", 12);
1213
+ const user = compact(md.user_id ?? "-", 12);
1214
1214
  const sessionId = compact(md.session_id ?? "-", 28);
1215
1215
  rows.push(React.createElement(Text, {
1216
1216
  key: `contexts-row-${i}`,
@@ -1218,7 +1218,7 @@ function ContextsContent({ snapshot, viewFocused, maxRows, maxCols }) {
1218
1218
  }, `${marker} `, React.createElement(Text, {
1219
1219
  color: sourceInfo.color,
1220
1220
  bold: true
1221
- }, `[${sourceInfo.text}]`), ` ${createdAt} ${engineer} ${sessionId}`));
1221
+ }, `[${sourceInfo.text}]`), ` ${createdAt} ${user} ${sessionId}`));
1222
1222
  }
1223
1223
  }
1224
1224
  rows.push(...tailRows);
@@ -1258,7 +1258,7 @@ function HeaderPanel({ snapshot, stdoutColumns }) {
1258
1258
  const clientsOnline = Array.isArray(snapshot.onlineClients) ? snapshot.onlineClients.length : 0;
1259
1259
  const fittedTail = fitToWidth([
1260
1260
  `live ${formatTime(snapshot.now)}`,
1261
- `☻ ${snapshot.cfg.engineerId}`,
1261
+ `☻ ${snapshot.cfg.userId}`,
1262
1262
  `clients ${clientsOnline}`,
1263
1263
  `uptime ${formatUptime(Date.now() - Number(snapshot.stats.startedAt ?? 0))}`
1264
1264
  ].join(" │ "), Math.max(innerWidth - 7 - healthToken.length - 3, 0));
@@ -2032,7 +2032,7 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
2032
2032
  baseUrl: (process$1.env.ULTRACONTEXT_BASE_URL ?? "https://api.ultracontext.ai").trim(),
2033
2033
  daemonWsHost: resolveDaemonWsHost(process$1.env),
2034
2034
  daemonWsInfoFile: resolveDaemonWsInfoFile(process$1.env),
2035
- engineerId: process$1.env.DAEMON_ENGINEER_ID ?? process$1.env.USER ?? "unknown-engineer",
2035
+ userId: process$1.env.DAEMON_USER_ID ?? process$1.env.USER ?? "unknown-user",
2036
2036
  host: (process$1.env.DAEMON_HOST || os.hostname() || "unknown-host").trim(),
2037
2037
  uiRefreshMs: toInt(process$1.env.TUI_REFRESH_MS, 1200),
2038
2038
  resumeAutoRefreshMs: Math.max(toInt(process$1.env.RESUME_AUTO_REFRESH_MS, 3500), 0),
@@ -2289,13 +2289,13 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
2289
2289
  return false;
2290
2290
  }
2291
2291
  const host = String(snapshot.host ?? cfg.host);
2292
- const engineerId = String(snapshot.engineerId ?? cfg.engineerId);
2292
+ const userId = String(snapshot.userId ?? cfg.userId);
2293
2293
  const ts = Number(snapshot.ts ?? Date.now());
2294
2294
  const clientCountRaw = Number(snapshot.clients ?? 1);
2295
2295
  const clientCount = Number.isFinite(clientCountRaw) && clientCountRaw > 0 ? Math.floor(clientCountRaw) : 1;
2296
2296
  ui.onlineClients = Array.from({ length: clientCount }, () => ({
2297
2297
  host,
2298
- engineerId,
2298
+ userId,
2299
2299
  ts
2300
2300
  }));
2301
2301
  return true;
@@ -2720,9 +2720,7 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
2720
2720
  return contexts.filter((ctx) => {
2721
2721
  const md = ctx?.metadata ?? {};
2722
2722
  const source = String(md.source ?? "").toLowerCase();
2723
- const kind = String(md.context_kind ?? "");
2724
2723
  if (cfg.resumeSourceFilter !== "all" && source && source !== cfg.resumeSourceFilter) return false;
2725
- if (kind && kind !== "session") return false;
2726
2724
  return true;
2727
2725
  });
2728
2726
  }
@@ -2798,7 +2796,7 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
2798
2796
  `Context ID: ${context.id}`,
2799
2797
  `Created at: ${resumeFormatDate(context.created_at)}`,
2800
2798
  `Source: ${context.metadata?.source ?? "-"}`,
2801
- `Engineer: ${context.metadata?.engineer_id ?? "-"}`,
2799
+ `User: ${context.metadata?.user_id ?? "-"}`,
2802
2800
  `Session ID: ${context.metadata?.session_id ?? "-"}`,
2803
2801
  "",
2804
2802
  "## Snapshot",
@@ -3471,7 +3469,7 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
3471
3469
  options: UPDATE_PROMPT_OPTIONS
3472
3470
  },
3473
3471
  cfg: {
3474
- engineerId: cfg.engineerId,
3472
+ userId: cfg.userId,
3475
3473
  host: cfg.host,
3476
3474
  daemonWsHost: cfg.daemonWsHost,
3477
3475
  daemonWsInfoFile: cfg.daemonWsInfoFile,
@@ -3686,4 +3684,4 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
3686
3684
 
3687
3685
  //#endregion
3688
3686
  export { tuiBoot };
3689
- //# sourceMappingURL=tui-BwpUi10R.mjs.map
3687
+ //# sourceMappingURL=tui-DNqvslCq.mjs.map