needle-cloud 2.11.0 → 2.11.1

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/cli.esm.js CHANGED
@@ -1 +1 @@
1
- import"node-fetch";import"@web-std/file";import"node:crypto";export{p as program}from"./cli-05c1463b.js";import"fs";import"dotenv";import"ora";import"commander";import"child_process";import"open";import"path";import"node:fs";import"node:fs/promises";import"node:os";import"node:path";import"util";import"stream";import"http";import"https";import"url";import"crypto";import"net";import"tls";import"assert";import"tty";import"os";import"events";import"http2";import"zlib";import"node:console";import"node:readline/promises";import"@logto/node";import"node:readline";import"node:stream";import"node:zlib";import"express";import"ws";import"node:child_process";import"minimatch";import"node:url";import"node:util";import"body-parser";import"node:timers/promises";
1
+ import"node-fetch";import"@web-std/file";import"node:crypto";export{p as program}from"./cli-bf2fbb2a.js";import"fs";import"dotenv";import"ora";import"commander";import"child_process";import"open";import"path";import"node:fs";import"node:fs/promises";import"node:os";import"node:path";import"util";import"stream";import"http";import"https";import"url";import"crypto";import"net";import"tls";import"assert";import"tty";import"os";import"events";import"http2";import"zlib";import"node:console";import"node:readline/promises";import"@logto/node";import"node:readline";import"node:stream";import"node:zlib";import"express";import"ws";import"node:child_process";import"minimatch";import"node:url";import"node:util";import"body-parser";import"node:timers/promises";
@@ -1 +1 @@
1
- import{existsSync as o,readdirSync as t,statSync as r}from"node:fs";import{dirname as i,join as e}from"node:path";import{g as n}from"./cli-05c1463b.js";import"node-fetch";import"@web-std/file";import"node:crypto";import"commander";import"fs";import"child_process";import"open";import"path";import"ora";import"node:fs/promises";import"node:os";import"util";import"stream";import"http";import"https";import"url";import"crypto";import"net";import"tls";import"assert";import"tty";import"os";import"events";import"http2";import"zlib";import"node:console";import"node:readline/promises";import"dotenv";import"@logto/node";import"node:readline";import"node:stream";import"node:zlib";import"express";import"ws";import"node:child_process";import"minimatch";import"node:url";import"node:util";import"body-parser";import"node:timers/promises";function p(){var p;let m;try{m=n()}catch{return null}const s=null==(p=m)||null==(p=p.entries)?void 0:p[0];if(!s)return null;if(!s.log_location)return null;if("unity"!==s.editor&&"blender"!==s.editor)return null;if(!o(s.log_location))return null;const l=s.log_location,d=function(o,i){const n=new Set([i]);try{for(const i of t(o)){if(!i.toLowerCase().endsWith(".log"))continue;const t=e(o,i);try{if(!r(t).isFile())continue}catch{continue}n.add(t)}}catch{}return[...n]}(i(l),l);return{editor:s.editor,path:l,paths:d}}export{p as findActiveEditorLog};
1
+ import{existsSync as o,readdirSync as t,statSync as r}from"node:fs";import{dirname as i,join as e}from"node:path";import{g as n}from"./cli-bf2fbb2a.js";import"node-fetch";import"@web-std/file";import"node:crypto";import"commander";import"fs";import"child_process";import"open";import"path";import"ora";import"node:fs/promises";import"node:os";import"util";import"stream";import"http";import"https";import"url";import"crypto";import"net";import"tls";import"assert";import"tty";import"os";import"events";import"http2";import"zlib";import"node:console";import"node:readline/promises";import"dotenv";import"@logto/node";import"node:readline";import"node:stream";import"node:zlib";import"express";import"ws";import"node:child_process";import"minimatch";import"node:url";import"node:util";import"body-parser";import"node:timers/promises";function p(){var p;let m;try{m=n()}catch{return null}const s=null==(p=m)||null==(p=p.entries)?void 0:p[0];if(!s)return null;if(!s.log_location)return null;if("unity"!==s.editor&&"blender"!==s.editor)return null;if(!o(s.log_location))return null;const l=s.log_location,d=function(o,i){const n=new Set([i]);try{for(const i of t(o)){if(!i.toLowerCase().endsWith(".log"))continue;const t=e(o,i);try{if(!r(t).isFile())continue}catch{continue}n.add(t)}}catch{}return[...n]}(i(l),l);return{editor:s.editor,path:l,paths:d}}export{p as findActiveEditorLog};
package/dist/index.d.ts CHANGED
@@ -32,6 +32,8 @@ type LogtoUserCustomData$1 = {
32
32
  }
33
33
 
34
34
  declare namespace Auth {
35
+ /** @param {Pick<Console, "debug" | "info" | "warn" | "error">} output */
36
+ function setLogger(output: Pick<Console, "debug" | "info" | "warn" | "error">): void;
35
37
  /** @param {boolean} _debug */
36
38
  function setDebug(_debug: boolean): void;
37
39
  let baseUrl: any;
@@ -227,6 +229,15 @@ type License = NeedleEngineLicense | NeedleCloudLicense | OneTimePurchase;
227
229
  /** Current state of a subscription-backed license. */
228
230
  type LicenseSubscriptionStatus = "active" | "canceled" | "incomplete" | "incomplete_expired" | "past_due" | "paused" | "trialing" | "unpaid";
229
231
 
232
+ /** Recovery options when the monthly AI allowance and available credits are exhausted. */
233
+ interface AIQuotaErrorData {
234
+ code: 'ai_allowance_exhausted';
235
+ limit_reached: true;
236
+ message: string;
237
+ account_id: string;
238
+ actions: Array<{ kind: 'top_up' | 'view_usage'; label: string; url: string }>;
239
+ }
240
+
230
241
  type AiTokenUsageInfo = {
231
242
  /** @deprecated Always 0. Use monthly_allowance_used01 for the shared AI allowance. */
232
243
  max_available: number,
@@ -246,6 +257,8 @@ type AiTokenUsageInfo = {
246
257
  type RecentChatsResponse$1 = {
247
258
  data: Array<{
248
259
  chat_id: string,
260
+ /** Cloud projects associated with this conversation, across project types. */
261
+ project_ids?: string[],
249
262
  slug: string,
250
263
  topic: string,
251
264
  created_at: string,
@@ -278,8 +291,58 @@ type ClientContext =
278
291
  | { type: "text", text: string }
279
292
  | ClientImage
280
293
 
294
+ /**
295
+ * Reply to an `elicitation` stream event. Carries the `action_id` from that event
296
+ * plus the user's answer: `value` (a chosen option), `text` (free-text), or
297
+ * `canceled`. The server resumes the AI turn (for `ask`) or runs the authorized
298
+ * write action (for `confirm_action`) and streams the continuation.
299
+ */
300
+ type AIChatRequestBody_ElicitationResponse = {
301
+ type: "elicitation_response",
302
+ slug: string,
303
+ action_id: string,
304
+ /** The chosen option value (must be one the server offered). */
305
+ value?: string,
306
+ /** Free-text answer, when the elicitation offered a text field. */
307
+ text?: string,
308
+ /** The user dismissed the request without choosing. */
309
+ canceled?: boolean,
310
+ /** Current browser session when answering a local file-edit permission request. */
311
+ file_edit_session_id?: string,
312
+ /** Current browser session when approving a local project command. */
313
+ local_command_session_id?: string,
314
+ /** Explicit Cloud opt-in to retain local file-edit tools after an answer. */
315
+ allow_file_edits?: boolean,
316
+ /** Explicit Cloud opt-in to retain local project commands after an answer. */
317
+ allow_local_commands?: boolean,
318
+ /** Current Cloud page URL for the continuation. */
319
+ full_url?: string,
320
+ stream?: boolean,
321
+ }
322
+
323
+
324
+ /** Rendering features explicitly supported by this chat consumer. */
325
+ type ChatClientCapabilities$1 = { inlineToolCalls?: boolean };
326
+ /** Update ordered inline parts before applying the event to the message's plain content. */
327
+ declare function updateInlineChatParts(
328
+ current: ChatInlinePart$1[] | undefined,
329
+ content: string,
330
+ event: ChatStreamEvent,
331
+ ): ChatInlinePart$1[] | undefined;
332
+
333
+ /** Vercel UIMessage-compatible subset for inline text and dynamic tools. */
334
+ type ChatInlinePart$1 =
335
+ | { type: 'text', text: string, state?: 'streaming' | 'done' }
336
+ | ({ type: 'dynamic-tool', toolCallId: string, toolName: string, title?: string, input: unknown } & (
337
+ | { state: 'input-available' }
338
+ | { state: 'output-available', output: { result_length?: number, duration_ms?: number } }
339
+ ));
281
340
 
282
341
  type ChatMessageToolCall = {
342
+ /** Stable invocation identity, when available. */
343
+ toolCallId?: string,
344
+ /** Position in the assistant text, measured in UTF-16 code units. */
345
+ contentOffset?: number,
283
346
  name: string,
284
347
  /** Server-provided pretty label for the tool, when the tool author set one
285
348
  * (streamed on the tool_call event). The UI prefers this over title-casing
@@ -315,6 +378,8 @@ type ChatMessage = {
315
378
  role: "assistant" | "tool" | "user",
316
379
  content: string,
317
380
  tool_calls?: ChatMessageToolCall[],
381
+ /** Ordered inline content when requested and available. */
382
+ parts?: ChatInlinePart$1[],
318
383
  /** Images belonging to this message. Absent on the vast majority of messages. */
319
384
  attachments?: ChatMessageAttachment[],
320
385
  metadata?: {
@@ -339,6 +404,8 @@ type ChatMessage = {
339
404
  } | null,
340
405
  }
341
406
  type AIChatGETResponse = {
407
+ /** Cloud projects associated with this conversation, across project types. */
408
+ project_ids?: string[],
342
409
  /** Null when no chat exists yet for the requested slug. */
343
410
  chat_id: string | null,
344
411
  messages: Array<ChatMessage>,
@@ -370,6 +437,8 @@ type AIChatSyncResponse = {
370
437
  role: "assistant",
371
438
  content: string,
372
439
  tool_calls?: ChatMessageToolCall[],
440
+ /** Ordered inline content when requested and available. */
441
+ parts?: ChatInlinePart$1[],
373
442
  metadata?: ChatMessage["metadata"],
374
443
  token_usage?: AiTokenUsageInfo | null,
375
444
  /** Full URL to view this chat on the Needle Cloud frontend. */
@@ -390,8 +459,7 @@ type AICompletionResponse = {
390
459
  text: string,
391
460
  token_usage: AiTokenUsageInfo,
392
461
  }
393
-
394
- /** JSON data supplied as context or instructions for an evaluation. */
462
+ /** JSON context or instructions. Embed image_url parts with base64 PNG/JPEG data URLs. Remote image URLs are not supported. */
395
463
  type AIEvaluationValue = string | number | boolean | null | AIEvaluationValue[] | { [key: string]: AIEvaluationValue };
396
464
  type AIEvaluationState$1 = string | AIEvaluationValue[] | { [key: string]: AIEvaluationValue };
397
465
  /** A focused question to evaluate against the supplied state. */
@@ -409,6 +477,18 @@ type AIEvaluationAnswer$1 =
409
477
  type AIEvaluationResponse$1 = { answers: Record<string, AIEvaluationAnswer$1>, token_usage: AiTokenUsageInfo };
410
478
  type AIEvaluationOptions$1 = { signal?: AbortSignal };
411
479
 
480
+ /** Metadata for one main chat provider request; byte counts are not token counts. */
481
+ interface ChatRequestDiagnostics$1 {
482
+ requestIndex: number;
483
+ model: string;
484
+ requestBytes: number;
485
+ messagesBytes: number;
486
+ toolsBytes: number;
487
+ messageCount: number;
488
+ messageRoles: Record<string, number>;
489
+ toolCount: number;
490
+ }
491
+
412
492
  /**
413
493
  * Discriminated union for events yielded by the SSE chat stream.
414
494
  *
@@ -430,6 +510,9 @@ type AIEvaluationOptions$1 = { signal?: AbortSignal };
430
510
  type ChatStreamEvent = { /** SSE event id for position tracking. */ id?: number } & (
431
511
  /** Streaming text chunk — append to the current AI message. */
432
512
  | { type: "delta", content: string }
513
+ | { type: 'tool-input-available', toolCallId: string, toolName: string, title?: string, input: unknown }
514
+ | { type: 'tool-output-available', toolCallId: string, output: { result_length?: number, duration_ms?: number } }
515
+ | { type: "request_diagnostics", diagnostics: ChatRequestDiagnostics$1 }
433
516
  /** Complete message text (sent once at the end, contains the full response). */
434
517
  | { type: "message", content: string }
435
518
  /** Server-assigned message ID for the AI response. */
@@ -445,7 +528,7 @@ type ChatStreamEvent = { /** SSE event id for position tracking. */ id?: number
445
528
  /** User messages joined this generation between tool rounds. Start a new assistant message after them. */
446
529
  | { type: "message_inserted", messages: Array<{ id: string, content: string }>, assistant_message_id: string }
447
530
  /** An error occurred. Display `message` to the user. */
448
- | { type: "error", message: string }
531
+ | { type: "error", message: string, details?: AIQuotaErrorData }
449
532
  /**
450
533
  * A non-fatal problem the USER should see, rendered as its own line rather
451
534
  * than folded into the answer. First case: a step whose model cannot view
@@ -581,6 +664,7 @@ type WebSocketLike = {
581
664
  * before allowing messages. If no tools are provided, it's HTTP-only.
582
665
  */
583
666
  type ChatSessionOptions$1 = {
667
+ capabilities?: ChatClientCapabilities$1,
584
668
  /** Source identifier (e.g. "editor", "cli", "my-app"). Defaults to "sdk". */
585
669
  source?: string,
586
670
  /** Tools to register via WebSocket. If empty/omitted, no WS connection is made. */
@@ -641,6 +725,8 @@ type ChatSessionHandle$1 = {
641
725
  * Internally awaits `ready` before sending.
642
726
  */
643
727
  sendMessage(slug: string, message: string, options?: ChatSessionSendOptions$1): AsyncGenerator<ChatStreamEvent>,
728
+ /** Answer or dismiss a pending question and stream the continuation. Awaits ready before sending. */
729
+ sendElicitationResponse(slug: string, response: Pick<AIChatRequestBody_ElicitationResponse, 'action_id' | 'value' | 'text' | 'canceled'>, options?: ChatSessionSendOptions$1): AsyncGenerator<ChatStreamEvent>,
644
730
  /**
645
731
  * Send a message and get a single JSON response (non-streaming).
646
732
  * Internally awaits `ready` before sending.
@@ -662,8 +748,10 @@ type ChatSessionHandle$1 = {
662
748
  * arrived) and reading the finished answer via `readChat`.
663
749
  */
664
750
  reconnectChat(slug: string): Promise<AsyncGenerator<ChatStreamEvent> | null>,
751
+ /** Add a project association without sending a message; existing links are retained. */
752
+ associateProject(slug: string, projectId: string): Promise<void>,
665
753
  /** List recent chats. */
666
- listChats(): Promise<RecentChatsResponse$1>,
754
+ listChats(options?: { projectId?: string }): Promise<RecentChatsResponse$1>,
667
755
  /**
668
756
  * Start a new chat: returns a fresh, unique slug. Pass it to `sendMessage` /
669
757
  * `sendMessageSync` to begin the conversation (the chat is created on the first message).
@@ -697,6 +785,8 @@ type ChatSessionHandle$1 = {
697
785
 
698
786
  /** Options for `ChatSessionHandle.sendMessage()` and `sendMessageSync()`. */
699
787
  type ChatSessionSendOptions$1 = {
788
+ /** Optional Cloud project to add to this conversation's associations, independent of project type. */
789
+ projectId?: string,
700
790
  /** Allow this chat to request local file edit approval. Defaults to false; this is not permission to write. */
701
791
  allowFileEdits?: boolean,
702
792
  /** Current local chat session ID used for a separate user approval. */
@@ -715,6 +805,13 @@ type ChatSessionSendOptions$1 = {
715
805
  context?: ClientContext[],
716
806
  }
717
807
 
808
+ /** HTTP chat failure with optional quota recovery actions. */
809
+ declare class AIChatError extends Error {
810
+ constructor(message: string, status: number, details?: AIQuotaErrorData | null);
811
+ status: number;
812
+ details: AIQuotaErrorData | null;
813
+ }
814
+
718
815
  /**
719
816
  * @internal Needle editor cloud projects — versioned revisions of OPAQUE
720
817
  * project documents (needle-cloud plans/cloud-projects-api.md). Editor-only,
@@ -2055,10 +2152,12 @@ type Deployment = {
2055
2152
 
2056
2153
  /**
2057
2154
  * List recent AI chats for the authenticated user.
2058
- * @param {ChatAuthOpts} [opts]
2155
+ * @param {ChatAuthOpts & { projectId?: string }} [opts]
2059
2156
  * @returns {Promise<RecentChatsResponse>}
2060
2157
  */
2061
- declare function listChats(opts?: ChatAuthOpts): Promise<RecentChatsResponse>;
2158
+ declare function listChats(opts?: ChatAuthOpts & {
2159
+ projectId?: string;
2160
+ }): Promise<RecentChatsResponse>;
2062
2161
  /**
2063
2162
  * Create a coordinated chat session with optional WebSocket tool support.
2064
2163
  *
@@ -2131,6 +2230,7 @@ type ChatAuthOpts = {
2131
2230
  type RecentChatsResponse = RecentChatsResponse$1;
2132
2231
  type ChatSessionOptions = ChatSessionOptions$1;
2133
2232
  type ChatSessionHandle = ChatSessionHandle$1;
2233
+ type ChatRequestDiagnostics = ChatRequestDiagnostics$1;
2134
2234
  type ChatSessionSendOptions = ChatSessionSendOptions$1;
2135
2235
  type ToolDefinition = ToolDefinition$1;
2136
2236
  type AIEvaluationState = AIEvaluationState$1;
@@ -2139,6 +2239,8 @@ type AIEvaluationQuestions = AIEvaluationQuestions$1;
2139
2239
  type AIEvaluationAnswer = AIEvaluationAnswer$1;
2140
2240
  type AIEvaluationResponse = AIEvaluationResponse$1;
2141
2241
  type AIEvaluationOptions = AIEvaluationOptions$1;
2242
+ type ChatInlinePart = ChatInlinePart$1;
2243
+ type ChatClientCapabilities = ChatClientCapabilities$1;
2142
2244
 
2143
2245
  /**
2144
2246
  * List publicly discoverable content items on Needle Cloud.
@@ -2705,5 +2807,5 @@ declare namespace AuthScopes {
2705
2807
  let All: string[];
2706
2808
  }
2707
2809
 
2708
- export { Auth, AuthScopes, NeedleLoginButton, aiComplete, aiEvaluate, archiveProject, checkProjectBlobs, checkoutProduct, cloneProject, completeProjectBlobUpload, createChatSession, createProject, deleteContent, deleteProject, generate3dAsset, getContent, getDeployments, getProductInformation, getProjectDeployments, getProjectHead, getProjectPromotions, getPublicContent, getRuntimeRelease, getRuntimeSnapshot, getUserLicenses, listChats, listContent, listProjectRevisions, listProjects, listPublicContent, ownsProduct, promoteProjectAsset, pullProjectRevision, pushProjectRevision, recordProjectDeployment, requestProjectBlobDownload, requestProjectBlobUpload, restoreProject, startCheckoutSession, unarchiveProject, updateContent, updateProject, updateProjectRevision, uploadFiles };
2709
- export type { AIEvaluationAnswer, AIEvaluationOptions, AIEvaluationQuestion, AIEvaluationQuestions, AIEvaluationResponse, AIEvaluationState, AuthData, AuthInitOpts, ChatAuthOpts, ChatSessionHandle, ChatSessionOptions, ChatSessionSendOptions, Deployment, Filelike, LogtoUserCustomData, RecentChatsResponse, ResourceUrl, ToolDefinition, UserInfoResponse };
2810
+ export { AIChatError, Auth, AuthScopes, NeedleLoginButton, aiComplete, aiEvaluate, archiveProject, checkProjectBlobs, checkoutProduct, cloneProject, completeProjectBlobUpload, createChatSession, createProject, deleteContent, deleteProject, generate3dAsset, getContent, getDeployments, getProductInformation, getProjectDeployments, getProjectHead, getProjectPromotions, getPublicContent, getRuntimeRelease, getRuntimeSnapshot, getUserLicenses, listChats, listContent, listProjectRevisions, listProjects, listPublicContent, ownsProduct, promoteProjectAsset, pullProjectRevision, pushProjectRevision, recordProjectDeployment, requestProjectBlobDownload, requestProjectBlobUpload, restoreProject, startCheckoutSession, unarchiveProject, updateContent, updateInlineChatParts, updateProject, updateProjectRevision, uploadFiles };
2811
+ export type { AIEvaluationAnswer, AIEvaluationOptions, AIEvaluationQuestion, AIEvaluationQuestions, AIEvaluationResponse, AIEvaluationState, AuthData, AuthInitOpts, ChatAuthOpts, ChatClientCapabilities, ChatInlinePart, ChatRequestDiagnostics, ChatSessionHandle, ChatSessionOptions, ChatSessionSendOptions, Deployment, Filelike, LogtoUserCustomData, RecentChatsResponse, ResourceUrl, ToolDefinition, UserInfoResponse };