@lunnoa/client 1.4.0 → 1.5.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 +11 -3
- package/dist/cli.js +199 -18
- package/dist/index.cjs +33 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1322 -1059
- package/dist/index.d.ts +1322 -1059
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +52 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +697 -608
- package/dist/react.d.ts +697 -608
- package/dist/react.js +52 -1
- package/dist/react.js.map +1 -1
- package/package.json +2 -6
- package/skills/lunnoa-client/SKILL.md +18 -6
- package/skills/lunnoa-solution-design/SKILL.md +20 -4
package/README.md
CHANGED
|
@@ -21,6 +21,14 @@ npm install @lunnoa/client
|
|
|
21
21
|
|
|
22
22
|
**Requirements:** Node.js ≥ 20 (or any runtime with `fetch` and web streams).
|
|
23
23
|
|
|
24
|
+
### Start a new app
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx @lunnoa/client init my-app --url https://lunnoa.your-company.example
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Scaffolds the [lunnoa-starter](https://github.com/lunnoa-automate/lunnoa-starter) Next.js template (thin, Docker-deployable, both auth patterns behind `LUNNOA_AUTH_MODE`) and writes `.env`, prompting for an API key when run interactively. `--template <owner/repo[#ref]|./local-folder>` overrides the source. Then `npm install` and open the folder in Claude Code / Cursor / Codex.
|
|
31
|
+
|
|
24
32
|
## Quickstart
|
|
25
33
|
|
|
26
34
|
```typescript
|
|
@@ -98,12 +106,12 @@ const { user, status, login, logout } = useLunnoaAuth();
|
|
|
98
106
|
const lunnoa = useLunnoaClient();
|
|
99
107
|
const { progress, status: progressStatus } = useExecutionProgress(executionId);
|
|
100
108
|
const { waiting, pendingInput, submitInput } = useNeedsInput(progress);
|
|
101
|
-
const { messages, send, stop, taskId } = useAgentChat(agentId);
|
|
109
|
+
const { messages, send, stop, taskId } = useAgentChat(agentId);
|
|
102
110
|
const { items, decide } = useApprovalsInbox({ pollIntervalMs: 15_000 });
|
|
103
111
|
const { data, page, setPage } = useEntityList({ objectTypeSlug: 'invoice' });
|
|
104
112
|
```
|
|
105
113
|
|
|
106
|
-
|
|
114
|
+
Peer: `react` ≥ 18 (required for `/react`). `@ai-sdk/react` (behind `useAgentChat`) ships as a dependency. Core `@lunnoa/client` stays headless.
|
|
107
115
|
|
|
108
116
|
## Resources
|
|
109
117
|
|
|
@@ -303,7 +311,7 @@ npx @lunnoa/client projects list --json
|
|
|
303
311
|
npx @lunnoa/client features --json
|
|
304
312
|
```
|
|
305
313
|
|
|
306
|
-
`tools list` is compact (`appId`, `actionId`, name, flags). `tools get` prints `inputConfig` and a `defineAction({ id, appId, input })` sketch. Auth flags and `LUNNOA_URL` / `LUNNOA_API_KEY` / `lunnoa.config` work the same as deploy.
|
|
314
|
+
`tools list` is compact (`appId`, `actionId`, name, flags). `tools get` prints `inputConfig` and a `defineAction({ id, appId, input })` sketch. Auth flags and `LUNNOA_URL` / `LUNNOA_API_KEY` / `lunnoa.config` work the same as deploy. The CLI also reads `./.env` (real environment variables win).
|
|
307
315
|
|
|
308
316
|
## Regenerating the API types
|
|
309
317
|
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
5
|
-
import { resolve as
|
|
4
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
5
|
+
import { resolve as resolve4 } from "path";
|
|
6
6
|
|
|
7
7
|
// src/core/auth.ts
|
|
8
8
|
var API_KEY_PREFIX = "lna_";
|
|
@@ -1083,6 +1083,35 @@ var EntityTypesResource = class {
|
|
|
1083
1083
|
}
|
|
1084
1084
|
};
|
|
1085
1085
|
|
|
1086
|
+
// src/resources/tables.ts
|
|
1087
|
+
var TablesResource = class {
|
|
1088
|
+
constructor(http) {
|
|
1089
|
+
this.http = http;
|
|
1090
|
+
}
|
|
1091
|
+
http;
|
|
1092
|
+
/** Lists tables in the API key's workspace (without columns and rows). */
|
|
1093
|
+
list(options = {}) {
|
|
1094
|
+
return this.http.get("/api/tables", {
|
|
1095
|
+
query: { projectId: options.projectId }
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
/** Returns a single table by ID, including columns and rows. */
|
|
1099
|
+
get(id) {
|
|
1100
|
+
return this.http.get(`/api/tables/${id}`);
|
|
1101
|
+
}
|
|
1102
|
+
/** Returns a single table by its workspace slug, including columns and rows. */
|
|
1103
|
+
getBySlug(slug) {
|
|
1104
|
+
return this.http.get(`/api/tables/slug/${slug}`);
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Creates or updates a table by workspace slug. Omitted columns or rows
|
|
1108
|
+
* keep their current value. Marks `managedByCode` by default.
|
|
1109
|
+
*/
|
|
1110
|
+
upsertBySlug(input) {
|
|
1111
|
+
return this.http.post("/api/tables/upsert", { body: input });
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1086
1115
|
// src/resources/approvals.ts
|
|
1087
1116
|
var ApprovalsResource = class {
|
|
1088
1117
|
constructor(http) {
|
|
@@ -1422,7 +1451,7 @@ function computeDurationMs(start, end) {
|
|
|
1422
1451
|
return b - a;
|
|
1423
1452
|
}
|
|
1424
1453
|
function defaultSleep(ms) {
|
|
1425
|
-
return new Promise((
|
|
1454
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
1426
1455
|
}
|
|
1427
1456
|
|
|
1428
1457
|
// src/resources/knowledge.ts
|
|
@@ -2067,6 +2096,8 @@ var LunnoaClient = class {
|
|
|
2067
2096
|
approvals;
|
|
2068
2097
|
entities;
|
|
2069
2098
|
entityTypes;
|
|
2099
|
+
/** Small reference / lookup tables (rows stored inline; use entities for transactional data). */
|
|
2100
|
+
tables;
|
|
2070
2101
|
knowledge;
|
|
2071
2102
|
queues;
|
|
2072
2103
|
queueItems;
|
|
@@ -2090,6 +2121,7 @@ var LunnoaClient = class {
|
|
|
2090
2121
|
this.workflows = new WorkflowsResource(this.http, this.executions);
|
|
2091
2122
|
this.entities = new EntitiesResource(this.http);
|
|
2092
2123
|
this.entityTypes = new EntityTypesResource(this.http);
|
|
2124
|
+
this.tables = new TablesResource(this.http);
|
|
2093
2125
|
this.knowledge = new KnowledgeResource(this.http);
|
|
2094
2126
|
this.queues = new QueuesResource(this.http);
|
|
2095
2127
|
this.queueItems = new QueueItemsResource(this.http);
|
|
@@ -2106,6 +2138,7 @@ var GROUPS_WITH_SUBCOMMAND = /* @__PURE__ */ new Set([
|
|
|
2106
2138
|
"workflows",
|
|
2107
2139
|
"agents",
|
|
2108
2140
|
"entity-types",
|
|
2141
|
+
"tables",
|
|
2109
2142
|
"tools",
|
|
2110
2143
|
"apps",
|
|
2111
2144
|
"connections",
|
|
@@ -2118,7 +2151,8 @@ var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
|
2118
2151
|
"--access-token",
|
|
2119
2152
|
"--project-id",
|
|
2120
2153
|
"--out",
|
|
2121
|
-
"--app"
|
|
2154
|
+
"--app",
|
|
2155
|
+
"--template"
|
|
2122
2156
|
]);
|
|
2123
2157
|
function requireFlagValue(flag, value) {
|
|
2124
2158
|
if (!value || value.startsWith("--")) {
|
|
@@ -2181,6 +2215,9 @@ function parseArgs(argv) {
|
|
|
2181
2215
|
case "--app":
|
|
2182
2216
|
args.app = value;
|
|
2183
2217
|
break;
|
|
2218
|
+
case "--template":
|
|
2219
|
+
args.template = value;
|
|
2220
|
+
break;
|
|
2184
2221
|
default:
|
|
2185
2222
|
break;
|
|
2186
2223
|
}
|
|
@@ -2196,6 +2233,7 @@ function parseArgs(argv) {
|
|
|
2196
2233
|
return args;
|
|
2197
2234
|
}
|
|
2198
2235
|
var USAGE = `Usage:
|
|
2236
|
+
npx @lunnoa/client init <dir> [--url <url>] [--api-key <lna_key>] [--template <owner/repo|path>]
|
|
2199
2237
|
npx @lunnoa/client codegen --url <url> --api-key <lna_key> [--out <dir>]
|
|
2200
2238
|
|
|
2201
2239
|
Discover (do not invent catalogue action ids):
|
|
@@ -2209,6 +2247,8 @@ var USAGE = `Usage:
|
|
|
2209
2247
|
npx @lunnoa/client agents list [--json]
|
|
2210
2248
|
npx @lunnoa/client workflows list [--json]
|
|
2211
2249
|
npx @lunnoa/client entity-types list [--json]
|
|
2250
|
+
npx @lunnoa/client tables list [--json]
|
|
2251
|
+
npx @lunnoa/client tables get <slugOrId> [--json]
|
|
2212
2252
|
npx @lunnoa/client projects list [--json]
|
|
2213
2253
|
npx @lunnoa/client features [--json]
|
|
2214
2254
|
|
|
@@ -2228,10 +2268,11 @@ Options:
|
|
|
2228
2268
|
--out Output directory for lunnoa.generated.ts (codegen; default: ./src/lunnoa)
|
|
2229
2269
|
--app Restrict tools/connections to one workflow app id
|
|
2230
2270
|
--for-agent Only catalogue entries with availableForAgent
|
|
2271
|
+
--template init starter: GitHub owner/repo[#ref] or local folder (default: lunnoa-automate/lunnoa-starter)
|
|
2231
2272
|
--json Machine-readable JSON (preferred for coding agents)
|
|
2232
2273
|
--help Show this help
|
|
2233
2274
|
|
|
2234
|
-
Environment: LUNNOA_URL, LUNNOA_API_KEY, LUNNOA_PROJECT_ID
|
|
2275
|
+
Environment: LUNNOA_URL, LUNNOA_API_KEY, LUNNOA_PROJECT_ID (also read from ./.env)
|
|
2235
2276
|
Optional config file: lunnoa.config.ts | .mjs | .js | .json
|
|
2236
2277
|
|
|
2237
2278
|
tools get prints inputConfig and a defineAction() sketch. tools list is compact;
|
|
@@ -2708,6 +2749,39 @@ async function runEntityTypesList(client, args) {
|
|
|
2708
2749
|
{ key: "managedByCode", header: "CODE" }
|
|
2709
2750
|
]);
|
|
2710
2751
|
}
|
|
2752
|
+
async function runTablesList(client, args) {
|
|
2753
|
+
const tables = await client.tables.list({ projectId: args.projectId });
|
|
2754
|
+
const rows = tables.map((table) => ({
|
|
2755
|
+
id: table.id,
|
|
2756
|
+
slug: table.slug,
|
|
2757
|
+
name: table.name,
|
|
2758
|
+
description: table.description ?? "",
|
|
2759
|
+
managedByCode: Boolean(table.managedByCode)
|
|
2760
|
+
}));
|
|
2761
|
+
if (args.json) {
|
|
2762
|
+
printJson(rows);
|
|
2763
|
+
return;
|
|
2764
|
+
}
|
|
2765
|
+
printTable(rows, [
|
|
2766
|
+
{ key: "id", header: "ID" },
|
|
2767
|
+
{ key: "slug", header: "SLUG" },
|
|
2768
|
+
{ key: "name", header: "NAME" },
|
|
2769
|
+
{ key: "managedByCode", header: "CODE" }
|
|
2770
|
+
]);
|
|
2771
|
+
}
|
|
2772
|
+
async function runTablesGet(client, args) {
|
|
2773
|
+
const ref = requireTarget(args, "table slug or id (example: tables get cost_centres)");
|
|
2774
|
+
const table = /^[0-9a-f]{8}-[0-9a-f]{4}-/i.test(ref) ? await client.tables.get(ref) : await client.tables.getBySlug(ref);
|
|
2775
|
+
if (args.json) {
|
|
2776
|
+
printJson(table);
|
|
2777
|
+
return;
|
|
2778
|
+
}
|
|
2779
|
+
console.log(`id: ${table.id}`);
|
|
2780
|
+
console.log(`slug: ${table.slug}`);
|
|
2781
|
+
console.log(`name: ${table.name}`);
|
|
2782
|
+
console.log(`columns: ${(table.columns ?? []).map((c) => c.key).join(", ")}`);
|
|
2783
|
+
console.log(`rows: ${table.rows?.length ?? 0}`);
|
|
2784
|
+
}
|
|
2711
2785
|
async function runProjectsList(client, args) {
|
|
2712
2786
|
const projects = await client.projects.list({
|
|
2713
2787
|
expansion: ["description", "countAgents", "countWorkflows"]
|
|
@@ -3222,8 +3296,8 @@ async function loadOptionalConfig() {
|
|
|
3222
3296
|
continue;
|
|
3223
3297
|
}
|
|
3224
3298
|
if (name.endsWith(".json")) {
|
|
3225
|
-
const { readFile } = await import("fs/promises");
|
|
3226
|
-
const raw = await
|
|
3299
|
+
const { readFile: readFile2 } = await import("fs/promises");
|
|
3300
|
+
const raw = await readFile2(absolute, "utf8");
|
|
3227
3301
|
return JSON.parse(raw);
|
|
3228
3302
|
}
|
|
3229
3303
|
const mod = await import(pathToFileURL(absolute).href);
|
|
@@ -3237,12 +3311,102 @@ async function loadOptionalConfig() {
|
|
|
3237
3311
|
return {};
|
|
3238
3312
|
}
|
|
3239
3313
|
|
|
3314
|
+
// src/cli/init.ts
|
|
3315
|
+
import { spawn } from "child_process";
|
|
3316
|
+
import { cp, mkdir, readdir, readFile, stat, writeFile } from "fs/promises";
|
|
3317
|
+
import { basename, join, resolve as resolve2 } from "path";
|
|
3318
|
+
import { createInterface } from "readline/promises";
|
|
3319
|
+
var DEFAULT_TEMPLATE = "lunnoa-automate/lunnoa-starter";
|
|
3320
|
+
var SKIP_LOCAL = /* @__PURE__ */ new Set(["node_modules", ".next", ".git", ".env", ".claude", ".cursor"]);
|
|
3321
|
+
function setEnvValues(source, values) {
|
|
3322
|
+
let out = source;
|
|
3323
|
+
for (const [key, value] of Object.entries(values)) {
|
|
3324
|
+
if (!value) continue;
|
|
3325
|
+
const line = `${key}=${value}`;
|
|
3326
|
+
const existing = new RegExp(`^${key}=.*$`, "m");
|
|
3327
|
+
out = existing.test(out) ? out.replace(existing, () => line) : `${out}${out === "" || out.endsWith("\n") ? "" : "\n"}${line}
|
|
3328
|
+
`;
|
|
3329
|
+
}
|
|
3330
|
+
return out;
|
|
3331
|
+
}
|
|
3332
|
+
async function isDirectory(path) {
|
|
3333
|
+
return (await stat(path).catch(() => void 0))?.isDirectory() ?? false;
|
|
3334
|
+
}
|
|
3335
|
+
async function downloadGithubTemplate(template, dest) {
|
|
3336
|
+
const [repo, ref = "HEAD"] = template.split("#");
|
|
3337
|
+
const url = `https://codeload.github.com/${repo}/tar.gz/${ref}`;
|
|
3338
|
+
const response = await fetch(url);
|
|
3339
|
+
if (!response.ok) {
|
|
3340
|
+
throw new Error(`Could not download template ${template} (${response.status} from ${url}).`);
|
|
3341
|
+
}
|
|
3342
|
+
const tarball = Buffer.from(await response.arrayBuffer());
|
|
3343
|
+
await new Promise((done, fail) => {
|
|
3344
|
+
const child = spawn("tar", ["-xzf", "-", "--strip-components=1"], {
|
|
3345
|
+
cwd: dest,
|
|
3346
|
+
stdio: ["pipe", "ignore", "inherit"]
|
|
3347
|
+
});
|
|
3348
|
+
child.on(
|
|
3349
|
+
"error",
|
|
3350
|
+
(error) => fail(new Error(`Could not run tar (${error.message}). Download ${url} manually.`))
|
|
3351
|
+
);
|
|
3352
|
+
child.on(
|
|
3353
|
+
"close",
|
|
3354
|
+
(code) => code === 0 ? done() : fail(new Error(`tar exited with code ${code}`))
|
|
3355
|
+
);
|
|
3356
|
+
child.stdin.end(tarball);
|
|
3357
|
+
});
|
|
3358
|
+
}
|
|
3359
|
+
async function runInit(args) {
|
|
3360
|
+
if (!args.path) {
|
|
3361
|
+
throw new Error("Missing project directory. Example: init my-app --url https://lunnoa.example");
|
|
3362
|
+
}
|
|
3363
|
+
const dest = resolve2(process.cwd(), args.path);
|
|
3364
|
+
if ((await readdir(dest).catch(() => [])).length > 0) {
|
|
3365
|
+
throw new Error(`${dest} already exists and is not empty.`);
|
|
3366
|
+
}
|
|
3367
|
+
await mkdir(dest, { recursive: true });
|
|
3368
|
+
const template = args.template ?? DEFAULT_TEMPLATE;
|
|
3369
|
+
if (await isDirectory(resolve2(template))) {
|
|
3370
|
+
await cp(resolve2(template), dest, {
|
|
3371
|
+
recursive: true,
|
|
3372
|
+
filter: (src) => !SKIP_LOCAL.has(basename(src))
|
|
3373
|
+
});
|
|
3374
|
+
} else {
|
|
3375
|
+
console.log(`Downloading ${template} ...`);
|
|
3376
|
+
await downloadGithubTemplate(template, dest);
|
|
3377
|
+
}
|
|
3378
|
+
let { url, apiKey } = args;
|
|
3379
|
+
if (process.stdin.isTTY && (!url || !apiKey)) {
|
|
3380
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
3381
|
+
url ||= (await rl.question("Lunnoa URL (e.g. https://lunnoa.your-company.example): ")).trim();
|
|
3382
|
+
apiKey ||= (await rl.question("API key lna_... (server-side only; Enter to skip and sign in as a user instead): ")).trim();
|
|
3383
|
+
rl.close();
|
|
3384
|
+
}
|
|
3385
|
+
const example = await readFile(join(dest, ".env.example"), "utf8").catch(() => "");
|
|
3386
|
+
await writeFile(
|
|
3387
|
+
join(dest, ".env"),
|
|
3388
|
+
setEnvValues(example, { LUNNOA_URL: url, LUNNOA_API_KEY: apiKey }),
|
|
3389
|
+
"utf8"
|
|
3390
|
+
);
|
|
3391
|
+
console.log(`
|
|
3392
|
+
Created ${dest}
|
|
3393
|
+
|
|
3394
|
+
Next steps:`);
|
|
3395
|
+
console.log(` cd ${args.path}`);
|
|
3396
|
+
console.log(" npm install");
|
|
3397
|
+
if (!apiKey) {
|
|
3398
|
+
console.log(" Add LUNNOA_API_KEY to .env, or set LUNNOA_AUTH_MODE=user to sign in with your Lunnoa account");
|
|
3399
|
+
}
|
|
3400
|
+
console.log(" npm run dev");
|
|
3401
|
+
console.log(" Open the folder in Claude Code / Cursor / Codex and describe your idea.");
|
|
3402
|
+
}
|
|
3403
|
+
|
|
3240
3404
|
// src/cli/skills.ts
|
|
3241
|
-
import { cp } from "fs/promises";
|
|
3242
|
-
import { dirname, resolve as
|
|
3405
|
+
import { cp as cp2 } from "fs/promises";
|
|
3406
|
+
import { dirname, resolve as resolve3 } from "path";
|
|
3243
3407
|
import { fileURLToPath } from "url";
|
|
3244
3408
|
var SKILL_TARGETS = [".claude/skills", ".cursor/skills"];
|
|
3245
|
-
var BUNDLED_SKILLS_DIR =
|
|
3409
|
+
var BUNDLED_SKILLS_DIR = resolve3(
|
|
3246
3410
|
dirname(fileURLToPath(import.meta.url)),
|
|
3247
3411
|
"..",
|
|
3248
3412
|
"skills"
|
|
@@ -3250,8 +3414,8 @@ var BUNDLED_SKILLS_DIR = resolve2(
|
|
|
3250
3414
|
async function installSkills(projectDir, sourceDir = BUNDLED_SKILLS_DIR) {
|
|
3251
3415
|
const written = [];
|
|
3252
3416
|
for (const target of SKILL_TARGETS) {
|
|
3253
|
-
const dest =
|
|
3254
|
-
await
|
|
3417
|
+
const dest = resolve3(projectDir, target);
|
|
3418
|
+
await cp2(sourceDir, dest, { recursive: true, force: true });
|
|
3255
3419
|
written.push(dest);
|
|
3256
3420
|
}
|
|
3257
3421
|
return written;
|
|
@@ -3312,10 +3476,10 @@ async function runCodegen(args) {
|
|
|
3312
3476
|
`Found ${definitions.entityTypes.length} entity type(s), ${definitions.workflows.length} workflow(s), ${definitions.agents.length} agent(s).`
|
|
3313
3477
|
);
|
|
3314
3478
|
const moduleSource = generateDeploymentModule(definitions);
|
|
3315
|
-
const outDir =
|
|
3316
|
-
await
|
|
3317
|
-
const outFile =
|
|
3318
|
-
await
|
|
3479
|
+
const outDir = resolve4(process.cwd(), args.out);
|
|
3480
|
+
await mkdir2(outDir, { recursive: true });
|
|
3481
|
+
const outFile = resolve4(outDir, "lunnoa.generated.ts");
|
|
3482
|
+
await writeFile2(outFile, moduleSource, "utf8");
|
|
3319
3483
|
console.log(`Wrote ${outFile}`);
|
|
3320
3484
|
}
|
|
3321
3485
|
async function deployWorkflow(args) {
|
|
@@ -3387,6 +3551,7 @@ var DISCOVERY_SUBCOMMANDS = {
|
|
|
3387
3551
|
tools: ["list", "get", "search"],
|
|
3388
3552
|
apps: ["list", "get"],
|
|
3389
3553
|
connections: ["list", "get"],
|
|
3554
|
+
tables: ["list", "get"],
|
|
3390
3555
|
features: void 0,
|
|
3391
3556
|
projects: ["list"]
|
|
3392
3557
|
};
|
|
@@ -3423,7 +3588,7 @@ ${USAGE}`
|
|
|
3423
3588
|
}
|
|
3424
3589
|
async function runDiscovery(args) {
|
|
3425
3590
|
const { command, subcommand } = args;
|
|
3426
|
-
if (command === "tools" || command === "apps" || command === "connections") {
|
|
3591
|
+
if (command === "tools" || command === "apps" || command === "connections" || command === "tables") {
|
|
3427
3592
|
assertKnownDiscoveryShape(args);
|
|
3428
3593
|
}
|
|
3429
3594
|
if (!isDiscoveryCommand(args)) {
|
|
@@ -3470,6 +3635,14 @@ async function runDiscovery(args) {
|
|
|
3470
3635
|
await runEntityTypesList(client, args);
|
|
3471
3636
|
return true;
|
|
3472
3637
|
}
|
|
3638
|
+
if (command === "tables" && subcommand === "list") {
|
|
3639
|
+
await runTablesList(client, args);
|
|
3640
|
+
return true;
|
|
3641
|
+
}
|
|
3642
|
+
if (command === "tables" && subcommand === "get") {
|
|
3643
|
+
await runTablesGet(client, args);
|
|
3644
|
+
return true;
|
|
3645
|
+
}
|
|
3473
3646
|
if (command === "projects" && (subcommand === "list" || !subcommand)) {
|
|
3474
3647
|
await runProjectsList(client, args);
|
|
3475
3648
|
return true;
|
|
@@ -3482,12 +3655,20 @@ async function runDiscovery(args) {
|
|
|
3482
3655
|
}
|
|
3483
3656
|
async function main() {
|
|
3484
3657
|
const args = parseArgs(process.argv.slice(2));
|
|
3658
|
+
try {
|
|
3659
|
+
process.loadEnvFile();
|
|
3660
|
+
} catch {
|
|
3661
|
+
}
|
|
3485
3662
|
if (!args.command || args.command === "--help" || args.command === "help" || args.help) {
|
|
3486
3663
|
console.log(USAGE);
|
|
3487
3664
|
return;
|
|
3488
3665
|
}
|
|
3666
|
+
if (args.command === "init") {
|
|
3667
|
+
await runInit(args);
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3489
3670
|
if (args.command === "skills" && args.subcommand === "install") {
|
|
3490
|
-
const written = await installSkills(
|
|
3671
|
+
const written = await installSkills(resolve4(process.cwd(), args.path ?? "."));
|
|
3491
3672
|
for (const dest of written) {
|
|
3492
3673
|
console.log(`Installed Lunnoa skills into ${dest}`);
|
|
3493
3674
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1125,6 +1125,35 @@ var EntityTypesResource = class {
|
|
|
1125
1125
|
}
|
|
1126
1126
|
};
|
|
1127
1127
|
|
|
1128
|
+
// src/resources/tables.ts
|
|
1129
|
+
var TablesResource = class {
|
|
1130
|
+
constructor(http) {
|
|
1131
|
+
this.http = http;
|
|
1132
|
+
}
|
|
1133
|
+
http;
|
|
1134
|
+
/** Lists tables in the API key's workspace (without columns and rows). */
|
|
1135
|
+
list(options = {}) {
|
|
1136
|
+
return this.http.get("/api/tables", {
|
|
1137
|
+
query: { projectId: options.projectId }
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
/** Returns a single table by ID, including columns and rows. */
|
|
1141
|
+
get(id) {
|
|
1142
|
+
return this.http.get(`/api/tables/${id}`);
|
|
1143
|
+
}
|
|
1144
|
+
/** Returns a single table by its workspace slug, including columns and rows. */
|
|
1145
|
+
getBySlug(slug) {
|
|
1146
|
+
return this.http.get(`/api/tables/slug/${slug}`);
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Creates or updates a table by workspace slug. Omitted columns or rows
|
|
1150
|
+
* keep their current value. Marks `managedByCode` by default.
|
|
1151
|
+
*/
|
|
1152
|
+
upsertBySlug(input) {
|
|
1153
|
+
return this.http.post("/api/tables/upsert", { body: input });
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1128
1157
|
// src/resources/approvals.ts
|
|
1129
1158
|
var ApprovalsResource = class {
|
|
1130
1159
|
constructor(http) {
|
|
@@ -2109,6 +2138,8 @@ var LunnoaClient = class {
|
|
|
2109
2138
|
approvals;
|
|
2110
2139
|
entities;
|
|
2111
2140
|
entityTypes;
|
|
2141
|
+
/** Small reference / lookup tables (rows stored inline; use entities for transactional data). */
|
|
2142
|
+
tables;
|
|
2112
2143
|
knowledge;
|
|
2113
2144
|
queues;
|
|
2114
2145
|
queueItems;
|
|
@@ -2132,6 +2163,7 @@ var LunnoaClient = class {
|
|
|
2132
2163
|
this.workflows = new WorkflowsResource(this.http, this.executions);
|
|
2133
2164
|
this.entities = new EntitiesResource(this.http);
|
|
2134
2165
|
this.entityTypes = new EntityTypesResource(this.http);
|
|
2166
|
+
this.tables = new TablesResource(this.http);
|
|
2135
2167
|
this.knowledge = new KnowledgeResource(this.http);
|
|
2136
2168
|
this.queues = new QueuesResource(this.http);
|
|
2137
2169
|
this.queueItems = new QueueItemsResource(this.http);
|
|
@@ -2240,6 +2272,7 @@ exports.QueuesResource = QueuesResource;
|
|
|
2240
2272
|
exports.RunsResource = RunsResource;
|
|
2241
2273
|
exports.ScorecardsResource = ScorecardsResource;
|
|
2242
2274
|
exports.SsoAuthResource = SsoAuthResource;
|
|
2275
|
+
exports.TablesResource = TablesResource;
|
|
2243
2276
|
exports.TasksResource = TasksResource;
|
|
2244
2277
|
exports.VariablesResource = VariablesResource;
|
|
2245
2278
|
exports.WorkflowAppsResource = WorkflowAppsResource;
|