mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-12 16:02:56 +00:00
feat: add wmill user list and document post-suspend approvers context (#11600)
* feat: add wmill user list and document post-suspend approvers context Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: approvers holds the resume url approver string when set Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate cli skills for approvers wording Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: update ee-repo-ref to acb254ac509aff244849c09e50a8d39aae185138 This commit updates the EE repository reference after PR #852 was merged in windmill-ee-private. Previous ee-repo-ref: 9cc330f1a8e80bc075a6ad9839966d3b344f8ddd New ee-repo-ref: acb254ac509aff244849c09e50a8d39aae185138 Automated by sync-ee-ref workflow. * fix: drop name column from wmill user list, usr has no name Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: approvalPage resumes record the logged-in user as approver Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
This commit is contained in:
co-authored by
Claude Opus 5.5
windmill-internal-app[bot]
Ruben Fiszel
parent
a2e51cdbaa
commit
1c2667cd55
@@ -1,6 +1,8 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
|
||||
import { requireLogin } from "../../core/auth.ts";
|
||||
import { resolveWorkspace } from "../../core/context.ts";
|
||||
import { mergeConfigWithConfigFile } from "../../core/conf.ts";
|
||||
import {
|
||||
GlobalOptions,
|
||||
isSuperset,
|
||||
@@ -69,6 +71,32 @@ async function list(opts: GlobalOptions) {
|
||||
.render();
|
||||
}
|
||||
|
||||
async function listWorkspaceUsers(opts: GlobalOptions & { json?: boolean }) {
|
||||
if (opts.json) log.setSilent(true);
|
||||
opts = await mergeConfigWithConfigFile(opts);
|
||||
const workspace = await resolveWorkspace(opts);
|
||||
await requireLogin(opts);
|
||||
|
||||
const users = await wmill.listUsers({ workspace: workspace.workspaceId });
|
||||
|
||||
if (opts.json) {
|
||||
console.log(JSON.stringify(users));
|
||||
} else {
|
||||
new Table()
|
||||
.header(["username", "email", "role"])
|
||||
.padding(2)
|
||||
.border(true)
|
||||
.body(
|
||||
users.map((u) => [
|
||||
u.username,
|
||||
u.email,
|
||||
u.is_admin ? "admin" : u.operator ? "operator" : "developer",
|
||||
])
|
||||
)
|
||||
.render();
|
||||
}
|
||||
}
|
||||
|
||||
function rdString() {
|
||||
return Math.random().toString(36).slice(2, 7);
|
||||
}
|
||||
@@ -518,6 +546,9 @@ export async function pushInstanceGroups(
|
||||
const command = new Command()
|
||||
.description("user related commands")
|
||||
.action(list as any)
|
||||
.command("list", "List the users of the workspace")
|
||||
.option("--json", "Output as JSON (for piping to jq)")
|
||||
.action(listWorkspaceUsers as any)
|
||||
.command("add", "Create a user")
|
||||
.arguments("<email:string> [password:string]")
|
||||
.option("--superadmin", "Specify to make the new user superadmin.")
|
||||
|
||||
Generated
+6
@@ -5969,6 +5969,10 @@ can call one, not an agent used as a tool.
|
||||
- \`results.step_id.property\` - Access specific property from a previous step output only when that step result is in scope
|
||||
- \`flow_input.iter.value\` - Current iteration value inside a \`forloopflow\`; in a \`whileloopflow\` it is just the iteration index (a plain number, same as \`flow_input.iter.index\`)
|
||||
- \`flow_input.iter.index\` - Current loop index when inside a loop (\`forloopflow\` or \`whileloopflow\`)
|
||||
- After a suspend step (approval), the next step's javascript expressions also get:
|
||||
- \`resume\` - the last resume payload (the resume form values); with \`continue_on_disapprove_timeout\`, a disapproval or timeout yields \`{ error: { name: "SuspendedDisapproved" | "SuspendedTimedOut", message } }\` instead
|
||||
- \`resumes\` - every resume payload, in arrival order
|
||||
- \`approvers\` - a plain array of strings, one per resume: for a resume through the \`resume\`/\`cancel\` URL from \`getResumeUrls(approver)\`, the \`approver\` passed there if any; otherwise (including the \`approvalPage\` link) the resuming user's username, else \`"anonymous"\`, e.g. \`approvers[0]\`. It is NOT the \`{ resume_id, approver }\` objects stored in the flow status, so \`approvers[0].approver\` is always undefined
|
||||
|
||||
## Loop Structure Rules
|
||||
|
||||
@@ -8711,6 +8715,8 @@ user related commands
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
- \`user list\` - List the users of the workspace
|
||||
- \`--json\` - Output as JSON (for piping to jq)
|
||||
- \`user add <email:string> [password:string]\` - Create a user
|
||||
- \`--superadmin\` - Specify to make the new user superadmin.
|
||||
- \`--company <company:string>\` - Specify to set the company of the new user.
|
||||
|
||||
@@ -727,6 +727,8 @@ user related commands
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
- `user list` - List the users of the workspace
|
||||
- `--json` - Output as JSON (for piping to jq)
|
||||
- `user add <email:string> [password:string]` - Create a user
|
||||
- `--superadmin` - Specify to make the new user superadmin.
|
||||
- `--company <company:string>` - Specify to set the company of the new user.
|
||||
|
||||
@@ -284,6 +284,10 @@ can call one, not an agent used as a tool.
|
||||
- `results.step_id.property` - Access specific property from a previous step output only when that step result is in scope
|
||||
- `flow_input.iter.value` - Current iteration value inside a `forloopflow`; in a `whileloopflow` it is just the iteration index (a plain number, same as `flow_input.iter.index`)
|
||||
- `flow_input.iter.index` - Current loop index when inside a loop (`forloopflow` or `whileloopflow`)
|
||||
- After a suspend step (approval), the next step's javascript expressions also get:
|
||||
- `resume` - the last resume payload (the resume form values); with `continue_on_disapprove_timeout`, a disapproval or timeout yields `{ error: { name: "SuspendedDisapproved" | "SuspendedTimedOut", message } }` instead
|
||||
- `resumes` - every resume payload, in arrival order
|
||||
- `approvers` - a plain array of strings, one per resume: for a resume through the `resume`/`cancel` URL from `getResumeUrls(approver)`, the `approver` passed there if any; otherwise (including the `approvalPage` link) the resuming user's username, else `"anonymous"`, e.g. `approvers[0]`. It is NOT the `{ resume_id, approver }` objects stored in the flow status, so `approvers[0].approver` is always undefined
|
||||
|
||||
## Loop Structure Rules
|
||||
|
||||
|
||||
@@ -311,6 +311,10 @@ can call one, not an agent used as a tool.
|
||||
- \`results.step_id.property\` - Access specific property from a previous step output only when that step result is in scope
|
||||
- \`flow_input.iter.value\` - Current iteration value inside a \`forloopflow\`; in a \`whileloopflow\` it is just the iteration index (a plain number, same as \`flow_input.iter.index\`)
|
||||
- \`flow_input.iter.index\` - Current loop index when inside a loop (\`forloopflow\` or \`whileloopflow\`)
|
||||
- After a suspend step (approval), the next step's javascript expressions also get:
|
||||
- \`resume\` - the last resume payload (the resume form values); with \`continue_on_disapprove_timeout\`, a disapproval or timeout yields \`{ error: { name: "SuspendedDisapproved" | "SuspendedTimedOut", message } }\` instead
|
||||
- \`resumes\` - every resume payload, in arrival order
|
||||
- \`approvers\` - a plain array of strings, one per resume: for a resume through the \`resume\`/\`cancel\` URL from \`getResumeUrls(approver)\`, the \`approver\` passed there if any; otherwise (including the \`approvalPage\` link) the resuming user's username, else \`"anonymous"\`, e.g. \`approvers[0]\`. It is NOT the \`{ resume_id, approver }\` objects stored in the flow status, so \`approvers[0].approver\` is always undefined
|
||||
|
||||
## Loop Structure Rules
|
||||
|
||||
@@ -4206,6 +4210,8 @@ user related commands
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
- \`user list\` - List the users of the workspace
|
||||
- \`--json\` - Output as JSON (for piping to jq)
|
||||
- \`user add <email:string> [password:string]\` - Create a user
|
||||
- \`--superadmin\` - Specify to make the new user superadmin.
|
||||
- \`--company <company:string>\` - Specify to set the company of the new user.
|
||||
|
||||
@@ -732,6 +732,8 @@ user related commands
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
- `user list` - List the users of the workspace
|
||||
- `--json` - Output as JSON (for piping to jq)
|
||||
- `user add <email:string> [password:string]` - Create a user
|
||||
- `--superadmin` - Specify to make the new user superadmin.
|
||||
- `--company <company:string>` - Specify to set the company of the new user.
|
||||
|
||||
@@ -371,6 +371,10 @@ can call one, not an agent used as a tool.
|
||||
- `results.step_id.property` - Access specific property from a previous step output only when that step result is in scope
|
||||
- `flow_input.iter.value` - Current iteration value inside a `forloopflow`; in a `whileloopflow` it is just the iteration index (a plain number, same as `flow_input.iter.index`)
|
||||
- `flow_input.iter.index` - Current loop index when inside a loop (`forloopflow` or `whileloopflow`)
|
||||
- After a suspend step (approval), the next step's javascript expressions also get:
|
||||
- `resume` - the last resume payload (the resume form values); with `continue_on_disapprove_timeout`, a disapproval or timeout yields `{ error: { name: "SuspendedDisapproved" | "SuspendedTimedOut", message } }` instead
|
||||
- `resumes` - every resume payload, in arrival order
|
||||
- `approvers` - a plain array of strings, one per resume: for a resume through the `resume`/`cancel` URL from `getResumeUrls(approver)`, the `approver` passed there if any; otherwise (including the `approvalPage` link) the resuming user's username, else `"anonymous"`, e.g. `approvers[0]`. It is NOT the `{ resume_id, approver }` objects stored in the flow status, so `approvers[0].approver` is always undefined
|
||||
|
||||
## Loop Structure Rules
|
||||
|
||||
|
||||
@@ -289,6 +289,10 @@ can call one, not an agent used as a tool.
|
||||
- `results.step_id.property` - Access specific property from a previous step output only when that step result is in scope
|
||||
- `flow_input.iter.value` - Current iteration value inside a `forloopflow`; in a `whileloopflow` it is just the iteration index (a plain number, same as `flow_input.iter.index`)
|
||||
- `flow_input.iter.index` - Current loop index when inside a loop (`forloopflow` or `whileloopflow`)
|
||||
- After a suspend step (approval), the next step's javascript expressions also get:
|
||||
- `resume` - the last resume payload (the resume form values); with `continue_on_disapprove_timeout`, a disapproval or timeout yields `{ error: { name: "SuspendedDisapproved" | "SuspendedTimedOut", message } }` instead
|
||||
- `resumes` - every resume payload, in arrival order
|
||||
- `approvers` - a plain array of strings, one per resume: for a resume through the `resume`/`cancel` URL from `getResumeUrls(approver)`, the `approver` passed there if any; otherwise (including the `approvalPage` link) the resuming user's username, else `"anonymous"`, e.g. `approvers[0]`. It is NOT the `{ resume_id, approver }` objects stored in the flow status, so `approvers[0].approver` is always undefined
|
||||
|
||||
## Loop Structure Rules
|
||||
|
||||
|
||||
Reference in New Issue
Block a user