@workser/cli 0.6.7 → 0.6.8
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/AGENTS.md +15 -6
- package/dist/index.js +91 -27
- package/package.json +1 -1
- package/skills/workser/SKILL.md +3 -0
package/AGENTS.md
CHANGED
|
@@ -100,6 +100,15 @@ workser audio understand "<query>" [--url <u>|--file <p>] [-t <task>] # transcr
|
|
|
100
100
|
|
|
101
101
|
workser ask "<question>" [--type <t>] [--option <o>] # ask the user, WAIT for the answer
|
|
102
102
|
|
|
103
|
+
# Tasks and subtasks (the plan shown in Orbit)
|
|
104
|
+
workser task show [id] # inspect the task and its current plan
|
|
105
|
+
workser task subtask list [taskId] # list the task's subtasks
|
|
106
|
+
workser task subtask add "<title>" --role <role> # add one proposed subtask
|
|
107
|
+
workser task subtask update <id> --role <role> # fix its teammate after creation
|
|
108
|
+
workser task subtask update <id> --title "…" --note "…" --scope <paths...>
|
|
109
|
+
workser task subtask remove <id> # remove it before work starts
|
|
110
|
+
workser task start [id] # starts only an already-approved plan
|
|
111
|
+
|
|
103
112
|
# owner-only (will return owner_only / exit 6 — ask the user to do these in Orbit):
|
|
104
113
|
# project create, project use, env rm, domain set
|
|
105
114
|
```
|
|
@@ -119,12 +128,12 @@ workser doc create "<title>" --markdown <text> | doc update <id> --markdown <tex
|
|
|
119
128
|
already doing and what this project chose on purpose, so you don't re-file work or
|
|
120
129
|
quietly reverse a decision.
|
|
121
130
|
|
|
122
|
-
**A plan with phases goes on
|
|
123
|
-
task
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
131
|
+
**A plan with phases goes on this task's Subtasks list, not the Board.** Use one
|
|
132
|
+
`task subtask add` per phase. If you spot a bad title, role, note, or file scope after
|
|
133
|
+
creation, correct that existing row with `task subtask update <id>`; do not say it is
|
|
134
|
+
locked, create a replacement, or duplicate the plan. Write the plan narrative once
|
|
135
|
+
as `doc create --markdown` with no `--work-item`, and record a real tradeoff with
|
|
136
|
+
`decision create`.
|
|
128
137
|
|
|
129
138
|
**Keep it true as you work.** `board move <id> in-progress` when you pick it up,
|
|
130
139
|
`in-review` when it's ready to look at, `board close <id>` when it's done and
|
package/dist/index.js
CHANGED
|
@@ -8494,15 +8494,33 @@ function collect2(value, previous) {
|
|
|
8494
8494
|
|
|
8495
8495
|
// src/commands/task.ts
|
|
8496
8496
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
8497
|
-
var STATUSES2 = [
|
|
8497
|
+
var STATUSES2 = [
|
|
8498
|
+
"todo",
|
|
8499
|
+
"working",
|
|
8500
|
+
"checking",
|
|
8501
|
+
"ready",
|
|
8502
|
+
"accepted",
|
|
8503
|
+
"archived"
|
|
8504
|
+
];
|
|
8498
8505
|
var ROLES = ["pm", "architect", "web", "api", "automation", "qa"];
|
|
8499
|
-
var KINDS2 = [
|
|
8506
|
+
var KINDS2 = [
|
|
8507
|
+
"data_reports",
|
|
8508
|
+
"web",
|
|
8509
|
+
"mobile",
|
|
8510
|
+
"service",
|
|
8511
|
+
"automation",
|
|
8512
|
+
"docs"
|
|
8513
|
+
];
|
|
8500
8514
|
function registerTask(program3) {
|
|
8501
8515
|
const task = program3.command("task").description("The project's tasks and their subtasks (AI Tech Team)");
|
|
8502
|
-
task.command("list").description("List the board's tasks \u2014 run this before starting anything").option(
|
|
8516
|
+
task.command("list").description("List the board's tasks \u2014 run this before starting anything").option(
|
|
8517
|
+
"--status <value>",
|
|
8518
|
+
`only tasks in this status (${STATUSES2.join(" | ")})`
|
|
8519
|
+
).option("--label <value>", "only tasks carrying this label").option("--limit <n>", "cap the number of tasks returned").action(
|
|
8503
8520
|
action(async ({ ctx, opts }) => {
|
|
8504
8521
|
requireProject(ctx);
|
|
8505
|
-
if (opts.status !== void 0)
|
|
8522
|
+
if (opts.status !== void 0)
|
|
8523
|
+
assertOneOf("--status", opts.status, STATUSES2);
|
|
8506
8524
|
const rows = await api(ctx, "/v1/project-tasks", {
|
|
8507
8525
|
query: {
|
|
8508
8526
|
status: opts.status,
|
|
@@ -8524,7 +8542,10 @@ function registerTask(program3) {
|
|
|
8524
8542
|
).action(
|
|
8525
8543
|
action(async ({ ctx, args }) => {
|
|
8526
8544
|
const id = args[0] || ctx.parentTaskId || resolveTaskId(ctx);
|
|
8527
|
-
const row = await api(
|
|
8545
|
+
const row = await api(
|
|
8546
|
+
ctx,
|
|
8547
|
+
`/v1/project-tasks/${encodeURIComponent(id)}`
|
|
8548
|
+
);
|
|
8528
8549
|
const goalId = row.goal_id;
|
|
8529
8550
|
const goal = goalId ? await api(
|
|
8530
8551
|
ctx,
|
|
@@ -8554,8 +8575,14 @@ function registerTask(program3) {
|
|
|
8554
8575
|
goalId: opts.goal,
|
|
8555
8576
|
phase: opts.phase,
|
|
8556
8577
|
targets: [
|
|
8557
|
-
...(opts.app ?? []).map((appId) => ({
|
|
8558
|
-
|
|
8578
|
+
...(opts.app ?? []).map((appId) => ({
|
|
8579
|
+
kind: "app",
|
|
8580
|
+
appId
|
|
8581
|
+
})),
|
|
8582
|
+
...(opts.infra ?? []).map((ref) => ({
|
|
8583
|
+
kind: "infra",
|
|
8584
|
+
ref
|
|
8585
|
+
}))
|
|
8559
8586
|
],
|
|
8560
8587
|
...hasChannelOrigin ? {
|
|
8561
8588
|
channelId: ctx.projectChannelId,
|
|
@@ -8595,8 +8622,11 @@ function registerTask(program3) {
|
|
|
8595
8622
|
...channelMessageError ? { channelMessageError } : {}
|
|
8596
8623
|
};
|
|
8597
8624
|
ok(result, () => {
|
|
8598
|
-
line(
|
|
8599
|
-
|
|
8625
|
+
line(
|
|
8626
|
+
`${import_picocolors28.default.green("opened")} ${import_picocolors28.default.bold(row.title)} ${import_picocolors28.default.dim(row.key ?? row.id)}`
|
|
8627
|
+
);
|
|
8628
|
+
if (channelMessage)
|
|
8629
|
+
line(import_picocolors28.default.dim("posted to the channel as Project Manager"));
|
|
8600
8630
|
if (channelMessageError) {
|
|
8601
8631
|
warn(
|
|
8602
8632
|
`Task opened, but its Project Manager card could not be posted: ${channelMessageError.message}`
|
|
@@ -8608,10 +8638,19 @@ function registerTask(program3) {
|
|
|
8608
8638
|
const subtask = task.command("subtask").description("The subtasks a task is broken into");
|
|
8609
8639
|
subtask.command("add <title>").description(
|
|
8610
8640
|
'Add one subtask, e.g. `workser task subtask add "Build the upload screen" --role web`'
|
|
8611
|
-
).option(
|
|
8641
|
+
).option(
|
|
8642
|
+
"--task <id>",
|
|
8643
|
+
"the parent task (defaults to the task this run is inside)"
|
|
8644
|
+
).option("--role <value>", `who does it (${ROLES.join(" | ")})`).option("--kind <value>", `what it produces (${KINDS2.join(" | ")})`).option("--note <text>", "one sentence on what this subtask does").option(
|
|
8612
8645
|
"--app <id...>",
|
|
8613
8646
|
"the app this subtask is for \u2014 one id runs it inside that app's folder; leave it off and it runs at the project, seeing every app"
|
|
8614
|
-
).option(
|
|
8647
|
+
).option(
|
|
8648
|
+
"--infra <ref...>",
|
|
8649
|
+
"shared setup it touches (database | storage | auth | hosting | jobs)"
|
|
8650
|
+
).option("--scope <path...>", "files or folders THIS subtask owns").option(
|
|
8651
|
+
"--depends-on <id...>",
|
|
8652
|
+
"subtasks that must finish first (key or id)"
|
|
8653
|
+
).action(
|
|
8615
8654
|
action(async ({ ctx, args, opts }) => {
|
|
8616
8655
|
const parent = resolveTaskId(ctx, opts.task);
|
|
8617
8656
|
if (opts.role !== void 0) assertOneOf("--role", opts.role, ROLES);
|
|
@@ -8627,13 +8666,21 @@ function registerTask(program3) {
|
|
|
8627
8666
|
scopePaths: opts.scope,
|
|
8628
8667
|
dependsOn,
|
|
8629
8668
|
targets: [
|
|
8630
|
-
...(opts.app ?? []).map((appId) => ({
|
|
8631
|
-
|
|
8669
|
+
...(opts.app ?? []).map((appId) => ({
|
|
8670
|
+
kind: "app",
|
|
8671
|
+
appId
|
|
8672
|
+
})),
|
|
8673
|
+
...(opts.infra ?? []).map((ref) => ({
|
|
8674
|
+
kind: "infra",
|
|
8675
|
+
ref
|
|
8676
|
+
}))
|
|
8632
8677
|
]
|
|
8633
8678
|
}
|
|
8634
8679
|
});
|
|
8635
8680
|
ok(row, () => {
|
|
8636
|
-
line(
|
|
8681
|
+
line(
|
|
8682
|
+
`${import_picocolors28.default.green("added")} ${import_picocolors28.default.bold(row.title)} ${import_picocolors28.default.dim(row.key ?? row.id)}`
|
|
8683
|
+
);
|
|
8637
8684
|
if (row.role) line(import_picocolors28.default.dim(`role: ${row.role}`));
|
|
8638
8685
|
});
|
|
8639
8686
|
})
|
|
@@ -8641,7 +8688,10 @@ function registerTask(program3) {
|
|
|
8641
8688
|
subtask.command("list [taskId]").description("The subtasks of a task, in order").action(
|
|
8642
8689
|
action(async ({ ctx, args }) => {
|
|
8643
8690
|
const id = resolveTaskId(ctx, args[0]);
|
|
8644
|
-
const row = await api(
|
|
8691
|
+
const row = await api(
|
|
8692
|
+
ctx,
|
|
8693
|
+
`/v1/project-tasks/${encodeURIComponent(id)}`
|
|
8694
|
+
);
|
|
8645
8695
|
const rows = row.subtasks ?? [];
|
|
8646
8696
|
ok(rows, () => {
|
|
8647
8697
|
if (!rows.length) {
|
|
@@ -8681,7 +8731,9 @@ function registerTask(program3) {
|
|
|
8681
8731
|
ok({ removed: args[0] }, () => line(import_picocolors28.default.green("removed")));
|
|
8682
8732
|
})
|
|
8683
8733
|
);
|
|
8684
|
-
task.command("move <id> <status>").description(
|
|
8734
|
+
task.command("move <id> <status>").description(
|
|
8735
|
+
`Move a task or step along the board (${STATUSES2.join(" | ")})`
|
|
8736
|
+
).action(
|
|
8685
8737
|
action(async ({ ctx, args }) => {
|
|
8686
8738
|
assertOneOf("<status>", args[1], STATUSES2);
|
|
8687
8739
|
const row = await api(
|
|
@@ -8689,7 +8741,10 @@ function registerTask(program3) {
|
|
|
8689
8741
|
`/v1/project-tasks/${encodeURIComponent(args[0])}/move`,
|
|
8690
8742
|
{ body: { status: args[1] } }
|
|
8691
8743
|
);
|
|
8692
|
-
ok(
|
|
8744
|
+
ok(
|
|
8745
|
+
row,
|
|
8746
|
+
() => line(`${import_picocolors28.default.green("moved")} ${import_picocolors28.default.bold(row.title)} \u2192 ${args[1]}`)
|
|
8747
|
+
);
|
|
8693
8748
|
})
|
|
8694
8749
|
);
|
|
8695
8750
|
task.command("resume [id]").description(
|
|
@@ -8740,7 +8795,9 @@ function registerTask(program3) {
|
|
|
8740
8795
|
});
|
|
8741
8796
|
})
|
|
8742
8797
|
);
|
|
8743
|
-
task.command("can-start [id]").description(
|
|
8798
|
+
task.command("can-start [id]").description(
|
|
8799
|
+
"Ask whether work on this task may begin. Refuses until the owner approves."
|
|
8800
|
+
).action(
|
|
8744
8801
|
action(async ({ ctx, args }) => {
|
|
8745
8802
|
const id = resolveTaskId(ctx, args[0]);
|
|
8746
8803
|
const row = await api(
|
|
@@ -8756,11 +8813,9 @@ function registerTask(program3) {
|
|
|
8756
8813
|
).action(
|
|
8757
8814
|
action(async ({ ctx, args }) => {
|
|
8758
8815
|
const id = resolveTaskId(ctx, args[0]);
|
|
8759
|
-
const row = await api(
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
{ method: "POST" }
|
|
8763
|
-
);
|
|
8816
|
+
const row = await api(ctx, `/v1/project-tasks/${encodeURIComponent(id)}/start`, {
|
|
8817
|
+
method: "POST"
|
|
8818
|
+
});
|
|
8764
8819
|
ok(row, () => {
|
|
8765
8820
|
const started = row?.started ?? null;
|
|
8766
8821
|
if (started && started > 0) {
|
|
@@ -8786,7 +8841,9 @@ function registerTask(program3) {
|
|
|
8786
8841
|
);
|
|
8787
8842
|
ok({ awaiting: row2.approval_state === "awaiting", task: row2 }, () => {
|
|
8788
8843
|
line(
|
|
8789
|
-
row2.approval_state === "awaiting" ? import_picocolors28.default.yellow(
|
|
8844
|
+
row2.approval_state === "awaiting" ? import_picocolors28.default.yellow(
|
|
8845
|
+
"The plan is waiting on the owner. They see it in the task."
|
|
8846
|
+
) : `Already ${row2.approval_state}.`
|
|
8790
8847
|
);
|
|
8791
8848
|
});
|
|
8792
8849
|
return;
|
|
@@ -8807,7 +8864,10 @@ function registerTask(program3) {
|
|
|
8807
8864
|
}
|
|
8808
8865
|
}
|
|
8809
8866
|
);
|
|
8810
|
-
ok(
|
|
8867
|
+
ok(
|
|
8868
|
+
row,
|
|
8869
|
+
() => line(`${import_picocolors28.default.green(row.approval_state)} ${import_picocolors28.default.bold(row.title)}`)
|
|
8870
|
+
);
|
|
8811
8871
|
})
|
|
8812
8872
|
);
|
|
8813
8873
|
task.command("done [id]").description("Record what a subtask produced, and move it to ready").option("--summary <text>", "what changed, in the owner's words").action(
|
|
@@ -8936,7 +8996,11 @@ Nothing is running. The next part waiting is "${next.name}" \u2014 offer it to t
|
|
|
8936
8996
|
)
|
|
8937
8997
|
);
|
|
8938
8998
|
} else if (!next) {
|
|
8939
|
-
line(
|
|
8999
|
+
line(
|
|
9000
|
+
import_picocolors28.default.dim(
|
|
9001
|
+
"\nEvery part of this plan is done. Say so, and offer to wrap it up."
|
|
9002
|
+
)
|
|
9003
|
+
);
|
|
8940
9004
|
}
|
|
8941
9005
|
line(
|
|
8942
9006
|
import_picocolors28.default.dim(
|
|
@@ -10791,7 +10855,7 @@ function colour(d) {
|
|
|
10791
10855
|
|
|
10792
10856
|
// src/index.ts
|
|
10793
10857
|
var pkg = {
|
|
10794
|
-
version: true ? "0.6.
|
|
10858
|
+
version: true ? "0.6.8" : "0.0.0-dev"
|
|
10795
10859
|
};
|
|
10796
10860
|
var program2 = new Command();
|
|
10797
10861
|
program2.name("workser").description(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workser/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8",
|
|
4
4
|
"description": "Workser CLI — give your local AI agent native DevOps & infrastructure on Workser. The agent runs `workser …` to provision, deploy, and manage real apps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/skills/workser/SKILL.md
CHANGED
|
@@ -77,6 +77,9 @@ pick or switch it.
|
|
|
77
77
|
3. **A phased plan goes on the subtask list, never the Board.** Phases are
|
|
78
78
|
`workser task subtask add` (`workser help tasks`) — not `board create`,
|
|
79
79
|
which makes a second, driftable "the plan" the task page never reads.
|
|
80
|
+
If a subtask's title, teammate, note, or scope is wrong after creation, fix
|
|
81
|
+
that same row with `workser task subtask update <id> --title … --role …
|
|
82
|
+
--note … --scope …`; never claim it is locked or create a duplicate.
|
|
80
83
|
Write the narrative once as `doc create` (no `--work-item`, or it's hidden
|
|
81
84
|
from the Docs panel), plus `decision create` for a real tradeoff. A plan
|
|
82
85
|
in your reply alone is gone when the conversation scrolls. Details:
|