kenobi-pages 0.1.5 → 0.1.6
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/bin/cli.mjs +37 -20
- package/dist/client.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/types.d.ts +0 -93
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -1,36 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`)},"writeGlobalConfig"),
|
|
2
|
+
var R=Object.defineProperty;var r=(e,o)=>R(e,"name",{value:o,configurable:!0});import{existsSync as I,mkdirSync as T,readFileSync as $,writeFileSync as A,appendFileSync as K}from"node:fs";import{readFile as F}from"node:fs/promises";import{homedir as G}from"node:os";import{join as N,resolve as P}from"node:path";import{createInterface as B}from"node:readline";var D="https://kenobi.ai",v=N(G(),".kenobi"),S=N(v,"config.json"),m="KENOBI_PAGES_KEY",E=r(()=>{try{return JSON.parse($(S,"utf-8"))}catch{return{}}},"readGlobalConfig"),W=r(e=>{T(v,{recursive:!0}),A(S,JSON.stringify(e,null,2)+`
|
|
3
|
+
`)},"writeGlobalConfig"),Y=r(()=>{let e=process.env[m]||E().apiKey;return e||(console.error("Error: No API key found."),console.error(""),console.error("Run 'npx kenobi-pages init' to set up your API key."),console.error(""),console.error("Or set the KENOBI_PAGES_KEY environment variable directly."),process.exit(1)),e},"getApiKey"),M=r(()=>(process.env.KENOBI_BASE_URL??E().baseUrl??D).replace(/\/+$/,""),"getBaseUrl"),f=r(async(e,o={})=>{let n=`${M()}${e}`,s=await fetch(n,{method:o.method??"GET",headers:{"x-kenobi-key":Y(),"Content-Type":"application/json"},body:o.body?JSON.stringify(o.body):void 0});if(!s.ok){let t=await s.text().catch(()=>"Unknown error"),i=s.status===401||s.status===403?4:s.status===404?3:1;console.error(`Error ${s.status}: ${t}`),process.exit(i)}return s.json()},"fetchKenobi"),x=r(e=>new Promise(o=>{let n=B({input:process.stdin,output:process.stderr});n.question(e,s=>{n.close(),o(s.trim())})}),"prompt"),_=r(()=>new Promise((e,o)=>{let n="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",s=>{n+=s}),process.stdin.on("end",()=>e(n)),process.stdin.on("error",o),process.stdin.isTTY&&e("")}),"readStdin"),C=r(async e=>{let o=e.indexOf("--file");return o!==-1&&e[o+1]?F(e[o+1],"utf-8"):null},"parseFileArg"),H=r(async()=>{console.error("Kenobi Pages \u2014 Setup"),console.error(""),console.error("Find your Pages API key in the workflow builder:"),console.error(" https://kenobi.ai/testing/cortex"),console.error("");let e=await x("Paste your API key (pk_live_... or pk_test_...): ");e||(console.error("No key provided. Aborting."),process.exit(1)),!e.startsWith("pk_live_")&&!e.startsWith("pk_test_")&&(console.error(`Warning: "${e}" doesn't look like a Kenobi public key (expected pk_live_... or pk_test_...).`),(await x("Continue anyway? (y/N): ")).toLowerCase()!=="y"&&(console.error("Aborting."),process.exit(1)));let o=E();o.apiKey=e,W(o),console.error(`\u2713 Saved to ${S}`);let n=P(process.cwd(),".env.local"),s=P(process.cwd(),".env"),t=I(n)?n:I(s)?s:null;if(t){let i=$(t,"utf-8");if(i.includes(m))console.error(`\u2713 ${m} already present in ${t.split("/").pop()}`);else{let l=i.endsWith(`
|
|
4
4
|
`)?"":`
|
|
5
|
-
`;
|
|
6
|
-
`),console.error(`\u2713 Added ${
|
|
7
|
-
`),console.error(`\u2713 Created .env.local with ${
|
|
8
|
-
${
|
|
5
|
+
`;K(t,`${l}${m}="${e}"
|
|
6
|
+
`),console.error(`\u2713 Added ${m} to ${t.split("/").pop()}`)}}else(await x("No .env.local found. Create one with your API key? (Y/n): ")).toLowerCase()!=="n"&&(A(n,`${m}="${e}"
|
|
7
|
+
`),console.error(`\u2713 Created .env.local with ${m}`));console.error(""),console.error("Done! You can now use kenobi-pages commands."),console.error(` npx kenobi-pages schema push "My Page" '{"fields":{...}}'`),console.error(" npx kenobi-pages types <workflowId>")},"initCommand"),q=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages schema get <workflowId>"),process.exit(2));let n=await f(`/api/v1/pages/${o}/schema`);console.log(JSON.stringify(n,null,2))},"schemaGet"),z=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages schema push <name> '<json>'"),console.error(" kenobi-pages schema push <name> --file schema.json"),console.error(" echo '<json>' | kenobi-pages schema push <name>"),process.exit(2));let n=e.slice(1),s=await C(n),t=s?null:n.find(k=>k.startsWith("{")),i=!s&&!t?await _():null,l=s??t??i;(!l||l.trim().length===0)&&(console.error("Error: No schema provided."),console.error("Pass inline JSON, --file <path>, or pipe to stdin."),process.exit(2));let a;try{a=JSON.parse(l)}catch{console.error("Error: Invalid JSON."),process.exit(2)}let g=await f("/api/v1/pages/schema",{method:"POST",body:{name:o,schema:a}});console.log(JSON.stringify(g,null,2)),console.error(`Schema "${g.name}" pushed successfully.`),console.error(`Source key: ${g.sourceKey}`),console.error("You can now select this schema as an output target in the Kenobi workflow builder.")},"schemaPush"),V=r(async e=>{let[o,n]=e;(!o||!n)&&(console.error("Usage: kenobi-pages page get <workflowId> <slug>"),process.exit(2));let s=await f(`/api/v1/pages/${o}/${n}`);console.log(JSON.stringify(s,null,2))},"pageGet"),X=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages types <workflowId>"),process.exit(2));let n=await f(`/api/v1/pages/${o}/schema`),s=n.schema;s?.fields||(console.error("Error: Workflow has no output schema with fields."),process.exit(1));let t=r(c=>" ".repeat(c),"indent"),i=r((c,d=1)=>{switch(c.type){case"string":case"url":return"string";case"number":return"number";case"boolean":return"boolean";case"enum":return c.values?.length?c.values.map(y=>`"${y}"`).join(" | "):"string";case"object":{let y=Object.entries(c.fields??{});return y.length===0?"Record<string, unknown>":`{
|
|
8
|
+
${y.map(([U,O])=>{let J=O.optional?"?":"";return`${t(d)}${U}${J}: ${i(O,d+1)}`}).join(`
|
|
9
9
|
`)}
|
|
10
|
-
${
|
|
11
|
-
`:""} ${
|
|
12
|
-
${
|
|
10
|
+
${t(d-1)}}`}case"array":return`Array<${i(c.items,d)}>`;default:return"unknown"}},"fieldToTs"),a=Object.entries(s.fields).map(([c,d])=>{let y=d.optional?"?":"";return`${d.description?` /** ${d.description} */
|
|
11
|
+
`:""} ${c}${y}: ${i(d,2)}`}),k=`export interface ${n.title?n.title.replace(/[^a-zA-Z0-9]+/g,""):"PageContent"} {
|
|
12
|
+
${a.join(`
|
|
13
13
|
`)}
|
|
14
14
|
}
|
|
15
|
-
`;console.log(
|
|
15
|
+
`;console.log(k)},"typesGen"),Z=new Set(["COMPLETED","FAILED","CANCELED","SYSTEM_FAILURE","CRASHED"]),Q=r(e=>new Promise(o=>setTimeout(o,e)),"sleep"),h=r((e,o)=>{let n=e.indexOf(o);return n!==-1&&e[n+1]?e[n+1]:void 0},"parseFlag"),ee=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages run <workflowId> [--params '<json>'] [--context '<text>']"),process.exit(2));let n=e.slice(1),s={},t=h(n,"--params");if(t)try{s=JSON.parse(t)}catch{console.error("Error: Invalid JSON in --params"),process.exit(2)}let i=h(n,"--context"),l={params:s};i&&(l.context=i);let a=await f(`/api/v1/workflows/${o}/run`,{method:"POST",body:l});console.error(`Run triggered: ${a.runId}`),console.error("Polling for completion...");let g=2e3,k=15e3;for(;;){await Q(g);let c=await f(`/api/v1/workflows/${o}/runs/${a.runId}`);if(console.error(` Status: ${c.status}`),Z.has(c.status)){console.log(JSON.stringify(c,null,2)),c.status!=="COMPLETED"&&process.exit(1);return}g=Math.min(g*1.5,k)}},"runWorkflow"),oe=r(async()=>{let e=await f("/api/v1/workflows");console.log(JSON.stringify(e,null,2))},"listWorkflows"),ne=r(async()=>{let e=await f("/api/v1/sources");console.log(JSON.stringify(e,null,2))},"listSources"),L=r(async e=>{let o=await C(e),n=o?null:e.find(i=>i.startsWith("{")),s=!o&&!n?await _():null,t=o??n??s;(!t||t.trim().length===0)&&(console.error("Error: No JSON provided."),console.error("Pass inline JSON, --file <path>, or pipe to stdin."),process.exit(2));try{return JSON.parse(t)}catch{console.error("Error: Invalid JSON."),process.exit(2)}},"readJsonInput"),se=r(async e=>{let o=h(e,"--name"),n=h(e,"--slug");(!o||!n)&&(console.error("Usage: kenobi-pages workflow create --name '<name>' --slug '<slug>' --config '<json>'"),console.error(" kenobi-pages workflow create --name '<name>' --slug '<slug>' --file config.json"),process.exit(2));let s=h(e,"--description"),t=e.indexOf("--config"),i=t!==-1&&e[t+1]?[e[t+1]]:e,l=await L(i),a={name:o,slug:n,config:l};s&&(a.description=s);let g=await f("/api/v1/workflows",{method:"POST",body:a});console.log(JSON.stringify(g,null,2)),console.error(`Workflow "${o}" created.`)},"workflowCreate"),te=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages workflow get <workflowId>"),process.exit(2));let n=await f(`/api/v1/workflows/${o}?full=true`);console.log(JSON.stringify(n,null,2))},"workflowGet"),re=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages workflow update <workflowId> --config '<json>'"),console.error(" kenobi-pages workflow update <workflowId> --file config.json"),process.exit(2));let n=e.slice(1),s=h(n,"--name"),t=h(n,"--description"),i=n.indexOf("--config"),l=i!==-1&&n[i+1]?[n[i+1]]:n,a={};s&&(a.name=s),t!==void 0&&(a.description=t),(n.includes("--config")||n.includes("--file"))&&(a.config=await L(l)),Object.keys(a).length===0&&(console.error("Error: Nothing to update. Pass --name, --description, --config, or --file."),process.exit(2));let k=await f(`/api/v1/workflows/${o}`,{method:"PUT",body:a});console.log(JSON.stringify(k,null,2)),console.error("Workflow updated.")},"workflowUpdate"),ie=r(async e=>{let o=e[0];o||(console.error("Usage: kenobi-pages workflow delete <workflowId>"),process.exit(2)),await f(`/api/v1/workflows/${o}`,{method:"DELETE"}),console.error("Workflow deleted.")},"workflowDelete"),ae=`kenobi-pages \u2014 Kenobi Pages CLI
|
|
16
16
|
|
|
17
17
|
Commands:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
init Set up your API key (interactive)
|
|
19
|
+
|
|
20
|
+
schema get <workflowId> Fetch a workflow's output schema
|
|
21
|
+
schema push <name> '<json>' Push a schema to Kenobi (inline JSON)
|
|
22
|
+
schema push <name> --file f Push a schema to Kenobi (from file)
|
|
23
|
+
|
|
24
|
+
page get <workflowId> <slug> Fetch page content for a specific lead
|
|
25
|
+
types <workflowId> Generate TypeScript interface from schema
|
|
26
|
+
|
|
27
|
+
sources List connected data sources
|
|
28
|
+
workflows List workflows for your org
|
|
29
|
+
|
|
30
|
+
workflow create --name '\u2026' --slug '\u2026' --config '<json>' Create a workflow
|
|
31
|
+
workflow create --name '\u2026' --slug '\u2026' --file config.json Create from file
|
|
32
|
+
workflow get <id> Get full workflow config
|
|
33
|
+
workflow update <id> --config '<json>' Update workflow config
|
|
34
|
+
workflow update <id> --file config.json Update from file
|
|
35
|
+
workflow delete <id> Delete a workflow
|
|
36
|
+
|
|
37
|
+
run <workflowId> [flags] Trigger a workflow run and poll to completion
|
|
26
38
|
|
|
27
39
|
Examples:
|
|
28
40
|
npx kenobi-pages init
|
|
41
|
+
npx kenobi-pages sources
|
|
29
42
|
npx kenobi-pages schema get 42
|
|
30
43
|
npx kenobi-pages schema push "My Page" '{"fields":{"headline":{"type":"string"}}}'
|
|
31
44
|
npx kenobi-pages types 42 > lib/kenobi-types.ts
|
|
32
45
|
npx kenobi-pages page get 42 acme-corp
|
|
33
46
|
npx kenobi-pages workflows
|
|
47
|
+
npx kenobi-pages workflow create --name "Lead page" --slug "lead-page" --config '{...}'
|
|
48
|
+
npx kenobi-pages workflow get 42
|
|
49
|
+
npx kenobi-pages workflow update 42 --config '{...}'
|
|
50
|
+
npx kenobi-pages workflow delete 42
|
|
34
51
|
npx kenobi-pages run 42 --params '{"slug":"acme-corp"}'
|
|
35
52
|
npx kenobi-pages run 42 --params '{"slug":"acme-corp"}' --context "Call transcript: ..."
|
|
36
53
|
|
|
@@ -46,10 +63,10 @@ Exit codes:
|
|
|
46
63
|
4 Unauthorized (invalid API key)
|
|
47
64
|
|
|
48
65
|
Environment:
|
|
49
|
-
KENOBI_PAGES_KEY
|
|
66
|
+
KENOBI_PAGES_KEY Org public key. Set via 'init' or manually.
|
|
50
67
|
KENOBI_BASE_URL Optional. Override the Kenobi API base URL.
|
|
51
68
|
|
|
52
69
|
Key resolution order:
|
|
53
70
|
1. KENOBI_PAGES_KEY environment variable
|
|
54
71
|
2. ~/.kenobi/config.json (written by 'init')
|
|
55
|
-
`,[,,...
|
|
72
|
+
`,[,,...b]=process.argv;(b.length===0||b[0]==="--help"||b[0]==="-h")&&(console.log(ae),process.exit(0));var[p,u,...w]=b;p==="init"?await H():p==="schema"&&u==="get"?await q(w):p==="schema"&&u==="push"?await z(w):p==="page"&&u==="get"?await V(w):p==="types"?await X([u,...w]):p==="sources"?await ne():p==="workflows"?await oe():p==="workflow"&&u==="create"?await se(w):p==="workflow"&&u==="get"?await te(w):p==="workflow"&&u==="update"?await re(w):p==="workflow"&&u==="delete"?await ie(w):p==="run"?await ee([u,...w].filter(Boolean)):(console.error(`Unknown command: ${b.join(" ")}`),console.error("Run 'kenobi-pages --help' for usage."),process.exit(1));
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var b=Object.defineProperty;var s=(i,o)=>b(i,"name",{value:o,configurable:!0});import{KenobiPagesError as c,KenobiNotFoundError as a,KenobiUnauthorizedError as f}from"./errors";const K="https://kenobi.ai",l=s(async(i,o,e)=>{const r=(i.baseUrl??K).replace(/\/+$/,""),n={headers:{"x-kenobi-key":i.apiKey}};(e?.revalidate!==void 0||e?.tags)&&(n.next={},e.revalidate!==void 0&&(n.next.revalidate=e.revalidate),e.tags&&(n.next.tags=[...e.tags]));const t=await fetch(`${r}${o}`,n);if(t.ok)return t;if(t.status===401)throw new f;if(t.status===404)throw new a;const g=await t.text().catch(()=>"Unknown error");throw new c(`Kenobi API error (${t.status}): ${g}`,t.status,"API_ERROR")},"fetchPage"),h=s(i=>({getPage:s(async(o,e,r)=>{try{return await(await l(i,`/api/v1/pages/${o}/${e}`,r)).json()}catch(n){if(n instanceof a)return null;throw n}},"getPage")}),"createKenobiPagesClient");export{h as createKenobiPagesClient};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createKenobiPagesClient } from "./client";
|
|
2
|
-
export { KenobiPagesError,
|
|
3
|
-
export type { KenobiPagesClient, KenobiPagesConfig, KenobiFetchOptions, KenobiPageResponse,
|
|
2
|
+
export { KenobiPagesError, KenobiUnauthorizedError } from "./errors";
|
|
3
|
+
export type { KenobiPagesClient, KenobiPagesConfig, KenobiFetchOptions, KenobiPageResponse, } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createKenobiPagesClient as
|
|
1
|
+
import{createKenobiPagesClient as r}from"./client";import{KenobiPagesError as i,KenobiUnauthorizedError as t}from"./errors";export{i as KenobiPagesError,t as KenobiUnauthorizedError,r as createKenobiPagesClient};
|
package/dist/types.d.ts
CHANGED
|
@@ -15,99 +15,6 @@ export interface KenobiPageResponse {
|
|
|
15
15
|
readonly metadata: Record<string, unknown> | null;
|
|
16
16
|
readonly updatedAt: string;
|
|
17
17
|
}
|
|
18
|
-
export interface KenobiSchemaResponse {
|
|
19
|
-
readonly schema: Record<string, unknown>;
|
|
20
|
-
readonly provider: string;
|
|
21
|
-
readonly title: string;
|
|
22
|
-
}
|
|
23
|
-
export interface PostSchemaResponse {
|
|
24
|
-
readonly sourceKey: string;
|
|
25
|
-
readonly name: string;
|
|
26
|
-
}
|
|
27
|
-
interface FieldSpecBase {
|
|
28
|
-
readonly description?: string;
|
|
29
|
-
readonly optional?: boolean;
|
|
30
|
-
}
|
|
31
|
-
export type OutputFieldSpec = ({
|
|
32
|
-
readonly type: "string";
|
|
33
|
-
readonly min?: number;
|
|
34
|
-
readonly max?: number;
|
|
35
|
-
} & FieldSpecBase) | ({
|
|
36
|
-
readonly type: "url";
|
|
37
|
-
} & FieldSpecBase) | ({
|
|
38
|
-
readonly type: "number";
|
|
39
|
-
readonly min?: number;
|
|
40
|
-
readonly max?: number;
|
|
41
|
-
readonly integer?: boolean;
|
|
42
|
-
} & FieldSpecBase) | ({
|
|
43
|
-
readonly type: "boolean";
|
|
44
|
-
} & FieldSpecBase) | ({
|
|
45
|
-
readonly type: "enum";
|
|
46
|
-
readonly values?: readonly string[];
|
|
47
|
-
} & FieldSpecBase) | ({
|
|
48
|
-
readonly type: "object";
|
|
49
|
-
readonly fields: Readonly<Record<string, OutputFieldSpec>>;
|
|
50
|
-
} & FieldSpecBase) | ({
|
|
51
|
-
readonly type: "array";
|
|
52
|
-
readonly items: OutputFieldSpec;
|
|
53
|
-
readonly min?: number;
|
|
54
|
-
readonly max?: number;
|
|
55
|
-
} & FieldSpecBase);
|
|
56
|
-
export interface KenobiPageSchema {
|
|
57
|
-
readonly fields: Readonly<Record<string, OutputFieldSpec>>;
|
|
58
|
-
}
|
|
59
|
-
export interface WorkflowParam {
|
|
60
|
-
readonly name: string;
|
|
61
|
-
readonly description?: string;
|
|
62
|
-
}
|
|
63
|
-
export interface WorkflowSummary {
|
|
64
|
-
readonly id: number;
|
|
65
|
-
readonly name: string;
|
|
66
|
-
readonly slug: string;
|
|
67
|
-
readonly description: string | null;
|
|
68
|
-
readonly params: readonly WorkflowParam[];
|
|
69
|
-
readonly outputProvider: string | null;
|
|
70
|
-
readonly outputTitle: string | null;
|
|
71
|
-
}
|
|
72
|
-
export interface WorkflowDetail {
|
|
73
|
-
readonly id: number;
|
|
74
|
-
readonly name: string;
|
|
75
|
-
readonly slug: string;
|
|
76
|
-
readonly description: string | null;
|
|
77
|
-
readonly params: readonly WorkflowParam[];
|
|
78
|
-
readonly output: {
|
|
79
|
-
readonly provider: string | null;
|
|
80
|
-
readonly title: string | null;
|
|
81
|
-
readonly schema: Record<string, unknown> | null;
|
|
82
|
-
};
|
|
83
|
-
readonly destinations: readonly {
|
|
84
|
-
readonly adapter: string;
|
|
85
|
-
}[];
|
|
86
|
-
}
|
|
87
|
-
export interface TriggerRunOptions {
|
|
88
|
-
readonly params?: Record<string, string>;
|
|
89
|
-
/** Ephemeral free-form context prepended to all LLM generation calls for this run. */
|
|
90
|
-
readonly context?: string;
|
|
91
|
-
}
|
|
92
|
-
export interface RunHandle {
|
|
93
|
-
readonly runId: string;
|
|
94
|
-
readonly status: string;
|
|
95
|
-
}
|
|
96
|
-
export type RunStatus = "QUEUED" | "EXECUTING" | "COMPLETED" | "FAILED" | "CANCELED";
|
|
97
|
-
export interface RunStatusResponse {
|
|
98
|
-
readonly runId: string;
|
|
99
|
-
readonly status: RunStatus;
|
|
100
|
-
readonly output: Record<string, unknown> | null;
|
|
101
|
-
readonly createdAt: string;
|
|
102
|
-
readonly finishedAt: string | null;
|
|
103
|
-
}
|
|
104
18
|
export interface KenobiPagesClient {
|
|
105
19
|
readonly getPage: (workflowId: number, slug: string, opts?: KenobiFetchOptions) => Promise<KenobiPageResponse | null>;
|
|
106
|
-
readonly getSchema: (workflowId: number, opts?: KenobiFetchOptions) => Promise<KenobiSchemaResponse>;
|
|
107
|
-
readonly postSchema: (name: string, schema: KenobiPageSchema) => Promise<PostSchemaResponse>;
|
|
108
|
-
readonly listWorkflows: () => Promise<readonly WorkflowSummary[]>;
|
|
109
|
-
readonly getWorkflow: (workflowId: number) => Promise<WorkflowDetail>;
|
|
110
|
-
readonly triggerRun: (workflowId: number, options: TriggerRunOptions) => Promise<RunHandle>;
|
|
111
|
-
readonly getRunStatus: (workflowId: number, runId: string) => Promise<RunStatusResponse>;
|
|
112
20
|
}
|
|
113
|
-
export {};
|