lua-cli 3.27.0 → 3.29.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 CHANGED
@@ -44,7 +44,7 @@ lua --version
44
44
 
45
45
  ## Authentication
46
46
 
47
- lua-cli authenticates using your API key. Get yours at [admin.heylua.ai](https://admin.heylua.ai).
47
+ lua-cli authenticates with a scoped personal credential or an existing API key. New email login limits the credential to the organization, agents, and role you select. Existing scoped and non-dotted legacy keys remain supported when you supply them directly.
48
48
 
49
49
  The key is resolved from the following sources in priority order:
50
50
 
@@ -60,21 +60,31 @@ The key is resolved from the following sources in priority order:
60
60
  lua auth configure
61
61
  ```
62
62
 
63
- Prompts you to choose between entering an API key directly or authenticating via email OTP. Credentials are saved to `~/.lua-cli/credentials`.
63
+ Choose **Email** to confirm an OTP. Select one organization, one or more agents, and an assignable role. Builder is the default role. The CLI stores the scoped credential in `~/.lua-cli/credentials` with mode `0600` on POSIX systems.
64
+
65
+ Choose **API Key** to validate and save an existing scoped or legacy key unchanged. The CLI does not rotate or revoke the supplied key.
64
66
 
65
67
  ```bash
66
68
  # Non-interactive variants:
67
- lua auth configure --api-key "lk_your_api_key_here"
68
- lua auth configure --email user@example.com # Step 1: sends OTP
69
- lua auth configure --email user@example.com --otp 123456 # Step 2: verifies OTP
69
+ lua auth configure --api-key "your-api-key"
70
+ lua auth configure --email user@example.com
71
+ lua auth configure \
72
+ --email user@example.com \
73
+ --otp 123456 \
74
+ --org-id org_123 \
75
+ --agent-id agent_123 \
76
+ --role builder \
77
+ --name "deployment laptop"
70
78
  ```
71
79
 
80
+ Repeat `--agent-id` to bind the credential to more than one agent. For a new local login, prefer the interactive command and keep the email, OTP, and secret out of AI conversations.
81
+
72
82
  ### Option B — Environment variable (CI/CD, Docker, servers)
73
83
 
74
84
  Set `LUA_API_KEY` in your environment. This takes priority over all other sources and requires no file on disk — ideal for headless servers, VMs, and containers.
75
85
 
76
86
  ```bash
77
- export LUA_API_KEY="lk_your_api_key_here"
87
+ export LUA_API_KEY="your-api-key"
78
88
  lua push all --force --auto-deploy
79
89
  ```
80
90
 
@@ -83,7 +93,7 @@ lua push all --force --auto-deploy
83
93
  Create a `.env` file in your project root:
84
94
 
85
95
  ```bash
86
- echo 'LUA_API_KEY=lk_your_api_key_here' >> .env
96
+ echo 'LUA_API_KEY=your-api-key' >> .env
87
97
  ```
88
98
 
89
99
  lua-cli automatically loads `.env` on startup. Add `.env` to your `.gitignore` to avoid committing credentials.
@@ -138,7 +148,7 @@ lua auth logout --force # No prompt
138
148
  lua auth configure
139
149
  ```
140
150
 
141
- Enter your API key when prompted (get one at [admin.heylua.ai](https://admin.heylua.ai)). For CI/CD or server environments, set `LUA_API_KEY` as an environment variable instead — see [Authentication](#authentication) above.
151
+ Choose **Email** and select the organization, agents, and role for the new scoped credential. If you already have a working key, choose **API Key** to keep using it unchanged. For CI or server environments, set `LUA_API_KEY` from a secret manager. See [Authentication](#authentication).
142
152
 
143
153
  ### 2. Initialize Project
144
154
 
@@ -415,7 +415,10 @@ declare interface ApiResponse<T = any> {
415
415
  message: string;
416
416
  code?: string;
417
417
  statusCode?: number;
418
+ retryAfterSeconds?: number;
418
419
  error?: string;
420
+ oldAccountLabel?: string;
421
+ newAccountLabel?: string;
419
422
  };
420
423
  }
421
424
 
@@ -1774,11 +1777,12 @@ declare type HeadersResolverFunction = () => Record<string, string>;
1774
1777
  */
1775
1778
  declare abstract class HttpClient {
1776
1779
  protected baseUrl: string;
1780
+ private readonly requestCredential?;
1777
1781
  /**
1778
1782
  * Creates an instance of HttpClient
1779
1783
  * @param baseUrl - The base URL for all API requests
1780
1784
  */
1781
- constructor(baseUrl: string);
1785
+ constructor(baseUrl: string, requestCredential?: RequestCredentialInput | undefined);
1782
1786
  /**
1783
1787
  * Makes an HTTP request with standardized error handling
1784
1788
  * @param url - The full URL to request
@@ -1829,6 +1833,13 @@ declare abstract class HttpClient {
1829
1833
  * @protected
1830
1834
  */
1831
1835
  protected httpPost<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>>;
1836
+ /**
1837
+ * Performs one HTTP POST attempt.
1838
+ *
1839
+ * Use this only when a successful response contains a one-time secret that
1840
+ * cannot be recovered after an ambiguous network or server failure.
1841
+ */
1842
+ protected httpPostOnce<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>>;
1832
1843
  /**
1833
1844
  * Performs an HTTP PUT request
1834
1845
  * @param url - The relative URL path to request (will be appended to baseUrl)
@@ -1925,6 +1936,18 @@ declare interface InboxPushInput {
1925
1936
  /** Idempotency/revision key: same key = revise the existing card in place,
1926
1937
  * never a second knock. Omit for one-shot notices. */
1927
1938
  key?: string;
1939
+ /** Cross-route resolution (PRO-1208 follow-up #2) — only meaningful on a
1940
+ * plain NOTICE push that carries a `key`. When `true`, this notice
1941
+ * declares it REPORTS THE RESOLUTION of whatever an open same-key
1942
+ * question card is still asking — the agent settled the cycle itself
1943
+ * (re-reviewed after the fix landed and auto-approved; the incident
1944
+ * closed on its own). Once the notice lands, the stale question card is
1945
+ * superseded: settled, no live actions, and never a knock. An in-flight
1946
+ * user answer always wins — their explicit decision stands. WITHOUT this
1947
+ * flag a same-key notice never touches the question track: routine
1948
+ * progress updates coexist with an open ask. Ignored without `key`, and
1949
+ * on question/fix pushes. Must be the literal boolean `true`. */
1950
+ resolvesQuestion?: boolean;
1928
1951
  /** Conversation the card should hand off into when the user acts. */
1929
1952
  threadId?: string;
1930
1953
  }
@@ -2056,15 +2079,15 @@ declare interface Job {
2056
2079
  * Handles all job-related API calls
2057
2080
  */
2058
2081
  declare class JobApi extends HttpClient {
2059
- apiKey: string;
2060
2082
  agentId: string;
2083
+ readonly credential: RequestCredentialInput;
2061
2084
  /**
2062
2085
  * Creates an instance of JobApi
2063
2086
  * @param baseUrl - The base URL for the API
2064
- * @param apiKey - The API key for authentication
2087
+ * @param credential - The API key for authentication
2065
2088
  * @param agentId - The unique identifier of the agent
2066
2089
  */
2067
- constructor(baseUrl: string, apiKey: string, agentId: string);
2090
+ constructor(baseUrl: string, credential: RequestCredentialInput, agentId: string);
2068
2091
  /**
2069
2092
  * Retrieves all jobs for the agent
2070
2093
  * @returns Promise resolving to an ApiResponse containing an array of jobs with their versions
@@ -3262,6 +3285,10 @@ export declare class LuaTrigger<T = any> {
3262
3285
  readonly verify?: (ctx: TriggerContext<T>) => boolean | Promise<boolean>;
3263
3286
  readonly filter?: (ctx: TriggerContext<T>) => boolean | Promise<boolean>;
3264
3287
  readonly transform?: (ctx: TriggerContext<T>) => string | AgentInvocationInput | Promise<string | AgentInvocationInput>;
3288
+ readonly tool?: {
3289
+ name: string;
3290
+ input?: (ctx: TriggerContext<T>) => Record<string, unknown> | Promise<Record<string, unknown>>;
3291
+ };
3265
3292
  constructor(config: LuaTriggerConfig<T>);
3266
3293
  getName(): string;
3267
3294
  getDescription(): string;
@@ -3301,6 +3328,24 @@ export declare interface LuaTriggerConfig<T = any> {
3301
3328
  * transform to forward larger or hand-picked fields as the message.
3302
3329
  */
3303
3330
  transform?: (ctx: TriggerContext<T>) => string | AgentInvocationInput | Promise<string | AgentInvocationInput>;
3331
+ /**
3332
+ * Direct tool binding: after `verify`/`filter` pass, the platform executes
3333
+ * this named skill tool DIRECTLY — no chat turn, no LLM, no visible
3334
+ * conversation thread. `name` is the BARE authored tool name (skill-first
3335
+ * resolution server-side); it must be a static string literal — the
3336
+ * compiler carries it into the trigger version as declared metadata.
3337
+ * `input` maps the trigger context to the tool's arguments and runs in the
3338
+ * same server-side slot sandbox (15s budget shared with verify/filter) —
3339
+ * it CANNOT call platform APIs. Omit `input` to execute with `{}`.
3340
+ *
3341
+ * Declaring BOTH `tool` and `transform` runs the tool; the transform is
3342
+ * ignored (the compiler warns). Approval-gated tools are refused server-
3343
+ * side (fail closed) — the execution row records the refusal.
3344
+ */
3345
+ tool?: {
3346
+ name: string;
3347
+ input?: (ctx: TriggerContext<T>) => Record<string, unknown> | Promise<Record<string, unknown>>;
3348
+ };
3304
3349
  }
3305
3350
 
3306
3351
  /**
@@ -4355,6 +4400,7 @@ export declare class LuaWebhook {
4355
4400
  private readonly querySchema?;
4356
4401
  private readonly headerSchema?;
4357
4402
  private readonly bodySchema?;
4403
+ private readonly secret?;
4358
4404
  private readonly executeFunction;
4359
4405
  /**
4360
4406
  * Creates a new LuaWebhook instance.
@@ -4368,6 +4414,11 @@ export declare class LuaWebhook {
4368
4414
  * @param config.execute - Function that processes the webhook request
4369
4415
  */
4370
4416
  constructor(config: LuaWebhookConfig);
4417
+ /**
4418
+ * Gets the webhook's signing key, if one is configured.
4419
+ * Never print this — it is the shared secret callers sign with.
4420
+ */
4421
+ getSecret(): string | undefined;
4371
4422
  /**
4372
4423
  * Gets the webhook name.
4373
4424
  */
@@ -4414,6 +4465,14 @@ export declare interface LuaWebhookConfig {
4414
4465
  headerSchema?: ZodType;
4415
4466
  /** Optional Zod schema for body validation */
4416
4467
  bodySchema?: ZodType;
4468
+ /**
4469
+ * Optional HMAC-SHA256 signing key. When set, Lua rejects any call to this
4470
+ * webhook that does not carry `x-lua-signature: sha256=<hex digest of the
4471
+ * raw request body>`. Must be a literal or a `const` resolvable at compile
4472
+ * time — the compiler cannot read a runtime expression. Rotate by changing
4473
+ * it and re-deploying.
4474
+ */
4475
+ secret?: string;
4417
4476
  /** Function that executes the webhook logic */
4418
4477
  execute: (event: LuaWebhookEvent) => Promise<any>;
4419
4478
  }
@@ -4577,15 +4636,14 @@ declare interface OrderAPI {
4577
4636
  }
4578
4637
 
4579
4638
  declare class OrderApi extends HttpClient implements OrderAPI {
4580
- private apiKey;
4581
4639
  private agentId;
4582
4640
  /**
4583
4641
  * Creates an instance of OrderApi
4584
4642
  * @param baseUrl - The base URL for the API
4585
- * @param apiKey - The API key for authentication
4643
+ * @param credential - The API key for authentication
4586
4644
  * @param agentId - The unique identifier of the agent
4587
4645
  */
4588
- constructor(baseUrl: string, apiKey: string, agentId: string);
4646
+ constructor(baseUrl: string, credential: RequestCredentialInput, agentId: string);
4589
4647
  /**
4590
4648
  * Creates a new order from a basket
4591
4649
  * @param orderData - The order creation request data containing basketId and additional order information
@@ -5405,6 +5463,22 @@ declare const REASONING_EFFORT_VALUES: readonly ["off", "minimal", "low", "mediu
5405
5463
 
5406
5464
  declare type ReasoningEffort = (typeof REASONING_EFFORT_VALUES)[number];
5407
5465
 
5466
+ declare interface RequestCredential {
5467
+ readonly descriptor: RequestCredentialDescriptor;
5468
+ bearer(): Promise<string>;
5469
+ }
5470
+
5471
+ declare type RequestCredentialDescriptor = {
5472
+ kind: 'api-key';
5473
+ source: 'environment' | 'stored';
5474
+ } | {
5475
+ kind: 'first-party-session';
5476
+ source: 'stored';
5477
+ uid: string;
5478
+ };
5479
+
5480
+ declare type RequestCredentialInput = string | RequestCredential;
5481
+
5408
5482
  /**
5409
5483
  * Additive field on primitive publish responses. When the agent is under
5410
5484
  * versioning the server performs a scoped promote and returns the newly