specli 0.0.23 → 0.0.24

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.
@@ -5,70 +5,36 @@
5
5
  *
6
6
  * @example
7
7
  * ```ts
8
- * import { specli } from "specli/ai";
8
+ * import { specliTool } from "specli/ai/tools";
9
9
  * import { generateText } from "ai";
10
10
  *
11
11
  * const result = await generateText({
12
12
  * model: yourModel,
13
13
  * tools: {
14
- * api: await specli({ spec: "https://api.example.com/openapi.json" }),
14
+ * api: await specliTool({ spec: "https://api.example.com/openapi.json" }),
15
15
  * },
16
16
  * prompt: "List all users",
17
17
  * });
18
18
  * ```
19
19
  */
20
- export type SpecliToolOptions = {
21
- /** The OpenAPI spec URL or file path */
22
- spec: string;
23
- /** Override the server/base URL */
24
- server?: string;
25
- /** Server URL template variables */
26
- serverVars?: Record<string, string>;
27
- /** Bearer token for authentication */
28
- bearerToken?: string;
29
- /** API key for authentication */
30
- apiKey?: string;
31
- /** Basic auth credentials */
32
- basicAuth?: {
33
- username: string;
34
- password: string;
35
- };
36
- /** Auth scheme to use (if multiple are available) */
37
- authScheme?: string;
38
- };
20
+ import { type SpecliOptions } from "../client/index.js";
39
21
  /**
40
22
  * Create an AI SDK tool for interacting with an OpenAPI spec.
41
23
  *
42
24
  * The spec is fetched once when this function is called, so the returned
43
25
  * tool already has the spec loaded and ready to use.
44
26
  */
45
- export declare function specli(options: SpecliToolOptions): Promise<import("ai").Tool<{
27
+ export declare function specliTool(options: SpecliOptions): Promise<import("ai").Tool<{
46
28
  command: "list" | "exec" | "help";
47
29
  resource?: string | undefined;
48
30
  action?: string | undefined;
49
31
  args?: string[] | undefined;
50
32
  flags?: Record<string, unknown> | undefined;
51
- }, {
52
- resources: {
53
- name: string;
54
- actions: {
55
- name: string;
56
- summary: string | undefined;
57
- method: string;
58
- path: string;
59
- args: string[];
60
- requiredFlags: string[];
61
- }[];
62
- }[];
33
+ }, import("../client/index.js").ActionDetail | {
34
+ resources: import("../client/index.js").ResourceInfo[];
63
35
  error?: undefined;
64
36
  resource?: undefined;
65
37
  actions?: undefined;
66
- action?: undefined;
67
- method?: undefined;
68
- path?: undefined;
69
- summary?: undefined;
70
- args?: undefined;
71
- flags?: undefined;
72
38
  status?: undefined;
73
39
  ok?: undefined;
74
40
  body?: undefined;
@@ -77,12 +43,6 @@ export declare function specli(options: SpecliToolOptions): Promise<import("ai")
77
43
  resources?: undefined;
78
44
  resource?: undefined;
79
45
  actions?: undefined;
80
- action?: undefined;
81
- method?: undefined;
82
- path?: undefined;
83
- summary?: undefined;
84
- args?: undefined;
85
- flags?: undefined;
86
46
  status?: undefined;
87
47
  ok?: undefined;
88
48
  body?: undefined;
@@ -91,34 +51,6 @@ export declare function specli(options: SpecliToolOptions): Promise<import("ai")
91
51
  actions: string[];
92
52
  resources?: undefined;
93
53
  error?: undefined;
94
- action?: undefined;
95
- method?: undefined;
96
- path?: undefined;
97
- summary?: undefined;
98
- args?: undefined;
99
- flags?: undefined;
100
- status?: undefined;
101
- ok?: undefined;
102
- body?: undefined;
103
- } | {
104
- action: string;
105
- method: string;
106
- path: string;
107
- summary: string | undefined;
108
- args: {
109
- name: string;
110
- description: string | undefined;
111
- }[];
112
- flags: {
113
- name: string;
114
- type: import("../cli/parse/schema-shape.js").ParamType;
115
- required: boolean;
116
- description: string | undefined;
117
- }[];
118
- resources?: undefined;
119
- error?: undefined;
120
- resource?: undefined;
121
- actions?: undefined;
122
54
  status?: undefined;
123
55
  ok?: undefined;
124
56
  body?: undefined;
@@ -130,10 +62,6 @@ export declare function specli(options: SpecliToolOptions): Promise<import("ai")
130
62
  error?: undefined;
131
63
  resource?: undefined;
132
64
  actions?: undefined;
133
- action?: undefined;
134
- method?: undefined;
135
- path?: undefined;
136
- summary?: undefined;
137
- args?: undefined;
138
- flags?: undefined;
139
65
  }>>;
66
+ export { specliTool as specli };
67
+ export type { SpecliOptions as SpecliToolOptions } from "../client/index.js";
package/dist/ai/tools.js CHANGED
@@ -5,13 +5,13 @@
5
5
  *
6
6
  * @example
7
7
  * ```ts
8
- * import { specli } from "specli/ai";
8
+ * import { specliTool } from "specli/ai/tools";
9
9
  * import { generateText } from "ai";
10
10
  *
11
11
  * const result = await generateText({
12
12
  * model: yourModel,
13
13
  * tools: {
14
- * api: await specli({ spec: "https://api.example.com/openapi.json" }),
14
+ * api: await specliTool({ spec: "https://api.example.com/openapi.json" }),
15
15
  * },
16
16
  * prompt: "List all users",
17
17
  * });
@@ -19,22 +19,15 @@
19
19
  */
20
20
  import { tool } from "ai";
21
21
  import { z } from "zod";
22
- import { buildRuntimeContext } from "../cli/runtime/context.js";
23
- import { execute } from "../cli/runtime/execute.js";
24
- function findAction(ctx, resource, action) {
25
- const r = ctx.commands.resources.find((r) => r.resource.toLowerCase() === resource.toLowerCase());
26
- return r?.actions.find((a) => a.action.toLowerCase() === action.toLowerCase());
27
- }
22
+ import { createClient } from "../client/index.js";
28
23
  /**
29
24
  * Create an AI SDK tool for interacting with an OpenAPI spec.
30
25
  *
31
26
  * The spec is fetched once when this function is called, so the returned
32
27
  * tool already has the spec loaded and ready to use.
33
28
  */
34
- export async function specli(options) {
35
- const { spec, server, serverVars, bearerToken, apiKey, basicAuth, authScheme, } = options;
36
- // Fetch and parse the spec upfront
37
- const ctx = await buildRuntimeContext({ spec });
29
+ export async function specliTool(options) {
30
+ const client = await createClient(options);
38
31
  return tool({
39
32
  description: `Execute API operations. Commands: "list" (show resources/actions), "help" (action details), "exec" (call API).`,
40
33
  inputSchema: z.object({
@@ -52,90 +45,32 @@ export async function specli(options) {
52
45
  }),
53
46
  execute: async ({ command, resource, action, args, flags }) => {
54
47
  if (command === "list") {
55
- return {
56
- resources: ctx.commands.resources.map((r) => ({
57
- name: r.resource,
58
- actions: r.actions.map((a) => ({
59
- name: a.action,
60
- summary: a.summary,
61
- method: a.method,
62
- path: a.path,
63
- args: a.positionals.map((p) => p.name),
64
- requiredFlags: a.flags
65
- .filter((f) => f.required)
66
- .map((f) => f.flag),
67
- })),
68
- })),
69
- };
48
+ return { resources: client.list() };
70
49
  }
71
50
  if (command === "help") {
72
51
  if (!resource)
73
52
  return { error: "Missing resource" };
74
- const r = ctx.commands.resources.find((r) => r.resource.toLowerCase() === resource.toLowerCase());
75
- if (!r)
76
- return { error: `Unknown resource: ${resource}` };
77
53
  if (!action) {
54
+ // List actions for a resource
55
+ const resources = client.list();
56
+ const r = resources.find((r) => r.name.toLowerCase() === resource.toLowerCase());
57
+ if (!r)
58
+ return { error: `Unknown resource: ${resource}` };
78
59
  return {
79
- resource: r.resource,
80
- actions: r.actions.map((a) => a.action),
60
+ resource: r.name,
61
+ actions: r.actions.map((a) => a.name),
81
62
  };
82
63
  }
83
- const a = r.actions.find((a) => a.action.toLowerCase() === action.toLowerCase());
84
- if (!a)
85
- return { error: `Unknown action: ${action}` };
86
- return {
87
- action: a.action,
88
- method: a.method,
89
- path: a.path,
90
- summary: a.summary,
91
- args: a.positionals.map((p) => ({
92
- name: p.name,
93
- description: p.description,
94
- })),
95
- flags: a.flags.map((f) => ({
96
- name: f.flag,
97
- type: f.type,
98
- required: f.required,
99
- description: f.description,
100
- })),
101
- };
64
+ const detail = client.help(resource, action);
65
+ if (!detail)
66
+ return { error: `Unknown: ${resource} ${action}` };
67
+ return detail;
102
68
  }
103
69
  if (command === "exec") {
104
70
  if (!resource || !action)
105
71
  return { error: "Missing resource or action" };
106
- const actionDef = findAction(ctx, resource, action);
107
- if (!actionDef)
108
- return { error: `Unknown: ${resource} ${action}` };
109
- const positionalValues = args ?? [];
110
- if (positionalValues.length < actionDef.positionals.length) {
111
- return {
112
- error: `Missing args: ${actionDef.positionals
113
- .slice(positionalValues.length)
114
- .map((p) => p.name)
115
- .join(", ")}`,
116
- };
117
- }
118
- const globals = {
119
- server,
120
- serverVar: serverVars
121
- ? Object.entries(serverVars).map(([k, v]) => `${k}=${v}`)
122
- : undefined,
123
- auth: authScheme,
124
- bearerToken,
125
- apiKey,
126
- username: basicAuth?.username,
127
- password: basicAuth?.password,
128
- };
129
72
  try {
130
- const result = await execute({
131
- specId: ctx.loaded.id,
132
- action: actionDef,
133
- positionalValues,
134
- flagValues: flags ?? {},
135
- globals,
136
- servers: ctx.servers,
137
- authSchemes: ctx.authSchemes,
138
- });
73
+ const result = await client.exec(resource, action, args ?? [], flags ?? {});
139
74
  return { status: result.status, ok: result.ok, body: result.body };
140
75
  }
141
76
  catch (err) {
@@ -146,3 +81,5 @@ export async function specli(options) {
146
81
  },
147
82
  });
148
83
  }
84
+ // Re-export for backwards compatibility
85
+ export { specliTool as specli };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Specli Client - Core programmatic API for OpenAPI specs
3
+ */
4
+ import type { AuthScheme } from "../cli/parse/auth-schemes.js";
5
+ import type { ServerInfo } from "../cli/parse/servers.js";
6
+ import { type ExecuteResult } from "../cli/runtime/execute.js";
7
+ export type SpecliOptions = {
8
+ /** The OpenAPI spec URL or file path */
9
+ spec: string;
10
+ /** Override the server/base URL */
11
+ server?: string;
12
+ /** Server URL template variables */
13
+ serverVars?: Record<string, string>;
14
+ /** Bearer token for authentication */
15
+ bearerToken?: string;
16
+ /** API key for authentication */
17
+ apiKey?: string;
18
+ /** Basic auth credentials */
19
+ basicAuth?: {
20
+ username: string;
21
+ password: string;
22
+ };
23
+ /** Auth scheme to use (if multiple are available) */
24
+ authScheme?: string;
25
+ };
26
+ export type ResourceInfo = {
27
+ name: string;
28
+ actions: ActionInfo[];
29
+ };
30
+ export type ActionInfo = {
31
+ name: string;
32
+ summary?: string;
33
+ method: string;
34
+ path: string;
35
+ args: string[];
36
+ requiredFlags: string[];
37
+ optionalFlags: string[];
38
+ };
39
+ export type ActionDetail = {
40
+ action: string;
41
+ method: string;
42
+ path: string;
43
+ summary?: string;
44
+ args: Array<{
45
+ name: string;
46
+ description?: string;
47
+ }>;
48
+ flags: Array<{
49
+ name: string;
50
+ type: string;
51
+ required: boolean;
52
+ description?: string;
53
+ }>;
54
+ };
55
+ export type SpecliClient = {
56
+ /** List all available resources and their actions */
57
+ list(): ResourceInfo[];
58
+ /** Get detailed help for a specific action */
59
+ help(resource: string, action: string): ActionDetail | undefined;
60
+ /** Execute an API action */
61
+ exec(resource: string, action: string, args?: string[], flags?: Record<string, unknown>): Promise<ExecuteResult>;
62
+ /** Get server information */
63
+ servers: ServerInfo[];
64
+ /** Get authentication schemes */
65
+ authSchemes: AuthScheme[];
66
+ };
67
+ /**
68
+ * Create a specli client for interacting with an OpenAPI spec.
69
+ */
70
+ export declare function createClient(options: SpecliOptions): Promise<SpecliClient>;
71
+ export type { AuthScheme } from "../cli/parse/auth-schemes.js";
72
+ export type { ServerInfo } from "../cli/parse/servers.js";
73
+ export type { ExecuteResult } from "../cli/runtime/execute.js";
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Specli Client - Core programmatic API for OpenAPI specs
3
+ */
4
+ import { buildRuntimeContext } from "../cli/runtime/context.js";
5
+ import { execute } from "../cli/runtime/execute.js";
6
+ function findAction(ctx, resource, action) {
7
+ const r = ctx.commands.resources.find((r) => r.resource.toLowerCase() === resource.toLowerCase());
8
+ return r?.actions.find((a) => a.action.toLowerCase() === action.toLowerCase());
9
+ }
10
+ /**
11
+ * Create a specli client for interacting with an OpenAPI spec.
12
+ */
13
+ export async function createClient(options) {
14
+ const { spec, server, serverVars, bearerToken, apiKey, basicAuth, authScheme, } = options;
15
+ const ctx = await buildRuntimeContext({ spec });
16
+ const globals = {
17
+ server,
18
+ serverVar: serverVars
19
+ ? Object.entries(serverVars).map(([k, v]) => `${k}=${v}`)
20
+ : undefined,
21
+ auth: authScheme,
22
+ bearerToken,
23
+ apiKey,
24
+ username: basicAuth?.username,
25
+ password: basicAuth?.password,
26
+ };
27
+ return {
28
+ list() {
29
+ return ctx.commands.resources.map((r) => ({
30
+ name: r.resource,
31
+ actions: r.actions.map((a) => ({
32
+ name: a.action,
33
+ summary: a.summary,
34
+ method: a.method,
35
+ path: a.path,
36
+ args: a.positionals.map((p) => p.name),
37
+ requiredFlags: a.flags.filter((f) => f.required).map((f) => f.flag),
38
+ optionalFlags: a.flags.filter((f) => !f.required).map((f) => f.flag),
39
+ })),
40
+ }));
41
+ },
42
+ help(resource, action) {
43
+ const actionDef = findAction(ctx, resource, action);
44
+ if (!actionDef)
45
+ return undefined;
46
+ return {
47
+ action: actionDef.action,
48
+ method: actionDef.method,
49
+ path: actionDef.path,
50
+ summary: actionDef.summary,
51
+ args: actionDef.positionals.map((p) => ({
52
+ name: p.name,
53
+ description: p.description,
54
+ })),
55
+ flags: actionDef.flags.map((f) => ({
56
+ name: f.flag,
57
+ type: f.type,
58
+ required: f.required,
59
+ description: f.description,
60
+ })),
61
+ };
62
+ },
63
+ async exec(resource, action, args = [], flags = {}) {
64
+ const actionDef = findAction(ctx, resource, action);
65
+ if (!actionDef) {
66
+ throw new Error(`Unknown action: ${resource} ${action}`);
67
+ }
68
+ return execute({
69
+ specId: ctx.loaded.id,
70
+ action: actionDef,
71
+ positionalValues: args,
72
+ flagValues: flags,
73
+ globals,
74
+ servers: ctx.servers,
75
+ authSchemes: ctx.authSchemes,
76
+ });
77
+ },
78
+ servers: ctx.servers,
79
+ authSchemes: ctx.authSchemes,
80
+ };
81
+ }
package/dist/index.d.ts CHANGED
@@ -15,69 +15,7 @@
15
15
  * console.log(result.body);
16
16
  * ```
17
17
  */
18
- import type { AuthScheme } from "./cli/parse/auth-schemes.js";
19
- import type { ServerInfo } from "./cli/parse/servers.js";
20
- import { type ExecuteResult } from "./cli/runtime/execute.js";
21
- export type SpecliOptions = {
22
- /** The OpenAPI spec URL or file path */
23
- spec: string;
24
- /** Override the server/base URL */
25
- server?: string;
26
- /** Server URL template variables */
27
- serverVars?: Record<string, string>;
28
- /** Bearer token for authentication */
29
- bearerToken?: string;
30
- /** API key for authentication */
31
- apiKey?: string;
32
- /** Basic auth credentials */
33
- basicAuth?: {
34
- username: string;
35
- password: string;
36
- };
37
- /** Auth scheme to use (if multiple are available) */
38
- authScheme?: string;
39
- };
40
- export type ResourceInfo = {
41
- name: string;
42
- actions: ActionInfo[];
43
- };
44
- export type ActionInfo = {
45
- name: string;
46
- summary?: string;
47
- method: string;
48
- path: string;
49
- args: string[];
50
- requiredFlags: string[];
51
- optionalFlags: string[];
52
- };
53
- export type ActionDetail = {
54
- action: string;
55
- method: string;
56
- path: string;
57
- summary?: string;
58
- args: Array<{
59
- name: string;
60
- description?: string;
61
- }>;
62
- flags: Array<{
63
- name: string;
64
- type: string;
65
- required: boolean;
66
- description?: string;
67
- }>;
68
- };
69
- export type SpecliClient = {
70
- /** List all available resources and their actions */
71
- list(): ResourceInfo[];
72
- /** Get detailed help for a specific action */
73
- help(resource: string, action: string): ActionDetail | undefined;
74
- /** Execute an API action */
75
- exec(resource: string, action: string, args?: string[], flags?: Record<string, unknown>): Promise<ExecuteResult>;
76
- /** Get server information */
77
- servers: ServerInfo[];
78
- /** Get authentication schemes */
79
- authSchemes: AuthScheme[];
80
- };
18
+ import { type SpecliClient, type SpecliOptions } from "./client/index.js";
81
19
  /**
82
20
  * Create a specli client for interacting with an OpenAPI spec.
83
21
  *
@@ -101,6 +39,4 @@ export type SpecliClient = {
101
39
  * ```
102
40
  */
103
41
  export declare function specli(options: SpecliOptions): Promise<SpecliClient>;
104
- export type { AuthScheme } from "./cli/parse/auth-schemes.js";
105
- export type { ServerInfo } from "./cli/parse/servers.js";
106
- export type { ExecuteResult } from "./cli/runtime/execute.js";
42
+ export type { ActionDetail, ActionInfo, AuthScheme, ExecuteResult, ResourceInfo, ServerInfo, SpecliClient, SpecliOptions, } from "./client/index.js";
package/dist/index.js CHANGED
@@ -15,12 +15,7 @@
15
15
  * console.log(result.body);
16
16
  * ```
17
17
  */
18
- import { buildRuntimeContext } from "./cli/runtime/context.js";
19
- import { execute } from "./cli/runtime/execute.js";
20
- function findAction(ctx, resource, action) {
21
- const r = ctx.commands.resources.find((r) => r.resource.toLowerCase() === resource.toLowerCase());
22
- return r?.actions.find((a) => a.action.toLowerCase() === action.toLowerCase());
23
- }
18
+ import { createClient, } from "./client/index.js";
24
19
  /**
25
20
  * Create a specli client for interacting with an OpenAPI spec.
26
21
  *
@@ -44,71 +39,5 @@ function findAction(ctx, resource, action) {
44
39
  * ```
45
40
  */
46
41
  export async function specli(options) {
47
- const { spec, server, serverVars, bearerToken, apiKey, basicAuth, authScheme, } = options;
48
- const ctx = await buildRuntimeContext({ spec });
49
- const globals = {
50
- server,
51
- serverVar: serverVars
52
- ? Object.entries(serverVars).map(([k, v]) => `${k}=${v}`)
53
- : undefined,
54
- auth: authScheme,
55
- bearerToken,
56
- apiKey,
57
- username: basicAuth?.username,
58
- password: basicAuth?.password,
59
- };
60
- return {
61
- list() {
62
- return ctx.commands.resources.map((r) => ({
63
- name: r.resource,
64
- actions: r.actions.map((a) => ({
65
- name: a.action,
66
- summary: a.summary,
67
- method: a.method,
68
- path: a.path,
69
- args: a.positionals.map((p) => p.name),
70
- requiredFlags: a.flags.filter((f) => f.required).map((f) => f.flag),
71
- optionalFlags: a.flags.filter((f) => !f.required).map((f) => f.flag),
72
- })),
73
- }));
74
- },
75
- help(resource, action) {
76
- const actionDef = findAction(ctx, resource, action);
77
- if (!actionDef)
78
- return undefined;
79
- return {
80
- action: actionDef.action,
81
- method: actionDef.method,
82
- path: actionDef.path,
83
- summary: actionDef.summary,
84
- args: actionDef.positionals.map((p) => ({
85
- name: p.name,
86
- description: p.description,
87
- })),
88
- flags: actionDef.flags.map((f) => ({
89
- name: f.flag,
90
- type: f.type,
91
- required: f.required,
92
- description: f.description,
93
- })),
94
- };
95
- },
96
- async exec(resource, action, args = [], flags = {}) {
97
- const actionDef = findAction(ctx, resource, action);
98
- if (!actionDef) {
99
- throw new Error(`Unknown action: ${resource} ${action}`);
100
- }
101
- return execute({
102
- specId: ctx.loaded.id,
103
- action: actionDef,
104
- positionalValues: args,
105
- flagValues: flags,
106
- globals,
107
- servers: ctx.servers,
108
- authSchemes: ctx.authSchemes,
109
- });
110
- },
111
- servers: ctx.servers,
112
- authSchemes: ctx.authSchemes,
113
- };
42
+ return createClient(options);
114
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specli",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "description": "Run any OpenAPI spec as a CLI. Built for Agents.",
5
5
  "repository": {
6
6
  "type": "git",