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/README.md +40 -46
- package/dist/cli/entry.mjs +3 -3
- package/dist/cli/sdk-daemon.mjs +71 -92
- package/dist/cli/sdk-daemon.mjs.map +1 -1
- package/dist/{ctl-DaIi3tUU.mjs → ctl-9dwvaRrC.mjs} +3 -3
- package/dist/{ctl-DaIi3tUU.mjs.map → ctl-9dwvaRrC.mjs.map} +1 -1
- package/dist/index.d.mts +12 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +10 -1
- package/dist/index.mjs.map +1 -1
- package/dist/{launcher-VTbHuuaQ.mjs → launcher-DXUM0K-z.mjs} +4 -4
- package/dist/launcher-DXUM0K-z.mjs.map +1 -0
- package/dist/{lock-H7LKrRSb.mjs → lock-Q6z0l6Mr.mjs} +9 -4
- package/dist/lock-Q6z0l6Mr.mjs.map +1 -0
- package/dist/{src-NyDFgJXL.mjs → src-Xh68VkBy.mjs} +3 -3
- package/dist/src-Xh68VkBy.mjs.map +1 -0
- package/dist/{tui-BwpUi10R.mjs → tui-DNqvslCq.mjs} +12 -14
- package/dist/tui-DNqvslCq.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/launcher-VTbHuuaQ.mjs.map +0 -1
- package/dist/lock-H7LKrRSb.mjs.map +0 -1
- package/dist/src-NyDFgJXL.mjs.map +0 -1
- package/dist/tui-BwpUi10R.mjs.map +0 -1
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
|
package/dist/index.d.mts.map
CHANGED
|
@@ -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
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
|
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"
|
|
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
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -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":";AAgFA,IAAa,wBAAb,cAA2C,MAAM;CAK7C,YAAY,MAA0D;AAClE,QAAM,gCAAgC,KAAK,OAAO,GAAG,KAAK,MAAM;AAChE,OAAK,OAAO;AACZ,OAAK,SAAS,KAAK;AACnB,OAAK,MAAM,KAAK;AAChB,OAAK,WAAW,KAAK;;;AAI7B,IAAa,eAAb,MAA0B;CAOtB,YAAY,KAAyB;AACjC,OAAK,WAAW,IAAI,WAAW,+BAA+B,QAAQ,QAAQ,GAAG;AACjF,OAAK,SAAS,IAAI;AAClB,OAAK,UAAU,IAAI,SAAS;AAC5B,OAAK,UAAU,IAAI;AACnB,OAAK,YAAY,IAAI;;CAGzB,MAAM,OAAO,QAA4B,EAAE,EAAkC;AACzE,SAAO,KAAK,QAA+B,aAAa;GACpD,QAAQ;GACR,MAAM;GACT,CAAC;;CAGN,MAAM,OAAoB,WAAmB,OAAgD;AACzF,SAAO,KAAK,QAA2B,aAAa,mBAAmB,UAAU,IAAI;GACjF,QAAQ;GACR,MAAM;GACT,CAAC;;CAKN,MAAM,IACF,aACA,SACqD;AACrD,MAAI,CAAC,eAAe,OAAO,gBAAgB,UAAU;GACjD,MAAM,SAAS,IAAI,iBAAiB;AACpC,OAAI,OAAO,gBAAgB,YAAY,YAAY,MAAO,QAAO,IAAI,SAAS,OAAO,YAAY,MAAM,CAAC;GACxG,MAAM,QAAQ,OAAO,UAAU;AAC/B,UAAO,KAAK,QAA8B,YAAY,QAAQ,IAAI,UAAU,MAAM,EAAE,QAAQ,OAAO,CAAC;;EAGxG,MAAM,SAAS,IAAI,iBAAiB;AACpC,MAAI,SAAS,YAAY,OAAW,QAAO,IAAI,WAAW,OAAO,QAAQ,QAAQ,CAAC;AAClF,MAAI,SAAS,OAAO,OAAW,QAAO,IAAI,MAAM,OAAO,QAAQ,GAAG,CAAC;AACnE,MAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,QAAQ,OAAO;AACzD,MAAI,SAAS,QAAS,QAAO,IAAI,WAAW,OAAO;EACnD,MAAM,QAAQ,OAAO,UAAU;AAC/B,SAAO,KAAK,QAA+B,aAAa,mBAAmB,YAAY,GAAG,QAAQ,IAAI,UAAU,MAAM,EAAE,QAAQ,OAAO,CAAC;;CAG5I,MAAM,OAAoB,WAAmB,OAAoB,SAAuD;EACpH,MAAM,OAAO,SAAS,WAChB;GAAE,SAAS,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;GAAE,UAAU,QAAQ;GAAU,GAC/E;AAEN,SAAO,KAAK,QAA2B,aAAa,mBAAmB,UAAU,IAAI;GACjF,QAAQ;GACR;GACH,CAAC;;CAGN,MAAM,OAAoB,WAAmB,KAAkB,SAAuD;AAClH,SAAO,KAAK,QAA2B,aAAa,mBAAmB,UAAU,IAAI;GACjF,QAAQ;GACR,MAAM;IAAE;IAAK,UAAU,SAAS;IAAU;GAC7C,CAAC;;CAGN,MAAc,QAAW,MAAc,MAAwF;EAC3H,MAAM,MAAM,GAAG,KAAK,UAAU,KAAK,WAAW,IAAI,GAAG,KAAK,MAAM;EAEhE,MAAM,UAAkC;GACpC,eAAe,UAAU,KAAK;GAC9B,GAAI,KAAK,WAAW,EAAE;GACtB,GAAI,KAAK,WAAW,EAAE;GACzB;EAED,IAAI;AACJ,MAAI,KAAK,SAAS,QAAW;AACzB,WAAQ,kBAAkB,QAAQ,mBAAmB;AACrD,UAAO,KAAK,UAAU,KAAK,KAAK;;EAGpC,MAAM,KAAK,KAAK,YAAY,IAAI,iBAAiB,GAAG;EACpD,MAAM,UAAU,KAAK,YAAY,iBAAiB,IAAI,OAAO,EAAE,KAAK,UAAU,GAAG;AAEjF,MAAI;GACA,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;IAChC,QAAQ,KAAK;IACb;IACA;IACA,QAAQ,IAAI;IACf,CAAC;AAEF,OAAI,CAAC,IAAI,IAAI;IACT,MAAM,WAAW,MAAM,aAAa,IAAI;AACxC,UAAM,IAAI,sBAAsB;KAAE,QAAQ,IAAI;KAAQ;KAAK;KAAU,CAAC;;AAG1E,OAAI,IAAI,WAAW,IAAK,QAAO;AAG/B,QADoB,IAAI,QAAQ,IAAI,eAAe,IAAI,IACvC,SAAS,mBAAmB,CAAE,QAAQ,MAAM,IAAI,MAAM;AACtE,UAAQ,MAAM,IAAI,MAAM;YAClB;AACN,OAAI,QAAS,cAAa,QAAQ;;;;AAK9C,eAAe,aAAa,KAAe;AACvC,KAAI;AACA,SAAO,MAAM,IAAI,MAAM;SACnB;AACJ"}
|
|
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-
|
|
2
|
-
import { c as resolveDaemonWsInfoFile } from "./src-
|
|
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
|
-
|
|
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-
|
|
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),
|
|
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
|
-
|
|
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 {
|
|
132
|
-
//# sourceMappingURL=lock-
|
|
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,
|
|
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(
|
|
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-
|
|
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-
|
|
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.
|
|
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?.
|
|
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
|
|
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} ${
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
`
|
|
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
|
-
|
|
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-
|
|
3687
|
+
//# sourceMappingURL=tui-DNqvslCq.mjs.map
|