@wspc/cli 0.0.12 → 0.0.14
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/dist/cli.js +166 -44
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/spec/openapi.json +51 -14
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command62 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/generated/cli/invite/accept.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -1078,6 +1078,15 @@ var recurrenceRuleList = (options) => (options.client ?? client).get({
|
|
|
1078
1078
|
url: "/todo/recurrence-rules",
|
|
1079
1079
|
...options
|
|
1080
1080
|
});
|
|
1081
|
+
var recurrenceRuleCreate = (options) => (options?.client ?? client).post({
|
|
1082
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1083
|
+
url: "/todo/recurrence-rules",
|
|
1084
|
+
...options,
|
|
1085
|
+
headers: {
|
|
1086
|
+
"Content-Type": "application/json",
|
|
1087
|
+
...options?.headers
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1081
1090
|
var todoList = (options) => (options.client ?? client).get({
|
|
1082
1091
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1083
1092
|
url: "/todo/items",
|
|
@@ -1111,6 +1120,20 @@ var todoCommentUpdate = (options) => (options.client ?? client).patch({
|
|
|
1111
1120
|
...options.headers
|
|
1112
1121
|
}
|
|
1113
1122
|
});
|
|
1123
|
+
var recurrenceRuleDelete = (options) => (options.client ?? client).delete({
|
|
1124
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1125
|
+
url: "/todo/recurrence-rules/{id}",
|
|
1126
|
+
...options,
|
|
1127
|
+
headers: {
|
|
1128
|
+
"Content-Type": "application/json",
|
|
1129
|
+
...options.headers
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
var recurrenceRuleGet = (options) => (options.client ?? client).get({
|
|
1133
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1134
|
+
url: "/todo/recurrence-rules/{id}",
|
|
1135
|
+
...options
|
|
1136
|
+
});
|
|
1114
1137
|
var todoDelete = (options) => (options.client ?? client).delete({
|
|
1115
1138
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1116
1139
|
url: "/todo/items/{id}",
|
|
@@ -1230,9 +1253,9 @@ var ConfigStore = class {
|
|
|
1230
1253
|
};
|
|
1231
1254
|
|
|
1232
1255
|
// src/version.ts
|
|
1233
|
-
var VERSION = "0.0.
|
|
1234
|
-
var SPEC_SHA = "
|
|
1235
|
-
var SPEC_FETCHED_AT = "2026-06-
|
|
1256
|
+
var VERSION = "0.0.14";
|
|
1257
|
+
var SPEC_SHA = "7842b7a9";
|
|
1258
|
+
var SPEC_FETCHED_AT = "2026-06-10T05:27:40.161Z";
|
|
1236
1259
|
var API_BASE = "https://api.wspc.ai";
|
|
1237
1260
|
|
|
1238
1261
|
// src/index.ts
|
|
@@ -2911,9 +2934,36 @@ var projectListCommand = new Command41("ls").description("List projects").option
|
|
|
2911
2934
|
render({ kind: "project_list", display: { "shape": "list", "columns": ["id", "name", "default_todo_type_id"], "format": { "id": "id-short", "name": "truncate", "default_todo_type_id": "id-short" }, "emptyMessage": "no projects" } }, result.data);
|
|
2912
2935
|
});
|
|
2913
2936
|
|
|
2914
|
-
// src/generated/cli/todo/rule/
|
|
2937
|
+
// src/generated/cli/todo/rule/add.ts
|
|
2915
2938
|
import { Command as Command42 } from "commander";
|
|
2916
|
-
var
|
|
2939
|
+
var recurrenceRuleCreateCommand = new Command42("add").description("Create a recurring todo rule").argument("<title>", "title").option("--rrule <value>", "rrule").option("--dtstart <value>", "dtstart").option("--description <value>", "description").option("--parent-id <value>", "parent_id").option("-p, --project <value>", "Project for the recurrence rule, its template todo, and all materialized instances. Must be an active project in the caller's organization.").option("-t, --type <value>", "type_id").action(async (title, opts) => {
|
|
2940
|
+
const client2 = await loadSdkClient();
|
|
2941
|
+
const result = await recurrenceRuleCreate({
|
|
2942
|
+
client: client2._rawClient,
|
|
2943
|
+
body: {
|
|
2944
|
+
title,
|
|
2945
|
+
rrule: opts.rrule,
|
|
2946
|
+
dtstart: opts.dtstart,
|
|
2947
|
+
description: opts.description,
|
|
2948
|
+
parent_id: opts.parentId,
|
|
2949
|
+
project_id: opts.project,
|
|
2950
|
+
type_id: opts.type
|
|
2951
|
+
}
|
|
2952
|
+
});
|
|
2953
|
+
if (result.error || !result.response?.ok) {
|
|
2954
|
+
process.stderr.write(
|
|
2955
|
+
`HTTP ${result.response?.status ?? "?"}: ${JSON.stringify(result.error ?? "unknown error", null, 2)}
|
|
2956
|
+
`
|
|
2957
|
+
);
|
|
2958
|
+
process.exitCode = 1;
|
|
2959
|
+
return;
|
|
2960
|
+
}
|
|
2961
|
+
render({ kind: "recurrence_rule_create", display: void 0 }, result.data);
|
|
2962
|
+
});
|
|
2963
|
+
|
|
2964
|
+
// src/generated/cli/todo/rule/ls.ts
|
|
2965
|
+
import { Command as Command43 } from "commander";
|
|
2966
|
+
var recurrenceRuleListCommand = new Command43("ls").description("List recurring todo rules").option("--project-id <value>", "Project id filter. Required. Unknown, cross-organization, or soft-deleted project ids return NOT_FOUND.").option("--user-id <value>", "user_id").action(async (opts) => {
|
|
2917
2967
|
const client2 = await loadSdkClient();
|
|
2918
2968
|
const result = await recurrenceRuleList({
|
|
2919
2969
|
client: client2._rawClient,
|
|
@@ -2930,12 +2980,26 @@ var recurrenceRuleListCommand = new Command42("ls").description("List recurring
|
|
|
2930
2980
|
process.exitCode = 1;
|
|
2931
2981
|
return;
|
|
2932
2982
|
}
|
|
2933
|
-
render({ kind: "recurrence_rule_list", display: { "shape": "list", "columns": ["id", "rrule", "dtstart"], "format": { "id": "id-short", "rrule": "truncate" }, "emptyMessage": "no recurrence rules" } }, result.data);
|
|
2983
|
+
render({ kind: "recurrence_rule_list", display: { "shape": "list", "columns": ["id", "rrule", "dtstart", "type_id"], "format": { "id": "id-short", "rrule": "truncate", "type_id": "id-short" }, "emptyMessage": "no recurrence rules" } }, result.data);
|
|
2934
2984
|
});
|
|
2935
2985
|
|
|
2936
2986
|
// src/generated/cli/todo/add.ts
|
|
2937
|
-
import { Command as
|
|
2938
|
-
|
|
2987
|
+
import { Command as Command44 } from "commander";
|
|
2988
|
+
|
|
2989
|
+
// src/handwritten/utils/parse-json-field.ts
|
|
2990
|
+
function parseJsonField(raw, flag) {
|
|
2991
|
+
if (raw === void 0) return void 0;
|
|
2992
|
+
try {
|
|
2993
|
+
return JSON.parse(raw);
|
|
2994
|
+
} catch {
|
|
2995
|
+
process.stderr.write(`Invalid JSON for --${flag}: ${raw}
|
|
2996
|
+
`);
|
|
2997
|
+
process.exit(1);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
// src/generated/cli/todo/add.ts
|
|
3002
|
+
var todoCreateCommand = new Command44("add").description("Create a todo").argument("<title>", "title").option("-p, --project <value>", "Project id to assign this todo to. It must be an active project in the caller's organization.").option("--description <value>", "Free-form details about the todo. Fully supports GFM Markdown (tables, strikethrough, task lists). Stored verbatim; client applications are responsible for rendering. Optional. Passing `null` is strictly rejected.").option("--parent-id <value>", "Parent todo ID (`tod_<ULID>`) to attach this todo as a child under another todo. Omit or pass `null` to create a root-level todo. Nesting is limited to one level; attempting to set a child todo as a parent will trigger `PARENT_IS_CHILD`. To make a subtask appear on every occurrence of a recurring rule, set this to that rule's template todo id (the template id returned when the rule is created); the server re-materializes future occurrences so each carries the subtask.").option("--status <value>", "Initial status of the todo. Omit to default to `open`. Allowed values: `open`, `in_progress`, `done`, `cancelled`.").option("--due-at <value>", 'Optional calendar due date in ISO date-only format (`YYYY-MM-DD`). Stored without timezone offsets to represent the same local calendar day globally. Pass `""` or omit the field to skip setting a due date. Passing `null` is strictly rejected.').option("--type-id <value>", "Type id this todo belongs to. Omit to use the project's default type. When project_id is also supplied, the type must belong to the same project. New server-generated type ids use typ_<ULID>; legacy ids remain accepted.").option("--custom-fields <value>", "Custom field values keyed by the field's immutable `key` (not the human `label`). Each value must match the declared field type: string fields require string values, and string_array fields require string arrays. Providing a key that is not declared on the resolved todo type is strictly rejected with `UNDECLARED_FIELD`. Missing required fields that lack a default value are rejected with `FIELD_REQUIRED`. Defaults declared on the type are auto-applied at create time.").action(async (title, opts) => {
|
|
2939
3003
|
const client2 = await loadSdkClient();
|
|
2940
3004
|
const result = await todoCreate({
|
|
2941
3005
|
client: client2._rawClient,
|
|
@@ -2947,7 +3011,7 @@ var todoCreateCommand = new Command43("add").description("Create a todo").argume
|
|
|
2947
3011
|
status: opts.status,
|
|
2948
3012
|
due_at: opts.dueAt,
|
|
2949
3013
|
type_id: opts.typeId,
|
|
2950
|
-
custom_fields: opts.customFields
|
|
3014
|
+
custom_fields: parseJsonField(opts.customFields, "custom-fields")
|
|
2951
3015
|
}
|
|
2952
3016
|
});
|
|
2953
3017
|
if (result.error || !result.response?.ok) {
|
|
@@ -2962,8 +3026,8 @@ var todoCreateCommand = new Command43("add").description("Create a todo").argume
|
|
|
2962
3026
|
});
|
|
2963
3027
|
|
|
2964
3028
|
// src/generated/cli/todo/ls.ts
|
|
2965
|
-
import { Command as
|
|
2966
|
-
var todoListCommand = new
|
|
3029
|
+
import { Command as Command45 } from "commander";
|
|
3030
|
+
var todoListCommand = new Command45("ls").description("List todos with filters").option("-p, --project <value>", "Filter by project. Required. Unknown, cross-organization, or soft-deleted project ids return NOT_FOUND.").option("--user-id <value>", "user_id").option("--parent-id <value>", "parent_id").option("-s, --status <value>", "status").option("--include-deleted <value>", "include_deleted").option("--include-templates <value>", "include_templates").option("--due-after <value>", "due_after").option("--due-before <value>", "due_before").option("--type-id <value>", "type_id").option("--sort-by <value>", "sort_by").option("--order <value>", "order").option("--include-orphan-fields <value>", "include_orphan_fields").option("--limit <value>", "Max todos to return. Clamped to [1, 200]. Default 50 server-side.").option("--cursor <value>", "Opaque pagination cursor returned in `next_cursor` of a previous response.").action(async (opts) => {
|
|
2967
3031
|
const client2 = await loadSdkClient();
|
|
2968
3032
|
const result = await todoList({
|
|
2969
3033
|
client: client2._rawClient,
|
|
@@ -2996,8 +3060,8 @@ var todoListCommand = new Command44("ls").description("List todos with filters")
|
|
|
2996
3060
|
});
|
|
2997
3061
|
|
|
2998
3062
|
// src/generated/cli/todo/type/ls.ts
|
|
2999
|
-
import { Command as
|
|
3000
|
-
var todoTypeListCommand = new
|
|
3063
|
+
import { Command as Command46 } from "commander";
|
|
3064
|
+
var todoTypeListCommand = new Command46("ls").description("List todo types").option("--project-id <value>", "Project id filter. Required. Unknown, cross-organization, or soft-deleted project ids return NOT_FOUND.").option("--user-id <value>", "user_id").option("--include-deleted <value>", "include_deleted").action(async (opts) => {
|
|
3001
3065
|
const client2 = await loadSdkClient();
|
|
3002
3066
|
const result = await todoTypeList({
|
|
3003
3067
|
client: client2._rawClient,
|
|
@@ -3019,8 +3083,8 @@ var todoTypeListCommand = new Command45("ls").description("List todo types").opt
|
|
|
3019
3083
|
});
|
|
3020
3084
|
|
|
3021
3085
|
// src/generated/cli/todo/comment/rm.ts
|
|
3022
|
-
import { Command as
|
|
3023
|
-
var todoCommentDeleteCommand = new
|
|
3086
|
+
import { Command as Command47 } from "commander";
|
|
3087
|
+
var todoCommentDeleteCommand = new Command47("rm").description("Soft-delete a comment").argument("<id>", "id").action(async (id, opts) => {
|
|
3024
3088
|
const client2 = await loadSdkClient();
|
|
3025
3089
|
const result = await todoCommentDelete({
|
|
3026
3090
|
client: client2._rawClient,
|
|
@@ -3040,8 +3104,8 @@ var todoCommentDeleteCommand = new Command46("rm").description("Soft-delete a co
|
|
|
3040
3104
|
});
|
|
3041
3105
|
|
|
3042
3106
|
// src/generated/cli/todo/comment/edit.ts
|
|
3043
|
-
import { Command as
|
|
3044
|
-
var todoCommentUpdateCommand = new
|
|
3107
|
+
import { Command as Command48 } from "commander";
|
|
3108
|
+
var todoCommentUpdateCommand = new Command48("edit").description("Edit a comment").argument("<id>", "id").argument("<content>", "content").action(async (id, content, opts) => {
|
|
3045
3109
|
const client2 = await loadSdkClient();
|
|
3046
3110
|
const result = await todoCommentUpdate({
|
|
3047
3111
|
client: client2._rawClient,
|
|
@@ -3063,9 +3127,54 @@ var todoCommentUpdateCommand = new Command47("edit").description("Edit a comment
|
|
|
3063
3127
|
render({ kind: "todo_comment_update", display: { "shape": "object", "format": { "id": "id-short", "todo_id": "id-short", "user_id": "id-short", "created_at": "relative-time", "updated_at": "relative-time", "deleted_at": "relative-time" } } }, result.data);
|
|
3064
3128
|
});
|
|
3065
3129
|
|
|
3130
|
+
// src/generated/cli/todo/rule/rm.ts
|
|
3131
|
+
import { Command as Command49 } from "commander";
|
|
3132
|
+
var recurrenceRuleDeleteCommand = new Command49("rm").description("Delete a recurring todo rule").argument("<id>", "id").option("--expected-version <value>", "expected_version").action(async (id, opts) => {
|
|
3133
|
+
const client2 = await loadSdkClient();
|
|
3134
|
+
const result = await recurrenceRuleDelete({
|
|
3135
|
+
client: client2._rawClient,
|
|
3136
|
+
path: {
|
|
3137
|
+
id
|
|
3138
|
+
},
|
|
3139
|
+
body: {
|
|
3140
|
+
expected_version: opts.expectedVersion
|
|
3141
|
+
}
|
|
3142
|
+
});
|
|
3143
|
+
if (result.error || !result.response?.ok) {
|
|
3144
|
+
process.stderr.write(
|
|
3145
|
+
`HTTP ${result.response?.status ?? "?"}: ${JSON.stringify(result.error ?? "unknown error", null, 2)}
|
|
3146
|
+
`
|
|
3147
|
+
);
|
|
3148
|
+
process.exitCode = 1;
|
|
3149
|
+
return;
|
|
3150
|
+
}
|
|
3151
|
+
render({ kind: "recurrence_rule_delete", display: void 0 }, result.data);
|
|
3152
|
+
});
|
|
3153
|
+
|
|
3154
|
+
// src/generated/cli/todo/rule/show.ts
|
|
3155
|
+
import { Command as Command50 } from "commander";
|
|
3156
|
+
var recurrenceRuleGetCommand = new Command50("show").description("Get a recurring todo rule").argument("<id>", "id").action(async (id, opts) => {
|
|
3157
|
+
const client2 = await loadSdkClient();
|
|
3158
|
+
const result = await recurrenceRuleGet({
|
|
3159
|
+
client: client2._rawClient,
|
|
3160
|
+
path: {
|
|
3161
|
+
id
|
|
3162
|
+
}
|
|
3163
|
+
});
|
|
3164
|
+
if (result.error || !result.response?.ok) {
|
|
3165
|
+
process.stderr.write(
|
|
3166
|
+
`HTTP ${result.response?.status ?? "?"}: ${JSON.stringify(result.error ?? "unknown error", null, 2)}
|
|
3167
|
+
`
|
|
3168
|
+
);
|
|
3169
|
+
process.exitCode = 1;
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
render({ kind: "recurrence_rule_get", display: { "shape": "object", "format": { "id": "id-short", "type_id": "id-short" } } }, result.data);
|
|
3173
|
+
});
|
|
3174
|
+
|
|
3066
3175
|
// src/generated/cli/todo/rm.ts
|
|
3067
|
-
import { Command as
|
|
3068
|
-
var todoDeleteCommand = new
|
|
3176
|
+
import { Command as Command51 } from "commander";
|
|
3177
|
+
var todoDeleteCommand = new Command51("rm").description("Soft-delete a todo").argument("<id>", "id").option("--expected-version <value>", "expected_version").option("--cascade <value>", "cascade").action(async (id, opts) => {
|
|
3069
3178
|
const client2 = await loadSdkClient();
|
|
3070
3179
|
const result = await todoDelete({
|
|
3071
3180
|
client: client2._rawClient,
|
|
@@ -3089,8 +3198,8 @@ var todoDeleteCommand = new Command48("rm").description("Soft-delete a todo").ar
|
|
|
3089
3198
|
});
|
|
3090
3199
|
|
|
3091
3200
|
// src/generated/cli/todo/show.ts
|
|
3092
|
-
import { Command as
|
|
3093
|
-
var todoGetCommand = new
|
|
3201
|
+
import { Command as Command52 } from "commander";
|
|
3202
|
+
var todoGetCommand = new Command52("show").description("Get a todo by id").argument("<id>", "id").option("--include-deleted <value>", "include_deleted").option("--include-orphan-fields <value>", "include_orphan_fields").action(async (id, opts) => {
|
|
3094
3203
|
const client2 = await loadSdkClient();
|
|
3095
3204
|
const result = await todoGet({
|
|
3096
3205
|
client: client2._rawClient,
|
|
@@ -3115,8 +3224,8 @@ var todoGetCommand = new Command49("show").description("Get a todo by id").argum
|
|
|
3115
3224
|
});
|
|
3116
3225
|
|
|
3117
3226
|
// src/generated/cli/todo/update.ts
|
|
3118
|
-
import { Command as
|
|
3119
|
-
var todoUpdateCommand = new
|
|
3227
|
+
import { Command as Command53 } from "commander";
|
|
3228
|
+
var todoUpdateCommand = new Command53("update").description("Update a todo").argument("<id>", "id").option("--expected-version <value>", "expected_version").option("--title <value>", "New title. Omit to leave the existing title unchanged. Must be non-empty when supplied.").option("--description <value>", 'New description. Markdown formatted (CommonMark + GFM tables, strikethrough, task lists). Pass empty string `""` explicitly to clear an existing description, or omit to leave unchanged. Passing `null` is strictly rejected.').option("--parent-id <value>", "Re-parent the todo. Pass a valid parent ID to attach under another todo, pass `null` to move it back to the root level, or omit to leave unchanged. Nesting is limited to one level; attempting to set a child todo as a parent will trigger `PARENT_IS_CHILD`.").option("--status <value>", "New status of the todo. Allowed transitions: `open` \u2794 `in_progress` \u2794 `done`. `cancelled` represents a terminal state. Transitioning to `done` automatically emits a `captureTodoCompleted` analytics event. Omit to leave the existing status unchanged.").option("--due-at <value>", 'Update calendar due date in ISO date-only format (`YYYY-MM-DD`). Pass `""` explicitly to clear an existing due date, or omit to leave it unchanged. Passing `null` is strictly rejected.').option("--type-id <value>", "Re-assign this todo to a different active type. The new type must belong to the todo's same project; otherwise the request fails with TYPE_PROJECT_MISMATCH. New server-generated type ids use typ_<ULID>; legacy ids remain accepted.").option("--custom-fields <value>", "PATCH semantics: only the keys present in this map change. Pass `null` for a key (e.g. `custom_fields: { priority: null }`) to explicitly delete that custom field value. Array values are replaced wholesale with no element-level diff. Providing a key that is not declared on the effective todo type is rejected with `UNDECLARED_FIELD`.").option("--user-id <value>", "Reassign the owner (assignee) user ID of this todo. Target user must belong to the same organization.").action(async (id, opts) => {
|
|
3120
3229
|
const client2 = await loadSdkClient();
|
|
3121
3230
|
const result = await todoUpdate({
|
|
3122
3231
|
client: client2._rawClient,
|
|
@@ -3131,7 +3240,7 @@ var todoUpdateCommand = new Command50("update").description("Update a todo").arg
|
|
|
3131
3240
|
status: opts.status,
|
|
3132
3241
|
due_at: opts.dueAt,
|
|
3133
3242
|
type_id: opts.typeId,
|
|
3134
|
-
custom_fields: opts.customFields,
|
|
3243
|
+
custom_fields: parseJsonField(opts.customFields, "custom-fields"),
|
|
3135
3244
|
user_id: opts.userId
|
|
3136
3245
|
}
|
|
3137
3246
|
});
|
|
@@ -3206,7 +3315,10 @@ function registerGeneratedCommands(root) {
|
|
|
3206
3315
|
root_todo_project.addCommand(projectCreateCommand);
|
|
3207
3316
|
root_todo_project.addCommand(projectListCommand);
|
|
3208
3317
|
const root_todo_rule = root_todo.command("rule").description("rule commands");
|
|
3318
|
+
root_todo_rule.addCommand(recurrenceRuleCreateCommand);
|
|
3209
3319
|
root_todo_rule.addCommand(recurrenceRuleListCommand);
|
|
3320
|
+
root_todo_rule.addCommand(recurrenceRuleDeleteCommand);
|
|
3321
|
+
root_todo_rule.addCommand(recurrenceRuleGetCommand);
|
|
3210
3322
|
root_todo.addCommand(todoCreateCommand);
|
|
3211
3323
|
root_todo.addCommand(todoListCommand);
|
|
3212
3324
|
const root_todo_type = root_todo.command("type").description("type commands");
|
|
@@ -3217,7 +3329,7 @@ function registerGeneratedCommands(root) {
|
|
|
3217
3329
|
}
|
|
3218
3330
|
|
|
3219
3331
|
// src/handwritten/commands/login.ts
|
|
3220
|
-
import { Command as
|
|
3332
|
+
import { Command as Command54 } from "commander";
|
|
3221
3333
|
|
|
3222
3334
|
// src/handwritten/auth/device-flow.ts
|
|
3223
3335
|
var DEFAULT_SLEEP = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -3396,9 +3508,18 @@ async function runLogin(opts) {
|
|
|
3396
3508
|
}
|
|
3397
3509
|
|
|
3398
3510
|
// src/handwritten/commands/login.ts
|
|
3399
|
-
|
|
3511
|
+
function resolveLoginTarget(opts, env) {
|
|
3512
|
+
const baseUrl = opts.apiBase ?? env.WSPC_API_BASE ?? API_BASE;
|
|
3513
|
+
const envName = opts.env ?? (baseUrl === API_BASE ? "prod" : "local");
|
|
3514
|
+
return { baseUrl, envName };
|
|
3515
|
+
}
|
|
3516
|
+
function wantsJson(opts, env) {
|
|
3517
|
+
return opts.json === true || env.WSPC_OUTPUT === "json";
|
|
3518
|
+
}
|
|
3519
|
+
var loginCommand = new Command54("login").description("Log in via OAuth device flow (default) or API key").option("--api-key <key>", "Log in with a wspc API key (escape hatch)").option("--api-base <url>", "Target API base URL (default: production)").option("--env <name>", "Config env name to store credentials under").option("--json", "Emit machine-readable events to stdout").action(async (opts) => {
|
|
3400
3520
|
const store = new ConfigStore();
|
|
3401
|
-
const
|
|
3521
|
+
const { baseUrl, envName } = resolveLoginTarget(opts, process.env);
|
|
3522
|
+
const output = wantsJson(opts, process.env) ? { write: () => {
|
|
3402
3523
|
}, writeJson: (e) => process.stdout.write(JSON.stringify(e) + "\n") } : {
|
|
3403
3524
|
write: (s) => process.stdout.write(s + "\n"),
|
|
3404
3525
|
writeJson: () => {
|
|
@@ -3406,14 +3527,15 @@ var loginCommand = new Command51("login").description("Log in via OAuth device f
|
|
|
3406
3527
|
};
|
|
3407
3528
|
await runLogin({
|
|
3408
3529
|
store,
|
|
3409
|
-
baseUrl
|
|
3530
|
+
baseUrl,
|
|
3531
|
+
envName,
|
|
3410
3532
|
apiKey: opts.apiKey,
|
|
3411
3533
|
output
|
|
3412
3534
|
});
|
|
3413
3535
|
});
|
|
3414
3536
|
|
|
3415
3537
|
// src/handwritten/commands/logout.ts
|
|
3416
|
-
import { Command as
|
|
3538
|
+
import { Command as Command55 } from "commander";
|
|
3417
3539
|
|
|
3418
3540
|
// src/handwritten/auth/logout.ts
|
|
3419
3541
|
async function runLogout(opts) {
|
|
@@ -3441,7 +3563,7 @@ async function runLogout(opts) {
|
|
|
3441
3563
|
}
|
|
3442
3564
|
|
|
3443
3565
|
// src/handwritten/commands/logout.ts
|
|
3444
|
-
var logoutCommand = new
|
|
3566
|
+
var logoutCommand = new Command55("logout").description("Log out an account (default: the active account in the current env)").argument("[email]", "Email of the account to log out").option("--all", "Log out every account in the current env").action(async (email, opts) => {
|
|
3445
3567
|
const res = await runLogout({ store: new ConfigStore(), email, all: opts.all });
|
|
3446
3568
|
if (res.removed.length === 0) {
|
|
3447
3569
|
process.stdout.write("nothing to log out\n");
|
|
@@ -3454,7 +3576,7 @@ var logoutCommand = new Command52("logout").description("Log out an account (def
|
|
|
3454
3576
|
});
|
|
3455
3577
|
|
|
3456
3578
|
// src/handwritten/commands/whoami.ts
|
|
3457
|
-
import { Command as
|
|
3579
|
+
import { Command as Command56 } from "commander";
|
|
3458
3580
|
var ENV_DISPLAY = {
|
|
3459
3581
|
shape: "object",
|
|
3460
3582
|
fields: ["name", "api_base", "account", "actor", "agent_label"]
|
|
@@ -3486,7 +3608,7 @@ async function backfillActiveEmail(store, envName, email, userId) {
|
|
|
3486
3608
|
await store.write(cfg);
|
|
3487
3609
|
}
|
|
3488
3610
|
}
|
|
3489
|
-
var whoamiCommand = new
|
|
3611
|
+
var whoamiCommand = new Command56("whoami").description("Show the active env, signed-in account, and organization").action(async () => {
|
|
3490
3612
|
const store = new ConfigStore();
|
|
3491
3613
|
const config = await store.read();
|
|
3492
3614
|
let resolved;
|
|
@@ -3539,8 +3661,8 @@ function printLoggedOut() {
|
|
|
3539
3661
|
}
|
|
3540
3662
|
|
|
3541
3663
|
// src/handwritten/commands/config.ts
|
|
3542
|
-
import { Command as
|
|
3543
|
-
var configCommand = new
|
|
3664
|
+
import { Command as Command57 } from "commander";
|
|
3665
|
+
var configCommand = new Command57("config").description("Manage wspc local config");
|
|
3544
3666
|
registerRenderer("config_show", (data) => {
|
|
3545
3667
|
const d = data;
|
|
3546
3668
|
if (d.envs.length === 0) {
|
|
@@ -3611,7 +3733,7 @@ configCommand.command("use <env>").description("Switch current_env").action(asyn
|
|
|
3611
3733
|
});
|
|
3612
3734
|
|
|
3613
3735
|
// src/handwritten/commands/account.ts
|
|
3614
|
-
import { Command as
|
|
3736
|
+
import { Command as Command58 } from "commander";
|
|
3615
3737
|
async function listAccounts(store) {
|
|
3616
3738
|
const c = await store.read();
|
|
3617
3739
|
const envName = c.current_env;
|
|
@@ -3652,7 +3774,7 @@ registerRenderer("account_ls", (data) => {
|
|
|
3652
3774
|
]);
|
|
3653
3775
|
process.stdout.write(table(headers, body));
|
|
3654
3776
|
});
|
|
3655
|
-
var accountCommand = new
|
|
3777
|
+
var accountCommand = new Command58("account").description("Manage logged-in accounts");
|
|
3656
3778
|
accountCommand.command("ls").description("List accounts in the current env (active marked with \u2713)").action(async () => {
|
|
3657
3779
|
const accounts = await listAccounts(new ConfigStore());
|
|
3658
3780
|
render({ kind: "account_ls" }, { accounts });
|
|
@@ -3664,7 +3786,7 @@ accountCommand.command("switch <email>").description("Set the active account for
|
|
|
3664
3786
|
});
|
|
3665
3787
|
|
|
3666
3788
|
// src/handwritten/commands/todo-done.ts
|
|
3667
|
-
import { Command as
|
|
3789
|
+
import { Command as Command59 } from "commander";
|
|
3668
3790
|
var TODO_UPDATE_DISPLAY = {
|
|
3669
3791
|
shape: "object",
|
|
3670
3792
|
format: {
|
|
@@ -3682,7 +3804,7 @@ var TODO_UPDATE_DISPLAY = {
|
|
|
3682
3804
|
deleted_at: "relative-time"
|
|
3683
3805
|
}
|
|
3684
3806
|
};
|
|
3685
|
-
var todoDoneCommand = new
|
|
3807
|
+
var todoDoneCommand = new Command59("done").description("Mark a todo done (sugar for `update <id> --status done`)").argument("<id>", "Todo id").action(async (id) => {
|
|
3686
3808
|
const client2 = await loadSdkClient();
|
|
3687
3809
|
const result = await todoUpdate({
|
|
3688
3810
|
client: client2._rawClient,
|
|
@@ -3701,7 +3823,7 @@ var todoDoneCommand = new Command56("done").description("Mark a todo done (sugar
|
|
|
3701
3823
|
});
|
|
3702
3824
|
|
|
3703
3825
|
// src/handwritten/commands/email/send.ts
|
|
3704
|
-
import { Command as
|
|
3826
|
+
import { Command as Command60 } from "commander";
|
|
3705
3827
|
import { readFile, stat } from "fs/promises";
|
|
3706
3828
|
import { basename } from "path";
|
|
3707
3829
|
|
|
@@ -3759,7 +3881,7 @@ async function resolveAttachment(input) {
|
|
|
3759
3881
|
`--attach ${input}: neither a readable file nor a valid <prefix>_<ulid>:<idx> reference.`
|
|
3760
3882
|
);
|
|
3761
3883
|
}
|
|
3762
|
-
var sendCommand = new
|
|
3884
|
+
var sendCommand = new Command60("send").description("Send an outbound email").requiredOption("--from <alias-email>", "alias email to send from").option("--to <addr...>", "recipient address (repeatable)", []).option("--subject <text>", "subject").option("--text <body>", "plain-text body").option("--text-file <path>", "read text body from file").option("--reply <id>", "inbound email id to reply to").option("--attach <path-or-ref...>", "attachment (file path or eml_xxx:idx)", []).requiredOption("--idempotency-key <key>", "idempotency key").action(async (opts) => {
|
|
3763
3885
|
const isReply = Boolean(opts.reply);
|
|
3764
3886
|
const to = opts.to;
|
|
3765
3887
|
const attachInputs = opts.attach;
|
|
@@ -3846,7 +3968,7 @@ var sendCommand = new Command57("send").description("Send an outbound email").re
|
|
|
3846
3968
|
});
|
|
3847
3969
|
|
|
3848
3970
|
// src/handwritten/commands/email/attachment.ts
|
|
3849
|
-
import { Command as
|
|
3971
|
+
import { Command as Command61 } from "commander";
|
|
3850
3972
|
import { createWriteStream } from "fs";
|
|
3851
3973
|
import { Readable } from "stream";
|
|
3852
3974
|
import { pipeline } from "stream/promises";
|
|
@@ -3863,7 +3985,7 @@ function parseContentDispositionFilename(header) {
|
|
|
3863
3985
|
}
|
|
3864
3986
|
|
|
3865
3987
|
// src/handwritten/commands/email/attachment.ts
|
|
3866
|
-
var attachmentCommand = new
|
|
3988
|
+
var attachmentCommand = new Command61("attachment").description("Download an inbound email attachment by index").argument("<email-id>").argument("<idx>").option("--output <path>", "output file path").option("--include-deleted", "allow downloads from soft-deleted parent emails").action(async (emailId, idxArg, opts) => {
|
|
3867
3989
|
const idx = Number(idxArg);
|
|
3868
3990
|
if (!Number.isInteger(idx) || idx < 0) {
|
|
3869
3991
|
process.stderr.write(`<idx> must be a non-negative integer (got "${idxArg}")
|
|
@@ -3896,7 +4018,7 @@ var attachmentCommand = new Command58("attachment").description("Download an inb
|
|
|
3896
4018
|
|
|
3897
4019
|
// src/cli.ts
|
|
3898
4020
|
function buildProgram() {
|
|
3899
|
-
const program = new
|
|
4021
|
+
const program = new Command62().name("wspc").description("Official CLI for wspc.ai").version(`wspc ${VERSION} (spec ${SPEC_SHA}, fetched ${SPEC_FETCHED_AT})`).option("--json", "Output raw JSON (machine-readable)").option("--account <email>", "Run as a specific account (overrides the active account)").hook("preAction", (_thisCommand, actionCommand) => {
|
|
3900
4022
|
const globals = actionCommand.optsWithGlobals();
|
|
3901
4023
|
if (globals.json) process.env.WSPC_OUTPUT = "json";
|
|
3902
4024
|
if (globals.account) process.env.WSPC_ACCOUNT = String(globals.account);
|