Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 31 additions & 14 deletions apps/docs/content/docs/cli/cli-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ List automations in the active organization.
output="Automation"
>
Get an automation's metadata. The prompt body is omitted — use
[`automations prompt`](#superset-automations-prompt-id) to read it.
[`automations prompt get`](#superset-automations-prompt-get-id) to read it.
Use [`automations logs`](#superset-automations-logs-id) for run history.
</Command>

Expand Down Expand Up @@ -659,33 +659,50 @@ superset automations create \
>
Update an automation's metadata (name, schedule, agent, host). All flags
optional. Omitting a flag preserves the existing value — `undefined` means
"no change", not "clear". Use [`automations prompt`](#superset-automations-prompt-id)
to read or replace the prompt body.
"no change", not "clear". Use [`automations prompt get`](#superset-automations-prompt-get-id)
or [`automations prompt set`](#superset-automations-prompt-set-id) to read or
replace the prompt body.
</Command>

<Command
name="superset automations prompt <id>"
name="superset automations prompt get <id>"
args={[
{ name: "id", required: true, description: "Automation ID." },
]}
output="Markdown"
>
Print an automation's prompt body to stdout. The output is the raw prompt
with no trailing newline added, so `prompt get` and `prompt set` round-trip
byte-exactly.

```bash
# Read to a file
superset automations prompt get aut_… > prompt.md

# Verify a push landed
superset automations prompt get aut_… | diff - ./prompt.md
```
</Command>
Comment on lines +668 to +685
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

prompt get is missing its structured output shape for --json / --quiet / agent modes.

The PR description explicitly states that prompt get "falls back to structured { id, prompt } output" when --json, --quiet, or an agent-mode env var is active. The current block only documents the raw-text path via output="Markdown", so users scripting against prompt get --json (the typical machine-readable invocation) have no documented return shape.

Also, "Markdown" is not a TypeScript type name — every other output prop in this file is either a named type ("Automation", "Array<AutomationRun>") or an inline literal. Depending on how the Command component renders the output prop, this may appear oddly in the rendered docs.

Suggested fix — add the JSON fallback shape inline the same way other commands document multiple output modes:

📝 Proposed documentation update
 <Command
 	name="superset automations prompt get <id>"
 	args={[
 		{ name: "id", required: true, description: "Automation ID." },
 	]}
-	output="Markdown"
 >
 Print an automation's prompt body to stdout. The output is the raw prompt
 with no trailing newline added, so `prompt get` and `prompt set` round-trip
 byte-exactly.

+In `--json`, `--quiet`, or agent modes the command falls back to structured output:
+
+```ts
+{ id: string; prompt: string }
+```
+
 ```bash
 # Read to a file
 superset automations prompt get aut_… > prompt.md
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name="superset automations prompt get <id>"
args={[
{ name: "id", required: true, description: "Automation ID." },
]}
output="Markdown"
>
Print an automation's prompt body to stdout. The output is the raw prompt
with no trailing newline added, so `prompt get` and `prompt set` round-trip
byte-exactly.
```bash
# Read to a file
superset automations prompt get aut_… > prompt.md
# Verify a push landed
superset automations prompt get aut_… | diff - ./prompt.md
```
</Command>
name="superset automations prompt get <id>"
args={[
{ name: "id", required: true, description: "Automation ID." },
]}
>
Print an automation's prompt body to stdout. The output is the raw prompt
with no trailing newline added, so `prompt get` and `prompt set` round-trip
byte-exactly.
In `--json`, `--quiet`, or agent modes the command falls back to structured output:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/content/docs/cli/cli-reference.mdx` around lines 668 - 685, The
documentation for the Command "superset automations prompt get <id>" only shows
the raw Markdown output and omits the structured JSON fallback; update the
Command block to document both outputs so machine users see the JSON shape used
for --json/--quiet/agent modes (add an inline type block showing { id: string;
prompt: string }) and adjust the output prop/description to reflect both the raw
Markdown path and the structured JSON fallback so the rendered docs show the
machine-readable return shape as well as the raw prompt behavior.


<Command
name="superset automations prompt set <id>"
args={[
{ name: "id", required: true, description: "Automation ID." },
]}
options={[
{ flag: "--from-file <path>", description: "Read the new prompt from a file. Use `-` for stdin." },
{ flag: "--from-file <path>", required: true, description: "Read the new prompt from a file. Use `-` for stdin." },
]}
output="Markdown (read mode) or Automation (write mode)"
output="Automation"
>
Read or replace an automation's prompt body. Without `--from-file`, prints
the current prompt to stdout. With `--from-file <path>` or piped stdin,
replaces the prompt verbatim.
Replace an automation's prompt body. The new prompt fully overwrites the
old one.

```bash
# Read
superset automations prompt aut_… > prompt.md

# Write from file
superset automations prompt aut_… --from-file ./prompt.md
superset automations prompt set aut_… --from-file ./prompt.md

# Write from stdin
cat ./prompt.md | superset automations prompt aut_…
cat ./prompt.md | superset automations prompt set aut_… --from-file -
```
</Command>

Expand Down
6 changes: 5 additions & 1 deletion apps/docs/content/docs/sdk/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,18 @@ Recurring agent runs scheduled by RRULE. Requires a Pro subscription on the org
const automations = await client.automations.list();
```

Each row includes `scheduleText` — a human-readable rendering of the rrule.
Each row is an `AutomationSummary` — the `prompt` body is omitted (it can be
large markdown). Fetch one with `automations.getPrompt(id)`. Each row includes
`scheduleText`, a human-readable rendering of the rrule.

### `automations.retrieve(id)`

```ts
const a = await client.automations.retrieve(id);
```

Returns an `AutomationSummary` (no `prompt` body — call `getPrompt(id)`).

### `automations.create(body)`

Create a recurring automation.
Expand Down
5 changes: 1 addition & 4 deletions packages/cli/src/commands/automations/get/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ export default command({
args: [positional("id").required().desc("Automation id")],
run: async ({ ctx, args }) => {
const id = args.id as string;
const result = await ctx.api.automation.get.query({ id });
// Prompt is fetched via `superset automations prompt <id>` (it can be
// large markdown). Runs are paginated via `superset automations logs <id>`.
const { prompt: _prompt, ...automation } = result;
const automation = await ctx.api.automation.get.query({ id });
return { data: automation };
},
});
61 changes: 0 additions & 61 deletions packages/cli/src/commands/automations/prompt/command.ts

This file was deleted.

24 changes: 24 additions & 0 deletions packages/cli/src/commands/automations/prompt/get/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { isAgentMode, positional } from "@superset/cli-framework";
import { command } from "../../../../lib/command";

export default command({
description: "Print an automation's prompt to stdout",
args: [positional("id").required().desc("Automation id")],
run: async ({ ctx, args, options }) => {
const id = args.id as string;
const { prompt } = await ctx.api.automation.getPrompt.query({ id });
// `--quiet` is intentionally ignored here: it would route through
// `extractIds` and emit only the UUID (which the caller already has
// as input), discarding the prompt body. Plain stdout is the right
// "machine-friendly" output for this command.
const globals = options as Record<string, unknown>;
if (globals.json === true || isAgentMode()) {
return { data: { id, prompt } };
}
// Default: write the raw prompt with no trailing newline so that
// `prompt get <id> > out.md` round-trips byte-exactly with a
// subsequent `prompt set <id> --from-file out.md`.
process.stdout.write(prompt ?? "");
return undefined;
},
});
3 changes: 3 additions & 0 deletions packages/cli/src/commands/automations/prompt/meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
description: "Read or write an automation's prompt",
};
43 changes: 43 additions & 0 deletions packages/cli/src/commands/automations/prompt/set/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { readFileSync } from "node:fs";
import { positional, string } from "@superset/cli-framework";
import { command } from "../../../../lib/command";

async function readStdin(): Promise<string> {
const chunks: Buffer[] = [];
for await (const chunk of process.stdin) {
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
}
return Buffer.concat(chunks).toString("utf-8");
}

export default command({
description: "Replace an automation's prompt from a file or stdin",
args: [positional("id").required().desc("Automation id")],
options: {
fromFile: string()
.required()
.desc(
"Path to a markdown file with the new prompt. Use '-' to read from stdin.",
),
},
run: async ({ ctx, args, options }) => {
const id = args.id as string;
const next =
options.fromFile === "-"
? await readStdin()
: readFileSync(options.fromFile, "utf-8");

if (!next.trim()) {
throw new Error("Refusing to write an empty prompt.");
}

const result = await ctx.api.automation.setPrompt.mutate({
id,
prompt: next,
});
return {
data: { id: result.id, name: result.name, length: next.length },
message: `Updated prompt for "${result.name}" (${next.length} chars).`,
};
},
});
5 changes: 1 addition & 4 deletions packages/mcp-v2/src/tools/automations/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ export function register(server: McpServer): void {
},
handler: async (input, ctx) => {
const caller = createMcpCaller(ctx);
const { prompt: _prompt, ...rest } = await caller.automation.get({
id: input.id,
});
return rest;
return await caller.automation.get({ id: input.id });
},
});
}
5 changes: 2 additions & 3 deletions packages/mcp-v2/src/tools/automations/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ export function register(server: McpServer): void {
defineTool(server, {
name: "automations_list",
description:
"List automations (scheduled agent runs) the calling user owns in the active organization. Returns a summary shape — call automations_get to fetch the full prompt and agentConfig for one automation.",
"List automations (scheduled agent runs) the calling user owns in the active organization. Returns a summary shape — call automations_get_prompt to fetch the prompt for one automation, or automations_get for the rest of its config.",
handler: async (_input, ctx) => {
const caller = createMcpCaller(ctx);
const rows = await caller.automation.list();
return rows.map(({ prompt: _prompt, ...rest }) => rest);
return await caller.automation.list();
},
});
}
2 changes: 2 additions & 0 deletions packages/sdk/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
AutomationRun,
AutomationRunDispatched,
Automations,
AutomationSummary,
AutomationUpdateParams,
} from "./resources/automations";
import { Host, HostListResponse, Hosts } from "./resources/hosts";
Expand Down Expand Up @@ -1138,6 +1139,7 @@ export declare namespace Superset {
export {
Automations,
Automation,
AutomationSummary,
AutomationListResponse,
AutomationCreateParams,
AutomationUpdateParams,
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export {
type AutomationRun,
type AutomationRunDispatched,
Automations,
type AutomationSummary,
type AutomationUpdateParams,
type Host,
type HostListResponse,
Expand Down
45 changes: 34 additions & 11 deletions packages/sdk/src/resources/automations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import type { RequestOptions } from "../internal/request-options";

export class Automations extends APIResource {
/**
* List automations in the active organization.
* List automations in the active organization. Returned rows omit the
* `prompt` body — fetch one prompt with `getPrompt(id)`.
*
* Mirrors `superset automations list`.
*/
Expand All @@ -17,12 +18,20 @@ export class Automations extends APIResource {
}

/**
* Retrieve a single automation by id.
* Retrieve a single automation by id. The `prompt` body is omitted —
* fetch it separately with `getPrompt(id)`.
*
* Mirrors `superset automations get`.
*/
retrieve(id: string, options?: RequestOptions): APIPromise<Automation> {
return this._client.query<Automation>("automation.get", { id }, options);
retrieve(
id: string,
options?: RequestOptions,
): APIPromise<AutomationSummary> {
return this._client.query<AutomationSummary>(
"automation.get",
{ id },
options,
);
}
Comment on lines +26 to 35
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Breaking SDK change: retrieve and list no longer return prompt — needs version bump or migration note

Both the TypeScript API type and the underlying automation.get / automation.list tRPC wire responses now omit prompt. Any existing SDK consumer reading .prompt from automations.retrieve(id) or automations.list() will silently receive undefined at runtime (even without TypeScript errors if they're on an older version of the package).

The PR description states "No wire-format/API changes," but the tRPC response shape for get and list has genuinely changed. This should be accompanied by a semver major bump, a changelog entry, or at minimum a migration note pointing consumers to automations.getPrompt(id).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/sdk/src/resources/automations.ts` around lines 26 - 35, The SDK's
retrieve and list methods (AutomationResource.retrieve and
AutomationResource.list) now return responses that omit the prompt field because
the underlying tRPC handlers ("automation.get" / "automation.list") no longer
include it; update the release artifacts: add a changelog entry and semver-major
bump (or explicit migration note) explaining the breaking change and point
consumers to automations.getPrompt(id) for prompt data, and also update the
TypeScript docs/comments for retrieve and list to reflect that prompt is no
longer returned so callers know to call getPrompt instead.


/**
Expand Down Expand Up @@ -125,9 +134,10 @@ export class Automations extends APIResource {
}

/**
* Get the prompt for an automation.
* Get the prompt body (markdown) for an automation. `retrieve` and
* `list` omit it because it can be large.
*
* Mirrors `superset automations prompt --get`.
* Mirrors `superset automations prompt get`.
*/
getPrompt(
id: string,
Expand All @@ -141,9 +151,10 @@ export class Automations extends APIResource {
}

/**
* Update the prompt for an automation.
* Replace the prompt body for an automation. The new prompt fully
* overwrites the old one.
*
* Mirrors `superset automations prompt`.
* Mirrors `superset automations prompt set`.
*/
setPrompt(
id: string,
Expand All @@ -165,12 +176,15 @@ export interface AgentConfig {
[key: string]: unknown;
}

export interface Automation {
/**
* Lean automation row returned by `list` and `retrieve`. The `prompt`
* body is omitted — call `getPrompt(id)` to fetch it.
*/
export interface AutomationSummary {
id: string;
organizationId: string;
ownerUserId: string;
name: string;
prompt: string;
agentConfig: AgentConfig;
targetHostId: string | null;
v2ProjectId: string;
Expand All @@ -187,7 +201,15 @@ export interface Automation {
updatedAt: string;
}

export type AutomationListResponse = Array<Automation>;
/**
* Full automation row including the `prompt` body. Returned by mutations
* like `create`, `update`, `pause`, `resume`, and `setPrompt`.
*/
export interface Automation extends AutomationSummary {
prompt: string;
}

export type AutomationListResponse = Array<AutomationSummary>;

export interface AutomationCreateParams {
name: string;
Expand Down Expand Up @@ -252,6 +274,7 @@ export interface AutomationRunDispatched {
export declare namespace Automations {
export type {
Automation,
AutomationSummary,
AutomationListResponse,
AutomationCreateParams,
AutomationUpdateParams,
Expand Down
Loading
Loading