chatroom-cli 1.13.3 → 1.14.1
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/index.js +164 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12552,7 +12552,7 @@ async function createDefaultDeps8() {
|
|
|
12552
12552
|
}
|
|
12553
12553
|
async function handoff(chatroomId, options, deps) {
|
|
12554
12554
|
const d = deps ?? await createDefaultDeps8();
|
|
12555
|
-
const { role, message, nextRole, attachedArtifactIds = [] } = options;
|
|
12555
|
+
const { role, message, nextRole, attachedArtifactIds = [], attachedWorkflowKeys = [] } = options;
|
|
12556
12556
|
const sessionId = d.session.getSessionId();
|
|
12557
12557
|
if (!sessionId) {
|
|
12558
12558
|
const otherUrls = d.session.getOtherSessionUrls();
|
|
@@ -12582,6 +12582,22 @@ async function handoff(chatroomId, options, deps) {
|
|
|
12582
12582
|
process.exit(1);
|
|
12583
12583
|
}
|
|
12584
12584
|
}
|
|
12585
|
+
const resolvedWorkflowIds = [];
|
|
12586
|
+
if (attachedWorkflowKeys.length > 0) {
|
|
12587
|
+
for (const key of attachedWorkflowKeys) {
|
|
12588
|
+
try {
|
|
12589
|
+
const result2 = await d.backend.query(api.workflows.resolveWorkflowId, {
|
|
12590
|
+
sessionId,
|
|
12591
|
+
chatroomId,
|
|
12592
|
+
workflowKey: key
|
|
12593
|
+
});
|
|
12594
|
+
resolvedWorkflowIds.push(result2.workflowId);
|
|
12595
|
+
} catch {
|
|
12596
|
+
formatError(`Workflow "${key}" not found`, ["Check the workflow key and try again"]);
|
|
12597
|
+
process.exit(1);
|
|
12598
|
+
}
|
|
12599
|
+
}
|
|
12600
|
+
}
|
|
12585
12601
|
let result;
|
|
12586
12602
|
try {
|
|
12587
12603
|
result = await d.backend.mutation(api.messages.handoff, {
|
|
@@ -12592,6 +12608,9 @@ async function handoff(chatroomId, options, deps) {
|
|
|
12592
12608
|
targetRole: nextRole,
|
|
12593
12609
|
...attachedArtifactIds.length > 0 && {
|
|
12594
12610
|
attachedArtifactIds
|
|
12611
|
+
},
|
|
12612
|
+
...resolvedWorkflowIds.length > 0 && {
|
|
12613
|
+
attachedWorkflowIds: resolvedWorkflowIds
|
|
12595
12614
|
}
|
|
12596
12615
|
});
|
|
12597
12616
|
} catch (error) {
|
|
@@ -12665,6 +12684,32 @@ ${error instanceof Error ? error.message : String(error)}`);
|
|
|
12665
12684
|
console.log(` • ${id}`);
|
|
12666
12685
|
});
|
|
12667
12686
|
}
|
|
12687
|
+
if (resolvedWorkflowIds.length > 0) {
|
|
12688
|
+
for (const wfId of resolvedWorkflowIds) {
|
|
12689
|
+
try {
|
|
12690
|
+
const detail = await d.backend.query(api.workflows.getWorkflowDetail, {
|
|
12691
|
+
sessionId,
|
|
12692
|
+
chatroomId,
|
|
12693
|
+
workflowId: wfId
|
|
12694
|
+
});
|
|
12695
|
+
const wf = detail.workflow;
|
|
12696
|
+
console.log("");
|
|
12697
|
+
console.log(`\uD83D\uDCCA Attached Workflow: ${wf.workflowKey} (${wf.status}, ${detail.steps.length} steps)`);
|
|
12698
|
+
for (let i2 = 0;i2 < detail.steps.length; i2++) {
|
|
12699
|
+
const step = detail.steps[i2];
|
|
12700
|
+
const isLast = i2 === detail.steps.length - 1;
|
|
12701
|
+
const prefix = isLast ? "└─" : "├─";
|
|
12702
|
+
const statusEmoji = step.status === "completed" ? "✅" : step.status === "in_progress" ? "\uD83D\uDD04" : step.status === "cancelled" ? "❌" : "⏳";
|
|
12703
|
+
const roleLabel = step.assigneeRole ? ` [${step.assigneeRole}]` : "";
|
|
12704
|
+
const deps2 = step.dependsOn.length > 0 ? ` (depends: ${step.dependsOn.join(", ")})` : "";
|
|
12705
|
+
console.log(` ${prefix} ${step.stepKey}${roleLabel} ${statusEmoji} ${step.status}${deps2}`);
|
|
12706
|
+
}
|
|
12707
|
+
console.log("");
|
|
12708
|
+
console.log(` Inspect: chatroom workflow status --chatroom-id=${chatroomId} --workflow-key=${wf.workflowKey}`);
|
|
12709
|
+
console.log(` View step: chatroom workflow step-view --chatroom-id=${chatroomId} --workflow-key=${wf.workflowKey} --step-key=<key>`);
|
|
12710
|
+
} catch {}
|
|
12711
|
+
}
|
|
12712
|
+
}
|
|
12668
12713
|
const convexUrl = d.session.getConvexUrl();
|
|
12669
12714
|
const cliEnvPrefix = getCliEnvPrefix(convexUrl);
|
|
12670
12715
|
console.log(`
|
|
@@ -13428,14 +13473,14 @@ var init_file_content = () => {};
|
|
|
13428
13473
|
// src/commands/workflow/index.ts
|
|
13429
13474
|
var exports_workflow = {};
|
|
13430
13475
|
__export(exports_workflow, {
|
|
13476
|
+
viewStep: () => viewStep,
|
|
13431
13477
|
specifyWorkflowStep: () => specifyWorkflowStep,
|
|
13432
13478
|
parseSections: () => parseSections,
|
|
13433
13479
|
getWorkflowStatus: () => getWorkflowStatus,
|
|
13434
13480
|
exitWorkflow: () => exitWorkflow,
|
|
13435
13481
|
executeWorkflow: () => executeWorkflow,
|
|
13436
13482
|
createWorkflow: () => createWorkflow,
|
|
13437
|
-
completeStep: () => completeStep
|
|
13438
|
-
cancelStep: () => cancelStep
|
|
13483
|
+
completeStep: () => completeStep
|
|
13439
13484
|
});
|
|
13440
13485
|
async function createDefaultDeps11() {
|
|
13441
13486
|
const client2 = await getConvexClient();
|
|
@@ -13612,10 +13657,11 @@ async function specifyWorkflowStep(chatroomId, options, deps) {
|
|
|
13612
13657
|
const d = deps ?? await createDefaultDeps11();
|
|
13613
13658
|
const sessionId = requireAuth3(d);
|
|
13614
13659
|
validateChatroomId2(chatroomId);
|
|
13615
|
-
const sections = parseSections(options.stdinContent, ["GOAL", "REQUIREMENTS"], ["WARNINGS"]);
|
|
13660
|
+
const sections = parseSections(options.stdinContent, ["GOAL", "REQUIREMENTS"], ["WARNINGS", "SKILLS"]);
|
|
13616
13661
|
const goal = sections.get("GOAL");
|
|
13617
13662
|
const requirements = sections.get("REQUIREMENTS");
|
|
13618
13663
|
const warnings = sections.get("WARNINGS") || undefined;
|
|
13664
|
+
const skills = sections.get("SKILLS") || undefined;
|
|
13619
13665
|
try {
|
|
13620
13666
|
await d.backend.mutation(api.workflows.specifyStep, {
|
|
13621
13667
|
sessionId,
|
|
@@ -13625,7 +13671,8 @@ async function specifyWorkflowStep(chatroomId, options, deps) {
|
|
|
13625
13671
|
assigneeRole: options.assigneeRole,
|
|
13626
13672
|
goal,
|
|
13627
13673
|
requirements,
|
|
13628
|
-
warnings
|
|
13674
|
+
warnings,
|
|
13675
|
+
skills
|
|
13629
13676
|
});
|
|
13630
13677
|
console.log("");
|
|
13631
13678
|
console.log("✅ Step specified");
|
|
@@ -13732,6 +13779,9 @@ async function getWorkflowStatus(chatroomId, options, deps) {
|
|
|
13732
13779
|
if (spec.goal) {
|
|
13733
13780
|
console.log(` \uD83D\uDCCE Goal: ${spec.goal}`);
|
|
13734
13781
|
}
|
|
13782
|
+
if (spec.skills) {
|
|
13783
|
+
console.log(` \uD83D\uDD27 Skills: ${spec.skills}`);
|
|
13784
|
+
}
|
|
13735
13785
|
if (spec.requirements) {
|
|
13736
13786
|
console.log(` \uD83D\uDCCE Requirements: ${spec.requirements}`);
|
|
13737
13787
|
}
|
|
@@ -13787,58 +13837,118 @@ async function completeStep(chatroomId, options, deps) {
|
|
|
13787
13837
|
return;
|
|
13788
13838
|
}
|
|
13789
13839
|
}
|
|
13790
|
-
async function
|
|
13840
|
+
async function exitWorkflow(chatroomId, options, deps) {
|
|
13791
13841
|
const d = deps ?? await createDefaultDeps11();
|
|
13792
13842
|
const sessionId = requireAuth3(d);
|
|
13793
13843
|
validateChatroomId2(chatroomId);
|
|
13794
13844
|
if (!options.reason || options.reason.trim().length === 0) {
|
|
13795
|
-
console.error("❌ Reason is required when
|
|
13845
|
+
console.error("❌ Reason is required when exiting a workflow");
|
|
13796
13846
|
process.exit(1);
|
|
13797
13847
|
return;
|
|
13798
13848
|
}
|
|
13799
13849
|
try {
|
|
13800
|
-
await d.backend.mutation(api.workflows.
|
|
13850
|
+
await d.backend.mutation(api.workflows.exitWorkflow, {
|
|
13801
13851
|
sessionId,
|
|
13802
13852
|
chatroomId,
|
|
13803
13853
|
workflowKey: options.workflowKey,
|
|
13804
|
-
stepKey: options.stepKey,
|
|
13805
13854
|
reason: options.reason.trim()
|
|
13806
13855
|
});
|
|
13807
13856
|
console.log("");
|
|
13808
|
-
console.log("❌
|
|
13809
|
-
console.log(`
|
|
13810
|
-
console.log(` Step: ${options.stepKey}`);
|
|
13857
|
+
console.log("❌ Workflow exited (cancelled)");
|
|
13858
|
+
console.log(` Key: ${options.workflowKey}`);
|
|
13811
13859
|
console.log(` Reason: ${options.reason.trim()}`);
|
|
13812
13860
|
console.log("");
|
|
13813
13861
|
} catch (error) {
|
|
13814
|
-
console.error(`❌ Failed to
|
|
13862
|
+
console.error(`❌ Failed to exit workflow: ${error.message}`);
|
|
13815
13863
|
process.exit(1);
|
|
13816
13864
|
return;
|
|
13817
13865
|
}
|
|
13818
13866
|
}
|
|
13819
|
-
async function
|
|
13867
|
+
async function viewStep(chatroomId, options, deps) {
|
|
13820
13868
|
const d = deps ?? await createDefaultDeps11();
|
|
13821
13869
|
const sessionId = requireAuth3(d);
|
|
13822
13870
|
validateChatroomId2(chatroomId);
|
|
13823
|
-
if (!options.reason || options.reason.trim().length === 0) {
|
|
13824
|
-
console.error("❌ Reason is required when exiting a workflow");
|
|
13825
|
-
process.exit(1);
|
|
13826
|
-
return;
|
|
13827
|
-
}
|
|
13828
13871
|
try {
|
|
13829
|
-
await d.backend.
|
|
13872
|
+
const result = await d.backend.query(api.workflows.getStepView, {
|
|
13830
13873
|
sessionId,
|
|
13831
13874
|
chatroomId,
|
|
13832
13875
|
workflowKey: options.workflowKey,
|
|
13833
|
-
|
|
13876
|
+
stepKey: options.stepKey
|
|
13834
13877
|
});
|
|
13878
|
+
const step = result.step;
|
|
13879
|
+
const emoji = getStepStatusEmoji(step.status);
|
|
13835
13880
|
console.log("");
|
|
13836
|
-
console.log("
|
|
13837
|
-
console.log(
|
|
13838
|
-
console.log(
|
|
13881
|
+
console.log("══════════════════════════════════════════════════");
|
|
13882
|
+
console.log(`${emoji} STEP: ${step.stepKey}`);
|
|
13883
|
+
console.log("══════════════════════════════════════════════════");
|
|
13884
|
+
console.log(`Workflow: ${result.workflowKey} (${result.workflowStatus})`);
|
|
13885
|
+
console.log(`Description: ${step.description}`);
|
|
13886
|
+
console.log(`Status: ${step.status.toUpperCase()}`);
|
|
13887
|
+
if (step.assigneeRole) {
|
|
13888
|
+
console.log(`Assignee: ${step.assigneeRole}`);
|
|
13889
|
+
}
|
|
13890
|
+
if (step.dependsOn.length > 0) {
|
|
13891
|
+
console.log(`Dependencies: ${step.dependsOn.join(", ")}`);
|
|
13892
|
+
}
|
|
13893
|
+
console.log(`Order: ${step.order}`);
|
|
13894
|
+
if (step.completedAt) {
|
|
13895
|
+
const completedDate = new Date(step.completedAt).toLocaleString("en-US", {
|
|
13896
|
+
month: "short",
|
|
13897
|
+
day: "numeric",
|
|
13898
|
+
hour: "2-digit",
|
|
13899
|
+
minute: "2-digit",
|
|
13900
|
+
hour12: false
|
|
13901
|
+
});
|
|
13902
|
+
console.log(`Completed: ${completedDate}`);
|
|
13903
|
+
}
|
|
13904
|
+
if (step.cancelledAt) {
|
|
13905
|
+
const cancelledDate = new Date(step.cancelledAt).toLocaleString("en-US", {
|
|
13906
|
+
month: "short",
|
|
13907
|
+
day: "numeric",
|
|
13908
|
+
hour: "2-digit",
|
|
13909
|
+
minute: "2-digit",
|
|
13910
|
+
hour12: false
|
|
13911
|
+
});
|
|
13912
|
+
console.log(`Cancelled: ${cancelledDate}`);
|
|
13913
|
+
if (step.cancelReason) {
|
|
13914
|
+
console.log(`Cancel reason: ${step.cancelReason}`);
|
|
13915
|
+
}
|
|
13916
|
+
}
|
|
13917
|
+
if (step.specification) {
|
|
13918
|
+
const spec = step.specification;
|
|
13919
|
+
console.log("");
|
|
13920
|
+
console.log("──────────────────────────────────────────────────");
|
|
13921
|
+
console.log("\uD83D\uDCCB SPECIFICATION");
|
|
13922
|
+
console.log("──────────────────────────────────────────────────");
|
|
13923
|
+
if (spec.goal) {
|
|
13924
|
+
console.log("");
|
|
13925
|
+
console.log("Goal:");
|
|
13926
|
+
console.log(spec.goal);
|
|
13927
|
+
}
|
|
13928
|
+
if (spec.skills) {
|
|
13929
|
+
console.log("");
|
|
13930
|
+
console.log("Skills:");
|
|
13931
|
+
console.log(spec.skills);
|
|
13932
|
+
}
|
|
13933
|
+
if (spec.requirements) {
|
|
13934
|
+
console.log("");
|
|
13935
|
+
console.log("Requirements:");
|
|
13936
|
+
console.log(spec.requirements);
|
|
13937
|
+
}
|
|
13938
|
+
if (spec.warnings) {
|
|
13939
|
+
console.log("");
|
|
13940
|
+
console.log("⚠️ Warnings:");
|
|
13941
|
+
console.log(spec.warnings);
|
|
13942
|
+
}
|
|
13943
|
+
} else {
|
|
13944
|
+
console.log("");
|
|
13945
|
+
console.log("⚠️ No specification set. Run `workflow specify` to add one.");
|
|
13946
|
+
}
|
|
13947
|
+
console.log("");
|
|
13948
|
+
console.log("══════════════════════════════════════════════════");
|
|
13839
13949
|
console.log("");
|
|
13840
13950
|
} catch (error) {
|
|
13841
|
-
console.error(`❌ Failed to
|
|
13951
|
+
console.error(`❌ Failed to view step: ${error.message}`);
|
|
13842
13952
|
process.exit(1);
|
|
13843
13953
|
return;
|
|
13844
13954
|
}
|
|
@@ -15850,9 +15960,7 @@ var init_crash_loop_tracker = __esm(() => {
|
|
|
15850
15960
|
});
|
|
15851
15961
|
|
|
15852
15962
|
// src/infrastructure/machine/stop-reason.ts
|
|
15853
|
-
function resolveStopReason(code2, signal
|
|
15854
|
-
if (wasIntentional)
|
|
15855
|
-
return "user.stop";
|
|
15963
|
+
function resolveStopReason(code2, signal) {
|
|
15856
15964
|
if (signal !== null)
|
|
15857
15965
|
return "agent_process.signal";
|
|
15858
15966
|
if (code2 === 0)
|
|
@@ -15868,7 +15976,6 @@ function agentKey2(chatroomId, role) {
|
|
|
15868
15976
|
class AgentProcessManager {
|
|
15869
15977
|
deps;
|
|
15870
15978
|
slots = new Map;
|
|
15871
|
-
pendingStopReasons = new Map;
|
|
15872
15979
|
constructor(deps) {
|
|
15873
15980
|
this.deps = deps;
|
|
15874
15981
|
}
|
|
@@ -15923,7 +16030,6 @@ class AgentProcessManager {
|
|
|
15923
16030
|
slot.pendingOperation = undefined;
|
|
15924
16031
|
return { success: true };
|
|
15925
16032
|
}
|
|
15926
|
-
this.pendingStopReasons.set(key, opts.reason);
|
|
15927
16033
|
slot.state = "stopping";
|
|
15928
16034
|
const operation = this.doStop(key, slot, pid, opts);
|
|
15929
16035
|
slot.pendingOperation = operation;
|
|
@@ -15939,9 +16045,7 @@ class AgentProcessManager {
|
|
|
15939
16045
|
if (slot.state === "stopping") {
|
|
15940
16046
|
return;
|
|
15941
16047
|
}
|
|
15942
|
-
const
|
|
15943
|
-
this.pendingStopReasons.delete(key);
|
|
15944
|
-
const stopReason = intentionalReason ?? resolveStopReason(opts.code, opts.signal, false);
|
|
16048
|
+
const stopReason = resolveStopReason(opts.code, opts.signal);
|
|
15945
16049
|
this.deps.spawning.recordExit(opts.chatroomId);
|
|
15946
16050
|
const harness = slot.harness;
|
|
15947
16051
|
const model = slot.model;
|
|
@@ -17305,6 +17409,8 @@ program2.command("classify").description("Classify a task's origin message (entr
|
|
|
17305
17409
|
});
|
|
17306
17410
|
program2.command("handoff").description("Complete your task and hand off to the next role").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Role to hand off to").option("--attach-artifact <artifactId>", "Attach artifact to handoff (can be used multiple times)", (value, previous) => {
|
|
17307
17411
|
return previous ? [...previous, value] : [value];
|
|
17412
|
+
}, []).option("--attachment <type:value>", "Attach a resource (can be used multiple times). Format: type:value. Supported: workflow-key:<key>", (value, previous) => {
|
|
17413
|
+
return previous ? [...previous, value] : [value];
|
|
17308
17414
|
}, []).action(async (options) => {
|
|
17309
17415
|
await maybeRequireAuth();
|
|
17310
17416
|
const { decode: decode2 } = await Promise.resolve().then(() => exports_decode);
|
|
@@ -17321,12 +17427,29 @@ program2.command("handoff").description("Complete your task and hand off to the
|
|
|
17321
17427
|
console.error("❌ Message is empty");
|
|
17322
17428
|
process.exit(1);
|
|
17323
17429
|
}
|
|
17430
|
+
const attachedWorkflowKeys = [];
|
|
17431
|
+
for (const att of options.attachment || []) {
|
|
17432
|
+
const colonIndex = att.indexOf(":");
|
|
17433
|
+
if (colonIndex === -1) {
|
|
17434
|
+
console.error(`❌ Invalid attachment format: "${att}". Expected type:value (e.g., workflow-key:my-workflow)`);
|
|
17435
|
+
process.exit(1);
|
|
17436
|
+
}
|
|
17437
|
+
const type = att.substring(0, colonIndex);
|
|
17438
|
+
const value = att.substring(colonIndex + 1);
|
|
17439
|
+
if (type === "workflow-key") {
|
|
17440
|
+
attachedWorkflowKeys.push(value);
|
|
17441
|
+
} else {
|
|
17442
|
+
console.error(`❌ Unknown attachment type: "${type}". Supported: workflow-key`);
|
|
17443
|
+
process.exit(1);
|
|
17444
|
+
}
|
|
17445
|
+
}
|
|
17324
17446
|
const { handoff: handoff2 } = await Promise.resolve().then(() => (init_handoff(), exports_handoff));
|
|
17325
17447
|
await handoff2(options.chatroomId, {
|
|
17326
17448
|
role: options.role,
|
|
17327
17449
|
message,
|
|
17328
17450
|
nextRole: options.nextRole,
|
|
17329
|
-
attachedArtifactIds: options.attachArtifact || []
|
|
17451
|
+
attachedArtifactIds: options.attachArtifact || [],
|
|
17452
|
+
attachedWorkflowKeys
|
|
17330
17453
|
});
|
|
17331
17454
|
});
|
|
17332
17455
|
program2.command("report-progress").description("Report progress on current task (does not complete the task)").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").action(async (options) => {
|
|
@@ -17512,31 +17635,26 @@ workflowCommand.command("step-complete").description("Mark a workflow step as co
|
|
|
17512
17635
|
stepKey: options.stepKey
|
|
17513
17636
|
});
|
|
17514
17637
|
});
|
|
17515
|
-
workflowCommand.command("
|
|
17638
|
+
workflowCommand.command("exit").description("Exit (cancel) an entire workflow with a reason").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--workflow-key <key>", "Workflow key to exit").requiredOption("--reason <text>", "Reason for exiting the workflow (required)").action(async (options) => {
|
|
17516
17639
|
await maybeRequireAuth();
|
|
17517
17640
|
if (!options.reason || options.reason.trim().length === 0) {
|
|
17518
17641
|
console.error("❌ --reason is required and cannot be empty");
|
|
17519
17642
|
process.exit(1);
|
|
17520
17643
|
}
|
|
17521
|
-
const {
|
|
17522
|
-
await
|
|
17644
|
+
const { exitWorkflow: exitWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
|
|
17645
|
+
await exitWorkflow2(options.chatroomId, {
|
|
17523
17646
|
role: options.role,
|
|
17524
17647
|
workflowKey: options.workflowKey,
|
|
17525
|
-
stepKey: options.stepKey,
|
|
17526
17648
|
reason: options.reason
|
|
17527
17649
|
});
|
|
17528
17650
|
});
|
|
17529
|
-
workflowCommand.command("
|
|
17651
|
+
workflowCommand.command("step-view").description("View the full details and specification of a single workflow step").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--workflow-key <key>", "Workflow key").requiredOption("--step-key <stepKey>", "Step key to view").action(async (options) => {
|
|
17530
17652
|
await maybeRequireAuth();
|
|
17531
|
-
|
|
17532
|
-
|
|
17533
|
-
process.exit(1);
|
|
17534
|
-
}
|
|
17535
|
-
const { exitWorkflow: exitWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
|
|
17536
|
-
await exitWorkflow2(options.chatroomId, {
|
|
17653
|
+
const { viewStep: viewStep2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
|
|
17654
|
+
await viewStep2(options.chatroomId, {
|
|
17537
17655
|
role: options.role,
|
|
17538
17656
|
workflowKey: options.workflowKey,
|
|
17539
|
-
|
|
17657
|
+
stepKey: options.stepKey
|
|
17540
17658
|
});
|
|
17541
17659
|
});
|
|
17542
17660
|
var taskCommand = program2.command("task").description("Manage tasks");
|