@ordewell/core 0.6.4 → 0.7.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/README.md +1 -1
- package/dist/{IFileSystem-Qj2MWHn_.d.mts → IFileSystem-BnLh-_SK.d.mts} +1 -1
- package/dist/{IFileSystem-DQEKyC6H.d.ts → IFileSystem-DofiRcCo.d.ts} +1 -1
- package/dist/{ModeResolver-rqaY_4Ex.d.mts → ModeResolver-DZzJSdIU.d.mts} +3 -3
- package/dist/{ModeResolver-ByNpC0EP.d.ts → ModeResolver-DkMYf4uS.d.ts} +3 -3
- package/dist/{Task-xqdxugt2.d.mts → Task-BnLxkVQF.d.mts} +414 -22
- package/dist/{Task-xqdxugt2.d.ts → Task-BnLxkVQF.d.ts} +414 -22
- package/dist/{chunk-JRZPSNRO.mjs → chunk-LGQNXPBX.mjs} +10 -2
- package/dist/chunk-LGQNXPBX.mjs.map +1 -0
- package/dist/{chunk-N66ZHFGN.mjs → chunk-OYUSADFM.mjs} +11 -1
- package/dist/chunk-OYUSADFM.mjs.map +1 -0
- package/dist/{chunk-HPNUFBIT.mjs → chunk-V3JHS7AX.mjs} +9 -1
- package/dist/chunk-V3JHS7AX.mjs.map +1 -0
- package/dist/{chunk-I6U3PVHL.mjs → chunk-Y36NIASW.mjs} +255 -32
- package/dist/chunk-Y36NIASW.mjs.map +1 -0
- package/dist/{chunk-M4KXBEFJ.mjs → chunk-ZV5LDNCO.mjs} +44 -43
- package/dist/chunk-ZV5LDNCO.mjs.map +1 -0
- package/dist/index.d.mts +518 -238
- package/dist/index.d.ts +518 -238
- package/dist/index.js +3925 -1568
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3525 -1393
- package/dist/index.mjs.map +1 -1
- package/dist/order-labels.d.mts +16 -2
- package/dist/order-labels.d.ts +16 -2
- package/dist/order-labels.js +12 -2
- package/dist/order-labels.js.map +1 -1
- package/dist/order-labels.mjs +7 -3
- package/dist/{parsing-DDZ1rUYa.d.mts → parsing-B6ctfF80.d.mts} +24 -3
- package/dist/{parsing-COPG8-Ep.d.ts → parsing-ddZXZFP4.d.ts} +24 -3
- package/dist/parsing.d.mts +4 -3
- package/dist/parsing.d.ts +4 -3
- package/dist/parsing.js +42 -41
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +3 -3
- package/dist/{plan-utils-Br8UAoiu.d.ts → plan-utils--kQRzSE-.d.ts} +251 -7
- package/dist/{plan-utils-DMgajMvd.d.mts → plan-utils-CKgNtDwQ.d.mts} +251 -7
- package/dist/plan-utils.d.mts +5 -3
- package/dist/plan-utils.d.ts +5 -3
- package/dist/plan-utils.js +313 -61
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +46 -3
- package/dist/testing.d.mts +26 -5
- package/dist/testing.d.ts +26 -5
- package/dist/testing.js +62 -2
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +62 -4
- package/dist/testing.mjs.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-HPNUFBIT.mjs.map +0 -1
- package/dist/chunk-I6U3PVHL.mjs.map +0 -1
- package/dist/chunk-JRZPSNRO.mjs.map +0 -1
- package/dist/chunk-M4KXBEFJ.mjs.map +0 -1
- package/dist/chunk-N66ZHFGN.mjs.map +0 -1
package/dist/order-labels.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bh as Task } from './Task-BnLxkVQF.mjs';
|
|
2
2
|
import 'child_process';
|
|
3
3
|
import 'events';
|
|
4
|
+
import 'zod/v4';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Parent-scoped dotted order label for a task, e.g. "2.1" for the first subtask
|
|
@@ -13,7 +14,20 @@ declare function taskOrderLabel(task: {
|
|
|
13
14
|
}, parent?: {
|
|
14
15
|
order: number;
|
|
15
16
|
}): string;
|
|
17
|
+
/** How a surface refers to a task in prose: "#2", or "#2.1" for a subtask. */
|
|
18
|
+
declare function taskRef(task: {
|
|
19
|
+
order: number;
|
|
20
|
+
}, parent?: {
|
|
21
|
+
order: number;
|
|
22
|
+
}): string;
|
|
23
|
+
/** A task named in full, as a confirmation or a picker title does: "#2 Deploy". */
|
|
24
|
+
declare function titledTaskRef(task: {
|
|
25
|
+
order: number;
|
|
26
|
+
title: string;
|
|
27
|
+
}, parent?: {
|
|
28
|
+
order: number;
|
|
29
|
+
}): string;
|
|
16
30
|
/** Resolve a dotted label to a task in a plan's top-level task list. */
|
|
17
31
|
declare function resolveOrderLabel(tasks: Task[], label: string): Task | undefined;
|
|
18
32
|
|
|
19
|
-
export { resolveOrderLabel, taskOrderLabel };
|
|
33
|
+
export { resolveOrderLabel, taskOrderLabel, taskRef, titledTaskRef };
|
package/dist/order-labels.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bh as Task } from './Task-BnLxkVQF.js';
|
|
2
2
|
import 'child_process';
|
|
3
3
|
import 'events';
|
|
4
|
+
import 'zod/v4';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Parent-scoped dotted order label for a task, e.g. "2.1" for the first subtask
|
|
@@ -13,7 +14,20 @@ declare function taskOrderLabel(task: {
|
|
|
13
14
|
}, parent?: {
|
|
14
15
|
order: number;
|
|
15
16
|
}): string;
|
|
17
|
+
/** How a surface refers to a task in prose: "#2", or "#2.1" for a subtask. */
|
|
18
|
+
declare function taskRef(task: {
|
|
19
|
+
order: number;
|
|
20
|
+
}, parent?: {
|
|
21
|
+
order: number;
|
|
22
|
+
}): string;
|
|
23
|
+
/** A task named in full, as a confirmation or a picker title does: "#2 Deploy". */
|
|
24
|
+
declare function titledTaskRef(task: {
|
|
25
|
+
order: number;
|
|
26
|
+
title: string;
|
|
27
|
+
}, parent?: {
|
|
28
|
+
order: number;
|
|
29
|
+
}): string;
|
|
16
30
|
/** Resolve a dotted label to a task in a plan's top-level task list. */
|
|
17
31
|
declare function resolveOrderLabel(tasks: Task[], label: string): Task | undefined;
|
|
18
32
|
|
|
19
|
-
export { resolveOrderLabel, taskOrderLabel };
|
|
33
|
+
export { resolveOrderLabel, taskOrderLabel, taskRef, titledTaskRef };
|
package/dist/order-labels.js
CHANGED
|
@@ -21,12 +21,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var order_labels_exports = {};
|
|
22
22
|
__export(order_labels_exports, {
|
|
23
23
|
resolveOrderLabel: () => resolveOrderLabel,
|
|
24
|
-
taskOrderLabel: () => taskOrderLabel
|
|
24
|
+
taskOrderLabel: () => taskOrderLabel,
|
|
25
|
+
taskRef: () => taskRef,
|
|
26
|
+
titledTaskRef: () => titledTaskRef
|
|
25
27
|
});
|
|
26
28
|
module.exports = __toCommonJS(order_labels_exports);
|
|
27
29
|
function taskOrderLabel(task, parent) {
|
|
28
30
|
return parent ? `${parent.order}.${task.order}` : String(task.order);
|
|
29
31
|
}
|
|
32
|
+
function taskRef(task, parent) {
|
|
33
|
+
return `#${taskOrderLabel(task, parent)}`;
|
|
34
|
+
}
|
|
35
|
+
function titledTaskRef(task, parent) {
|
|
36
|
+
return `${taskRef(task, parent)} ${task.title}`;
|
|
37
|
+
}
|
|
30
38
|
function resolveOrderLabel(tasks, label) {
|
|
31
39
|
const parts = label.split(".");
|
|
32
40
|
if (parts.length > 2 || parts.some((p) => !/^\d+$/.test(p))) return void 0;
|
|
@@ -39,6 +47,8 @@ function resolveOrderLabel(tasks, label) {
|
|
|
39
47
|
// Annotate the CommonJS export names for ESM import in node:
|
|
40
48
|
0 && (module.exports = {
|
|
41
49
|
resolveOrderLabel,
|
|
42
|
-
taskOrderLabel
|
|
50
|
+
taskOrderLabel,
|
|
51
|
+
taskRef,
|
|
52
|
+
titledTaskRef
|
|
43
53
|
});
|
|
44
54
|
//# sourceMappingURL=order-labels.js.map
|
package/dist/order-labels.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/order-labels.ts"],"sourcesContent":["import type { Task } from './models/Task';\n\n/**\n * Parent-scoped dotted order label for a task, e.g. \"2.1\" for the first subtask\n * of task 2. Kept in its own module (no Node imports) so a browser-bundled\n * surface — the VS Code webview — can import it via `@ordewell/core/order-labels`\n * without dragging the rest of core in.\n */\nexport function taskOrderLabel(task: { order: number }, parent?: { order: number }): string {\n return parent ? `${parent.order}.${task.order}` : String(task.order);\n}\n\n/** Resolve a dotted label to a task in a plan's top-level task list. */\nexport function resolveOrderLabel(tasks: Task[], label: string): Task | undefined {\n const parts = label.split('.');\n if (parts.length > 2 || parts.some((p) => !/^\\d+$/.test(p))) return undefined;\n const [topOrder, childOrder] = parts.map(Number);\n const top = tasks.find((t) => t.order === topOrder);\n if (!top) return undefined;\n if (childOrder === undefined) return top;\n return top.subtasks.find((s) => s.order === childOrder);\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,SAAS,eAAe,MAAyB,QAAoC;AAC1F,SAAO,SAAS,GAAG,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK;AACrE;AAGO,SAAS,kBAAkB,OAAe,OAAiC;AAChF,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,MAAI,MAAM,SAAS,KAAK,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,EAAG,QAAO;AACpE,QAAM,CAAC,UAAU,UAAU,IAAI,MAAM,IAAI,MAAM;AAC/C,QAAM,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,QAAQ;AAClD,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,eAAe,OAAW,QAAO;AACrC,SAAO,IAAI,SAAS,KAAK,CAAC,MAAM,EAAE,UAAU,UAAU;AACxD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/order-labels.ts"],"sourcesContent":["import type { Task } from './models/Task';\n\n/**\n * Parent-scoped dotted order label for a task, e.g. \"2.1\" for the first subtask\n * of task 2. Kept in its own module (no Node imports) so a browser-bundled\n * surface — the VS Code webview — can import it via `@ordewell/core/order-labels`\n * without dragging the rest of core in.\n */\nexport function taskOrderLabel(task: { order: number }, parent?: { order: number }): string {\n return parent ? `${parent.order}.${task.order}` : String(task.order);\n}\n\n/** How a surface refers to a task in prose: \"#2\", or \"#2.1\" for a subtask. */\nexport function taskRef(task: { order: number }, parent?: { order: number }): string {\n return `#${taskOrderLabel(task, parent)}`;\n}\n\n/** A task named in full, as a confirmation or a picker title does: \"#2 Deploy\". */\nexport function titledTaskRef(task: { order: number; title: string }, parent?: { order: number }): string {\n return `${taskRef(task, parent)} ${task.title}`;\n}\n\n/** Resolve a dotted label to a task in a plan's top-level task list. */\nexport function resolveOrderLabel(tasks: Task[], label: string): Task | undefined {\n const parts = label.split('.');\n if (parts.length > 2 || parts.some((p) => !/^\\d+$/.test(p))) return undefined;\n const [topOrder, childOrder] = parts.map(Number);\n const top = tasks.find((t) => t.order === topOrder);\n if (!top) return undefined;\n if (childOrder === undefined) return top;\n return top.subtasks.find((s) => s.order === childOrder);\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,SAAS,eAAe,MAAyB,QAAoC;AAC1F,SAAO,SAAS,GAAG,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK;AACrE;AAGO,SAAS,QAAQ,MAAyB,QAAoC;AACnF,SAAO,IAAI,eAAe,MAAM,MAAM,CAAC;AACzC;AAGO,SAAS,cAAc,MAAwC,QAAoC;AACxG,SAAO,GAAG,QAAQ,MAAM,MAAM,CAAC,IAAI,KAAK,KAAK;AAC/C;AAGO,SAAS,kBAAkB,OAAe,OAAiC;AAChF,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,MAAI,MAAM,SAAS,KAAK,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,EAAG,QAAO;AACpE,QAAM,CAAC,UAAU,UAAU,IAAI,MAAM,IAAI,MAAM;AAC/C,QAAM,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,QAAQ;AAClD,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,eAAe,OAAW,QAAO;AACrC,SAAO,IAAI,SAAS,KAAK,CAAC,MAAM,EAAE,UAAU,UAAU;AACxD;","names":[]}
|
package/dist/order-labels.mjs
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveOrderLabel,
|
|
3
|
-
taskOrderLabel
|
|
4
|
-
|
|
3
|
+
taskOrderLabel,
|
|
4
|
+
taskRef,
|
|
5
|
+
titledTaskRef
|
|
6
|
+
} from "./chunk-V3JHS7AX.mjs";
|
|
5
7
|
export {
|
|
6
8
|
resolveOrderLabel,
|
|
7
|
-
taskOrderLabel
|
|
9
|
+
taskOrderLabel,
|
|
10
|
+
taskRef,
|
|
11
|
+
titledTaskRef
|
|
8
12
|
};
|
|
9
13
|
//# sourceMappingURL=order-labels.mjs.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { R as RunnerModeInfo } from './ModeResolver-
|
|
1
|
+
import { bh as Task, bJ as ValidationContext, bK as ValidationResult, a$ as RunnerId } from './Task-BnLxkVQF.mjs';
|
|
2
|
+
import { R as RunnerModeInfo } from './ModeResolver-DZzJSdIU.mjs';
|
|
3
3
|
|
|
4
4
|
/** The envelope key a full plan reply is keyed by: `{"tasks":[...]}`. */
|
|
5
5
|
declare const PLAN_ENVELOPE_KEY = "tasks";
|
|
@@ -114,6 +114,27 @@ interface PartialPlanTask {
|
|
|
114
114
|
declare function parsePartialPlan(partial: string): PartialPlanTask[];
|
|
115
115
|
|
|
116
116
|
declare function parsePlanJson(raw: string, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): Task[];
|
|
117
|
+
/** One reason a plan was refused, pinned to the task and field it is about. */
|
|
118
|
+
interface PlanTaskError {
|
|
119
|
+
/** Absent when the envelope itself is wrong rather than one of its tasks. */
|
|
120
|
+
taskId?: string;
|
|
121
|
+
field: string;
|
|
122
|
+
message: string;
|
|
123
|
+
}
|
|
124
|
+
type PlanTasksResult = {
|
|
125
|
+
ok: true;
|
|
126
|
+
tasks: Task[];
|
|
127
|
+
} | {
|
|
128
|
+
ok: false;
|
|
129
|
+
errors: PlanTaskError[];
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Every check a plan's tasks must pass, on an already-parsed `{ tasks }`
|
|
133
|
+
* object — what a plan is held to whichever channel it arrived on. All
|
|
134
|
+
* problems are reported, in the order the text path has always met them, so
|
|
135
|
+
* the first is the one its corrective names.
|
|
136
|
+
*/
|
|
137
|
+
declare function validatePlanTasks(obj: unknown, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): PlanTasksResult;
|
|
117
138
|
/**
|
|
118
139
|
* Whether a reply that failed {@link parsePlanJson} actually LOOKED like a
|
|
119
140
|
* plan attempt — a balanced tasks-keyed object, or JSON that got cut off.
|
|
@@ -128,4 +149,4 @@ declare function checkImmutableLog(ctx: ValidationContext): ValidationResult;
|
|
|
128
149
|
declare function checkInProgress(ctx: ValidationContext): ValidationResult;
|
|
129
150
|
declare function validatePlanModification(ctx: ValidationContext): ValidationResult;
|
|
130
151
|
|
|
131
|
-
export { PLAN_ENVELOPE_KEY as P, TASK_OPS_ENVELOPE_KEY as T, type PartialPlanTask as a, PlanParseError as b,
|
|
152
|
+
export { PLAN_ENVELOPE_KEY as P, TASK_OPS_ENVELOPE_KEY as T, type PartialPlanTask as a, PlanParseError as b, type PlanTaskError as c, type PlanTasksResult as d, TASK_QUERY_ENVELOPE_KEY as e, checkDepsResolve as f, checkImmutableLog as g, checkInProgress as h, checkNoCycles as i, checkUniqueIds as j, escapeControlCharsInStrings as k, extractJsonObject as l, extractObjectWithBalance as m, extractObjectsWithKey as n, looksLikePlanAttempt as o, opensWithJsonObject as p, parsePartialPlan as q, parsePlanJson as r, stripModelNoise as s, stripTrailingCommas as t, validatePlanTasks as u, validatePlanModification as v };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { R as RunnerModeInfo } from './ModeResolver-
|
|
1
|
+
import { bh as Task, bJ as ValidationContext, bK as ValidationResult, a$ as RunnerId } from './Task-BnLxkVQF.js';
|
|
2
|
+
import { R as RunnerModeInfo } from './ModeResolver-DkMYf4uS.js';
|
|
3
3
|
|
|
4
4
|
/** The envelope key a full plan reply is keyed by: `{"tasks":[...]}`. */
|
|
5
5
|
declare const PLAN_ENVELOPE_KEY = "tasks";
|
|
@@ -114,6 +114,27 @@ interface PartialPlanTask {
|
|
|
114
114
|
declare function parsePartialPlan(partial: string): PartialPlanTask[];
|
|
115
115
|
|
|
116
116
|
declare function parsePlanJson(raw: string, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): Task[];
|
|
117
|
+
/** One reason a plan was refused, pinned to the task and field it is about. */
|
|
118
|
+
interface PlanTaskError {
|
|
119
|
+
/** Absent when the envelope itself is wrong rather than one of its tasks. */
|
|
120
|
+
taskId?: string;
|
|
121
|
+
field: string;
|
|
122
|
+
message: string;
|
|
123
|
+
}
|
|
124
|
+
type PlanTasksResult = {
|
|
125
|
+
ok: true;
|
|
126
|
+
tasks: Task[];
|
|
127
|
+
} | {
|
|
128
|
+
ok: false;
|
|
129
|
+
errors: PlanTaskError[];
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Every check a plan's tasks must pass, on an already-parsed `{ tasks }`
|
|
133
|
+
* object — what a plan is held to whichever channel it arrived on. All
|
|
134
|
+
* problems are reported, in the order the text path has always met them, so
|
|
135
|
+
* the first is the one its corrective names.
|
|
136
|
+
*/
|
|
137
|
+
declare function validatePlanTasks(obj: unknown, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): PlanTasksResult;
|
|
117
138
|
/**
|
|
118
139
|
* Whether a reply that failed {@link parsePlanJson} actually LOOKED like a
|
|
119
140
|
* plan attempt — a balanced tasks-keyed object, or JSON that got cut off.
|
|
@@ -128,4 +149,4 @@ declare function checkImmutableLog(ctx: ValidationContext): ValidationResult;
|
|
|
128
149
|
declare function checkInProgress(ctx: ValidationContext): ValidationResult;
|
|
129
150
|
declare function validatePlanModification(ctx: ValidationContext): ValidationResult;
|
|
130
151
|
|
|
131
|
-
export { PLAN_ENVELOPE_KEY as P, TASK_OPS_ENVELOPE_KEY as T, type PartialPlanTask as a, PlanParseError as b,
|
|
152
|
+
export { PLAN_ENVELOPE_KEY as P, TASK_OPS_ENVELOPE_KEY as T, type PartialPlanTask as a, PlanParseError as b, type PlanTaskError as c, type PlanTasksResult as d, TASK_QUERY_ENVELOPE_KEY as e, checkDepsResolve as f, checkImmutableLog as g, checkInProgress as h, checkNoCycles as i, checkUniqueIds as j, escapeControlCharsInStrings as k, extractJsonObject as l, extractObjectWithBalance as m, extractObjectsWithKey as n, looksLikePlanAttempt as o, opensWithJsonObject as p, parsePartialPlan as q, parsePlanJson as r, stripModelNoise as s, stripTrailingCommas as t, validatePlanTasks as u, validatePlanModification as v };
|
package/dist/parsing.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { a as PartialPlanTask, b as PlanParseError,
|
|
2
|
-
import './Task-
|
|
1
|
+
export { a as PartialPlanTask, b as PlanParseError, l as extractJsonObject, q as parsePartialPlan, r as parsePlanJson } from './parsing-B6ctfF80.mjs';
|
|
2
|
+
import './Task-BnLxkVQF.mjs';
|
|
3
3
|
import 'child_process';
|
|
4
4
|
import 'events';
|
|
5
|
-
import '
|
|
5
|
+
import 'zod/v4';
|
|
6
|
+
import './ModeResolver-DZzJSdIU.mjs';
|
package/dist/parsing.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { a as PartialPlanTask, b as PlanParseError,
|
|
2
|
-
import './Task-
|
|
1
|
+
export { a as PartialPlanTask, b as PlanParseError, l as extractJsonObject, q as parsePartialPlan, r as parsePlanJson } from './parsing-ddZXZFP4.js';
|
|
2
|
+
import './Task-BnLxkVQF.js';
|
|
3
3
|
import 'child_process';
|
|
4
4
|
import 'events';
|
|
5
|
-
import '
|
|
5
|
+
import 'zod/v4';
|
|
6
|
+
import './ModeResolver-DkMYf4uS.js';
|
package/dist/parsing.js
CHANGED
|
@@ -51,9 +51,12 @@ function createTask(overrides = {}) {
|
|
|
51
51
|
autonomy: overrides.autonomy,
|
|
52
52
|
sliceType: overrides.sliceType,
|
|
53
53
|
userStoriesCovered: overrides.userStoriesCovered,
|
|
54
|
-
...overrides.ops
|
|
54
|
+
...opsFlag(overrides.ops, overrides.type) ? { ops: true } : {}
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
function opsFlag(value, type = "ai") {
|
|
58
|
+
return value === true && type === "ai" ? true : void 0;
|
|
59
|
+
}
|
|
57
60
|
|
|
58
61
|
// src/services/JsonExtractor.ts
|
|
59
62
|
var PLAN_ENVELOPE_KEY = "tasks";
|
|
@@ -263,25 +266,37 @@ function parsePlanObject(json, raw, runners, runnerModes, autonomousDefault = tr
|
|
|
263
266
|
const detail = err instanceof Error ? err.message : String(err);
|
|
264
267
|
throw new PlanParseError(`Plan response was not valid JSON: ${detail}`, raw);
|
|
265
268
|
}
|
|
266
|
-
|
|
267
|
-
|
|
269
|
+
const result = validatePlanTasks(parsed, runners, runnerModes, autonomousDefault);
|
|
270
|
+
if (result.ok) return result.tasks;
|
|
271
|
+
const [first] = result.errors;
|
|
272
|
+
throw new PlanParseError(first.message, raw, { semantic: first.taskId !== void 0 });
|
|
273
|
+
}
|
|
274
|
+
function validatePlanTasks(obj, runners, runnerModes, autonomousDefault = true) {
|
|
275
|
+
const rawTasks = isRecord(obj) ? obj.tasks : void 0;
|
|
276
|
+
if (!Array.isArray(rawTasks)) {
|
|
277
|
+
return { ok: false, errors: [{ field: "tasks", message: "Invalid plan: missing tasks array" }] };
|
|
268
278
|
}
|
|
269
|
-
const rawTasks = parsed.tasks;
|
|
270
279
|
if (rawTasks.length === 0) {
|
|
271
|
-
|
|
280
|
+
return { ok: false, errors: [{ field: "tasks", message: "Plan contained no tasks" }] };
|
|
272
281
|
}
|
|
273
|
-
const tasks = rawTasks.map((t) => parseTask(t, runners, runnerModes, autonomousDefault));
|
|
274
|
-
|
|
282
|
+
const tasks = rawTasks.map((t) => parseTask(asRecord(t), runners, runnerModes, autonomousDefault));
|
|
283
|
+
const errors = verticalSliceErrors(tasks);
|
|
275
284
|
for (const t of tasks) {
|
|
276
285
|
if (!runners.includes(t.assignedRunner)) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
{
|
|
281
|
-
);
|
|
286
|
+
errors.push({
|
|
287
|
+
taskId: t.id,
|
|
288
|
+
field: "assignedRunner",
|
|
289
|
+
message: `Task "${t.title}" has invalid assignedRunner "${t.assignedRunner}". Expected one of: ${runners.join(", ")}`
|
|
290
|
+
});
|
|
282
291
|
}
|
|
283
292
|
}
|
|
284
|
-
return tasks;
|
|
293
|
+
return errors.length > 0 ? { ok: false, errors } : { ok: true, tasks };
|
|
294
|
+
}
|
|
295
|
+
function isRecord(value) {
|
|
296
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
297
|
+
}
|
|
298
|
+
function asRecord(value) {
|
|
299
|
+
return isRecord(value) ? value : {};
|
|
285
300
|
}
|
|
286
301
|
function parseTask(raw, runners, runnerModes, autonomousDefault = true, inherited) {
|
|
287
302
|
const assignedRunner = typeof raw.assignedRunner === "string" ? raw.assignedRunner : runners[0] ?? "claude-code";
|
|
@@ -301,12 +316,12 @@ function parseTask(raw, runners, runnerModes, autonomousDefault = true, inherite
|
|
|
301
316
|
// description/title — same fallback TaskOps.applyTaskOps uses for `add`, so
|
|
302
317
|
// a task never silently ends up unschedulable (getReadyTasks requires prompt).
|
|
303
318
|
prompt: raw.prompt ? String(raw.prompt) : description || title || void 0,
|
|
304
|
-
userSteps: Array.isArray(raw.userSteps) ? raw.userSteps.map((s) => ({
|
|
319
|
+
userSteps: Array.isArray(raw.userSteps) ? raw.userSteps.map(asRecord).map((s) => ({
|
|
305
320
|
order: Number(s.order ?? 0),
|
|
306
321
|
instruction: String(s.instruction ?? ""),
|
|
307
322
|
completed: false
|
|
308
323
|
})) : void 0,
|
|
309
|
-
subtasks: Array.isArray(raw.subtasks) ? raw.subtasks.map((s) => parseTask(s, runners, runnerModes, autonomousDefault, { sliceType, autonomy })) : [],
|
|
324
|
+
subtasks: Array.isArray(raw.subtasks) ? raw.subtasks.map((s) => parseTask(asRecord(s), runners, runnerModes, autonomousDefault, { sliceType, autonomy })) : [],
|
|
310
325
|
assignedModel: raw.assignedModel ? {
|
|
311
326
|
modelId: String(raw.assignedModel.modelId ?? ""),
|
|
312
327
|
modelLabel: String(raw.assignedModel.modelLabel ?? ""),
|
|
@@ -323,46 +338,32 @@ function parseTask(raw, runners, runnerModes, autonomousDefault = true, inherite
|
|
|
323
338
|
autonomy,
|
|
324
339
|
sliceType,
|
|
325
340
|
userStoriesCovered: Array.isArray(raw.userStoriesCovered) ? raw.userStoriesCovered.map(String) : void 0,
|
|
326
|
-
// A subtask runs with its parent, so only a top-level
|
|
327
|
-
ops:
|
|
341
|
+
// A subtask runs with its parent, so only a top-level task carries it (ADR-0020).
|
|
342
|
+
ops: inherited ? void 0 : opsFlag(raw.ops)
|
|
328
343
|
});
|
|
329
344
|
}
|
|
330
|
-
function
|
|
345
|
+
function verticalSliceErrors(tasks, parentTitle) {
|
|
331
346
|
const where = (t) => parentTitle ? `subtask "${t.title}" of "${parentTitle}"` : `Task "${t.title}"`;
|
|
332
|
-
const
|
|
347
|
+
const errors = [];
|
|
333
348
|
for (const t of tasks) {
|
|
349
|
+
const fail = (field, message) => errors.push({ taskId: t.id, field, message });
|
|
334
350
|
if (!t.sliceType) {
|
|
335
|
-
|
|
336
|
-
`${where(t)} is missing sliceType. Every task must specify sliceType ("AFK" or "HITL").`,
|
|
337
|
-
raw,
|
|
338
|
-
semantic
|
|
339
|
-
);
|
|
351
|
+
fail("sliceType", `${where(t)} is missing sliceType. Every task must specify sliceType ("AFK" or "HITL").`);
|
|
340
352
|
}
|
|
341
353
|
if (t.type === "ai" && !t.autonomy) {
|
|
342
|
-
|
|
343
|
-
`AI ${where(t)} is missing autonomy. Every AI task must specify autonomy ("AFK" or "HITL").`,
|
|
344
|
-
raw,
|
|
345
|
-
semantic
|
|
346
|
-
);
|
|
354
|
+
fail("autonomy", `AI ${where(t)} is missing autonomy. Every AI task must specify autonomy ("AFK" or "HITL").`);
|
|
347
355
|
}
|
|
348
356
|
if (t.autonomy === "AFK" && t.userSteps && t.userSteps.length > 0) {
|
|
349
|
-
|
|
350
|
-
`${where(t)} has autonomy "AFK" but contains userSteps. AFK tasks must not have user touchpoints.`,
|
|
351
|
-
raw,
|
|
352
|
-
semantic
|
|
353
|
-
);
|
|
357
|
+
fail("userSteps", `${where(t)} has autonomy "AFK" but contains userSteps. AFK tasks must not have user touchpoints.`);
|
|
354
358
|
}
|
|
355
|
-
if (t.type === "user" && t.sliceType !== "HITL") {
|
|
356
|
-
|
|
357
|
-
`User ${where(t)} has sliceType "${t.sliceType}". User tasks must have sliceType "HITL".`,
|
|
358
|
-
raw,
|
|
359
|
-
semantic
|
|
360
|
-
);
|
|
359
|
+
if (t.type === "user" && t.sliceType && t.sliceType !== "HITL") {
|
|
360
|
+
fail("sliceType", `User ${where(t)} has sliceType "${t.sliceType}". User tasks must have sliceType "HITL".`);
|
|
361
361
|
}
|
|
362
362
|
if (t.subtasks.length > 0) {
|
|
363
|
-
|
|
363
|
+
errors.push(...verticalSliceErrors(t.subtasks, t.title));
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
|
+
return errors;
|
|
366
367
|
}
|
|
367
368
|
|
|
368
369
|
// src/services/PartialPlanParser.ts
|