@parall/cli 1.43.0 → 1.45.0
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/commands/tasks.d.ts +45 -0
- package/dist/commands/tasks.d.ts.map +1 -1
- package/dist/commands/tasks.js +98 -23
- package/package.json +4 -4
package/dist/commands/tasks.d.ts
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
import type { UpdateTaskRequest } from '@parall/sdk';
|
|
1
2
|
import { Command } from 'commander';
|
|
3
|
+
export declare function buildCreateTaskData(opts: {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
status?: string;
|
|
7
|
+
priority?: string;
|
|
8
|
+
assigneeId?: string;
|
|
9
|
+
projectId?: string;
|
|
10
|
+
parentId?: string;
|
|
11
|
+
sourceChatId?: string;
|
|
12
|
+
dueDate?: string;
|
|
13
|
+
}): Partial<{
|
|
14
|
+
title: string;
|
|
15
|
+
description: string | undefined;
|
|
16
|
+
status: string | undefined;
|
|
17
|
+
priority: string | undefined;
|
|
18
|
+
assignee_id: string | undefined;
|
|
19
|
+
project_id: string | undefined;
|
|
20
|
+
parent_id: string | undefined;
|
|
21
|
+
source_chat_id: string | undefined;
|
|
22
|
+
due_date: string | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function buildUpdateTaskData(opts: {
|
|
25
|
+
title?: string;
|
|
26
|
+
status?: string;
|
|
27
|
+
priority?: string;
|
|
28
|
+
assigneeId?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
projectId?: string;
|
|
31
|
+
parentId?: string;
|
|
32
|
+
sortOrder?: string;
|
|
33
|
+
placement?: string;
|
|
34
|
+
dueDate?: string;
|
|
35
|
+
}): Partial<{
|
|
36
|
+
title: string | undefined;
|
|
37
|
+
status: UpdateTaskRequest["status"];
|
|
38
|
+
priority: UpdateTaskRequest["priority"];
|
|
39
|
+
assignee_id: string | undefined;
|
|
40
|
+
description: string | undefined;
|
|
41
|
+
project_id: string | undefined;
|
|
42
|
+
parent_id: string | undefined;
|
|
43
|
+
sort_order: number | undefined;
|
|
44
|
+
placement: "end" | undefined;
|
|
45
|
+
due_date: string | null | undefined;
|
|
46
|
+
}>;
|
|
2
47
|
export declare function registerTaskCommands(program: Command): void;
|
|
3
48
|
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8DpC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;GAYA;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;YAS0B,iBAAiB,CAAC,QAAQ,CAAC;cACvB,iBAAiB,CAAC,UAAU,CAAC;;;;;;;;GAS3D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAiWpD"}
|
package/dist/commands/tasks.js
CHANGED
|
@@ -4,6 +4,92 @@ import { printJson, printError, printRefHint, stripPrllScheme } from '../lib/out
|
|
|
4
4
|
function stripUndefined(obj) {
|
|
5
5
|
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
|
|
6
6
|
}
|
|
7
|
+
// The CLI is an agent semantic adapter (parall-cli-design.md § Design
|
|
8
|
+
// Principles): it owns the agent-facing command grammar and rejects values
|
|
9
|
+
// outside it before any request, so local coercion can never turn invalid
|
|
10
|
+
// intent into a successful no-op. The server independently re-validates and
|
|
11
|
+
// stays authoritative for domain semantics (calendar validity, placement
|
|
12
|
+
// set, ordering conflicts, permissions).
|
|
13
|
+
/** Strict command grammar for --due-date; calendar validity (e.g. 2026-02-30)
|
|
14
|
+
* stays the server's domain (400 INVALID_DUE_DATE). */
|
|
15
|
+
const DUE_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
16
|
+
function resolveCreateDueDate(value) {
|
|
17
|
+
if (value === undefined)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (!DUE_DATE_RE.test(value)) {
|
|
20
|
+
throw new Error('--due-date must be a YYYY-MM-DD date');
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
/** Update grammar adds the lowercase "none" sentinel — the agent-facing
|
|
25
|
+
* clear intent, mapped to an explicit null on the wire. */
|
|
26
|
+
function resolveUpdateDueDate(value) {
|
|
27
|
+
if (value === undefined)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (value === 'none')
|
|
30
|
+
return null;
|
|
31
|
+
if (!DUE_DATE_RE.test(value)) {
|
|
32
|
+
throw new Error('--due-date must be a YYYY-MM-DD date, or "none" to clear it');
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
/** Only intents the CLI understands are accepted — a new placement value is a
|
|
37
|
+
* coordinated server + SDK + CLI + skill change, not a passthrough. The
|
|
38
|
+
* server's INVALID_PLACEMENT check remains the backstop for non-CLI callers. */
|
|
39
|
+
function resolvePlacement(value) {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
return undefined;
|
|
42
|
+
if (value !== 'end') {
|
|
43
|
+
throw new Error('--placement must be "end"');
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
/** Number('abc') is NaN and JSON.stringify(NaN) is null — without this guard
|
|
48
|
+
* a malformed --sort-order becomes sort_order:null, which the server treats
|
|
49
|
+
* as "field absent" and answers 200 without moving the task. */
|
|
50
|
+
function resolveSortOrder(value) {
|
|
51
|
+
if (value === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
const trimmed = value.trim();
|
|
54
|
+
const parsed = trimmed === '' ? Number.NaN : Number(trimmed);
|
|
55
|
+
if (!Number.isFinite(parsed)) {
|
|
56
|
+
throw new Error('--sort-order must be a finite number');
|
|
57
|
+
}
|
|
58
|
+
return parsed;
|
|
59
|
+
}
|
|
60
|
+
export function buildCreateTaskData(opts) {
|
|
61
|
+
return stripUndefined({
|
|
62
|
+
title: opts.title,
|
|
63
|
+
description: opts.description,
|
|
64
|
+
status: opts.status,
|
|
65
|
+
priority: opts.priority,
|
|
66
|
+
assignee_id: opts.assigneeId ? stripPrllScheme(opts.assigneeId) : undefined,
|
|
67
|
+
project_id: opts.projectId ? stripPrllScheme(opts.projectId) : undefined,
|
|
68
|
+
parent_id: opts.parentId ? stripPrllScheme(opts.parentId) : undefined,
|
|
69
|
+
source_chat_id: opts.sourceChatId ? stripPrllScheme(opts.sourceChatId) : undefined,
|
|
70
|
+
due_date: resolveCreateDueDate(opts.dueDate),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
export function buildUpdateTaskData(opts) {
|
|
74
|
+
// Mutually exclusive (the server also rejects the pair with 400
|
|
75
|
+
// CONFLICTING_SORT); fail fast client-side so an agent doesn't spend a
|
|
76
|
+
// request round-trip to find out.
|
|
77
|
+
if (opts.placement !== undefined && opts.sortOrder !== undefined) {
|
|
78
|
+
throw new Error('--placement and --sort-order are mutually exclusive. Provide only one.');
|
|
79
|
+
}
|
|
80
|
+
return stripUndefined({
|
|
81
|
+
title: opts.title,
|
|
82
|
+
status: opts.status,
|
|
83
|
+
priority: opts.priority,
|
|
84
|
+
assignee_id: opts.assigneeId ? stripPrllScheme(opts.assigneeId) : undefined,
|
|
85
|
+
description: opts.description,
|
|
86
|
+
project_id: opts.projectId ? stripPrllScheme(opts.projectId) : undefined,
|
|
87
|
+
parent_id: opts.parentId ? stripPrllScheme(opts.parentId) : undefined,
|
|
88
|
+
sort_order: resolveSortOrder(opts.sortOrder),
|
|
89
|
+
placement: resolvePlacement(opts.placement),
|
|
90
|
+
due_date: resolveUpdateDueDate(opts.dueDate),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
7
93
|
export function registerTaskCommands(program) {
|
|
8
94
|
const tasks = program.command('tasks').description('Manage tasks');
|
|
9
95
|
tasks
|
|
@@ -50,19 +136,13 @@ export function registerTaskCommands(program) {
|
|
|
50
136
|
.option('--project-id <id>', 'Project ID')
|
|
51
137
|
.option('--parent-id <id>', 'Parent task ID')
|
|
52
138
|
.option('--source-chat-id <id>', 'Source chat ID')
|
|
139
|
+
.option('--due-date <date>', 'Planned completion date (YYYY-MM-DD)')
|
|
53
140
|
.action(async (opts) => {
|
|
54
141
|
try {
|
|
142
|
+
// Grammar first: an invalid option is a parameter error even when
|
|
143
|
+
// credentials are absent, and it must never reach the wire.
|
|
144
|
+
const data = buildCreateTaskData(opts);
|
|
55
145
|
const { client, orgId } = resolveCredentials();
|
|
56
|
-
const data = stripUndefined({
|
|
57
|
-
title: opts.title,
|
|
58
|
-
description: opts.description,
|
|
59
|
-
status: opts.status,
|
|
60
|
-
priority: opts.priority,
|
|
61
|
-
assignee_id: opts.assigneeId ? stripPrllScheme(opts.assigneeId) : undefined,
|
|
62
|
-
project_id: opts.projectId ? stripPrllScheme(opts.projectId) : undefined,
|
|
63
|
-
parent_id: opts.parentId ? stripPrllScheme(opts.parentId) : undefined,
|
|
64
|
-
source_chat_id: opts.sourceChatId ? stripPrllScheme(opts.sourceChatId) : undefined,
|
|
65
|
-
});
|
|
66
146
|
const result = await client.createTask(orgId, data);
|
|
67
147
|
printJson(result);
|
|
68
148
|
printRefHint(result.id);
|
|
@@ -96,24 +176,19 @@ export function registerTaskCommands(program) {
|
|
|
96
176
|
.option('--description <text>', 'Task description')
|
|
97
177
|
.option('--project-id <id>', 'Project ID')
|
|
98
178
|
.option('--parent-id <id>', 'Parent task ID')
|
|
99
|
-
.option('--sort-order <n>', '
|
|
179
|
+
.option('--sort-order <n>', 'Explicit sort_order value — only for pinpoint insertion relative to cards you can see; to append to a status column use --placement end')
|
|
180
|
+
.option('--placement <where>', 'Ordering intent — only "end" is accepted: appends the task to the end of its status column, position resolved by the server (mutually exclusive with --sort-order)')
|
|
181
|
+
.option('--due-date <date>', 'Planned completion date (YYYY-MM-DD), or "none" to clear it')
|
|
100
182
|
.action(async (taskId, opts) => {
|
|
101
183
|
try {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const data =
|
|
105
|
-
title: opts.title,
|
|
106
|
-
status: opts.status,
|
|
107
|
-
priority: opts.priority,
|
|
108
|
-
assignee_id: opts.assigneeId ? stripPrllScheme(opts.assigneeId) : undefined,
|
|
109
|
-
description: opts.description,
|
|
110
|
-
project_id: opts.projectId ? stripPrllScheme(opts.projectId) : undefined,
|
|
111
|
-
parent_id: opts.parentId ? stripPrllScheme(opts.parentId) : undefined,
|
|
112
|
-
sort_order: opts.sortOrder !== undefined ? Number(opts.sortOrder) : undefined,
|
|
113
|
-
});
|
|
184
|
+
// Grammar first: an invalid option is a parameter error even when
|
|
185
|
+
// credentials are absent, and it must never reach the wire.
|
|
186
|
+
const data = buildUpdateTaskData(opts);
|
|
114
187
|
if (Object.keys(data).length === 0) {
|
|
115
188
|
printError(new Error('No fields to update. Provide at least one option.'));
|
|
116
189
|
}
|
|
190
|
+
taskId = stripPrllScheme(taskId);
|
|
191
|
+
const { client, orgId } = resolveCredentials();
|
|
117
192
|
// Typed dispatch binding: when this turn is a typed dispatch about
|
|
118
193
|
// exactly this task, the update rides the claimed typed lane; the
|
|
119
194
|
// first update also carries the canonical task_update:<dsp> effect
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.0",
|
|
4
4
|
"description": "CLI client for Parall — universal agent & human access to Parall API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"diff": "^8.0.3",
|
|
37
37
|
"js-yaml": "^4.1.0",
|
|
38
38
|
"zod": "^4.3.6",
|
|
39
|
-
"@parall/agent-core": "1.
|
|
40
|
-
"@parall/sdk": "1.
|
|
39
|
+
"@parall/agent-core": "1.45.0",
|
|
40
|
+
"@parall/sdk": "1.45.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/js-yaml": "^4.0.9",
|
|
44
44
|
"@types/node": "^22.0.0",
|
|
45
45
|
"typescript": "^5.7.0",
|
|
46
|
-
"@parall/agent-core": "1.
|
|
46
|
+
"@parall/agent-core": "1.45.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsc",
|