@e0ipso/ai-task-manager 1.36.1 → 1.38.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/README.md +26 -21
- package/dist/cli.js +1 -32
- package/dist/cli.js.map +1 -1
- package/dist/conflict-detector.d.ts.map +1 -1
- package/dist/conflict-detector.js +0 -4
- package/dist/conflict-detector.js.map +1 -1
- package/dist/index.d.ts +3 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -245
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +9 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +14 -0
- package/dist/metadata.js.map +1 -1
- package/dist/types.d.ts +18 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +27 -58
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +93 -219
- package/dist/utils.js.map +1 -1
- package/package.json +4 -2
- package/templates/ai-task-manager/config/TASK_MANAGER.md +3 -3
- package/templates/ai-task-manager/config/hooks/PRE_PHASE.md +6 -26
- package/templates/ai-task-manager/config/hooks/PRE_TASK_ASSIGNMENT.md +6 -24
- package/templates/ai-task-manager/config/templates/PLAN_TEMPLATE.md +1 -1
- package/templates/{assistant → harness}/agents/plan-creator.md +2 -2
- package/templates/harness/skills/task-create-plan/SKILL.md +120 -0
- package/templates/harness/skills/task-create-plan/scripts/find-task-manager-root.cjs +116 -0
- package/templates/harness/skills/task-create-plan/scripts/get-next-plan-id.cjs +214 -0
- package/templates/harness/skills/task-execute-blueprint/SKILL.md +139 -0
- package/templates/harness/skills/task-execute-blueprint/scripts/create-feature-branch.cjs +376 -0
- package/templates/harness/skills/task-execute-blueprint/scripts/find-task-manager-root.cjs +116 -0
- package/templates/harness/skills/task-execute-blueprint/scripts/validate-plan-blueprint.cjs +375 -0
- package/templates/harness/skills/task-execute-task/SKILL.md +195 -0
- package/templates/harness/skills/task-execute-task/scripts/check-task-dependencies.cjs +437 -0
- package/templates/harness/skills/task-execute-task/scripts/find-task-manager-root.cjs +116 -0
- package/templates/harness/skills/task-execute-task/scripts/validate-plan-blueprint.cjs +375 -0
- package/templates/harness/skills/task-full-workflow/SKILL.md +378 -0
- package/templates/harness/skills/task-full-workflow/scripts/create-feature-branch.cjs +376 -0
- package/templates/harness/skills/task-full-workflow/scripts/find-task-manager-root.cjs +116 -0
- package/templates/harness/skills/task-full-workflow/scripts/get-next-plan-id.cjs +214 -0
- package/templates/harness/skills/task-full-workflow/scripts/get-next-task-id.cjs +312 -0
- package/templates/harness/skills/task-full-workflow/scripts/validate-plan-blueprint.cjs +375 -0
- package/templates/harness/skills/task-generate-tasks/SKILL.md +244 -0
- package/templates/harness/skills/task-generate-tasks/scripts/find-task-manager-root.cjs +116 -0
- package/templates/harness/skills/task-generate-tasks/scripts/get-next-task-id.cjs +312 -0
- package/templates/harness/skills/task-generate-tasks/scripts/validate-plan-blueprint.cjs +375 -0
- package/templates/harness/skills/task-refine-plan/SKILL.md +205 -0
- package/templates/harness/skills/task-refine-plan/scripts/find-task-manager-root.cjs +116 -0
- package/templates/harness/skills/task-refine-plan/scripts/validate-plan-blueprint.cjs +375 -0
- package/dist/exec.d.ts +0 -13
- package/dist/exec.d.ts.map +0 -1
- package/dist/exec.js +0 -261
- package/dist/exec.js.map +0 -1
- package/templates/ai-task-manager/config/scripts/check-task-dependencies.cjs +0 -240
- package/templates/ai-task-manager/config/scripts/compose-prompt.cjs +0 -234
- package/templates/ai-task-manager/config/scripts/create-feature-branch.cjs +0 -204
- package/templates/ai-task-manager/config/scripts/extract-task-skills.cjs +0 -84
- package/templates/ai-task-manager/config/scripts/find-root.cjs +0 -10
- package/templates/ai-task-manager/config/scripts/get-next-plan-id.cjs +0 -49
- package/templates/ai-task-manager/config/scripts/get-next-task-id.cjs +0 -81
- package/templates/ai-task-manager/config/scripts/shared-utils.cjs +0 -418
- package/templates/ai-task-manager/config/scripts/validate-plan-blueprint.cjs +0 -138
- package/templates/assistant/commands/tasks/create-plan-auto.md +0 -174
- package/templates/assistant/commands/tasks/create-plan.md +0 -175
- package/templates/assistant/commands/tasks/execute-blueprint.md +0 -233
- package/templates/assistant/commands/tasks/execute-task.md +0 -351
- package/templates/assistant/commands/tasks/fix-broken-tests.md +0 -44
- package/templates/assistant/commands/tasks/full-workflow.md +0 -849
- package/templates/assistant/commands/tasks/generate-tasks.md +0 -348
- package/templates/assistant/commands/tasks/refine-plan-auto.md +0 -172
- package/templates/assistant/commands/tasks/refine-plan.md +0 -163
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-create-plan
|
|
3
|
+
description: Create a new AI Task Manager plan for this repository. Use when the user asks to draft, plan, or scope a new task-manager plan — discovers the local .ai/task-manager root, runs the project's plan hooks, gathers clarifications, allocates the next plan ID, and writes a semantic HTML plan conforming to PLAN_TEMPLATE.html. Do not use for generic brainstorming or work outside the AI Task Manager.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# task-create-plan
|
|
7
|
+
|
|
8
|
+
Drive the end-to-end creation of a new AI Task Manager plan for the user's
|
|
9
|
+
repository. The skill is assistant-agnostic and self-contained: every script
|
|
10
|
+
it invokes lives under this skill's `scripts/` directory and is referenced
|
|
11
|
+
by relative path.
|
|
12
|
+
|
|
13
|
+
## Inputs
|
|
14
|
+
|
|
15
|
+
The user's request supplies the work order. Treat it as the only authoritative
|
|
16
|
+
source of intent. Do not invent answers to clarifying questions — prompt the
|
|
17
|
+
user instead.
|
|
18
|
+
|
|
19
|
+
## Operating Procedure
|
|
20
|
+
|
|
21
|
+
### 1. Locate the task-manager root
|
|
22
|
+
|
|
23
|
+
Run `scripts/find-task-manager-root.cjs` from the user's working directory.
|
|
24
|
+
The script walks up looking for `.ai/task-manager/.init-metadata.json` and
|
|
25
|
+
prints the absolute path of the resolved root on success.
|
|
26
|
+
|
|
27
|
+
If the script exits non-zero, the working directory is not inside an
|
|
28
|
+
initialized task-manager workspace. Stop and ask the user to run the project
|
|
29
|
+
initializer (e.g. `npx @e0ipso/ai-task-manager init`) before continuing. Do
|
|
30
|
+
not attempt to create a plan outside of a valid root.
|
|
31
|
+
|
|
32
|
+
For every subsequent step, treat the path printed by this script as `<root>`.
|
|
33
|
+
|
|
34
|
+
### 2. Load project context
|
|
35
|
+
|
|
36
|
+
Read `<root>/config/TASK_MANAGER.md` for the directory structure conventions
|
|
37
|
+
this project uses. Read `<root>/config/hooks/PRE_PLAN.md` and execute the
|
|
38
|
+
instructions it contains before proceeding. Read
|
|
39
|
+
`<root>/config/templates/PLAN_TEMPLATE.html` so the plan you emit conforms
|
|
40
|
+
to its semantic structure.
|
|
41
|
+
|
|
42
|
+
### 3. Analyze the work order
|
|
43
|
+
|
|
44
|
+
Identify:
|
|
45
|
+
|
|
46
|
+
- Objective and end goal.
|
|
47
|
+
- Scope and explicit boundaries.
|
|
48
|
+
- Success criteria.
|
|
49
|
+
- Dependencies, prerequisites, blockers.
|
|
50
|
+
- Technical requirements and constraints.
|
|
51
|
+
|
|
52
|
+
### 4. Clarification loop
|
|
53
|
+
|
|
54
|
+
If any critical context is missing, ask the user targeted questions. Keep
|
|
55
|
+
looping until you have no further questions. Explicitly confirm whether
|
|
56
|
+
backwards compatibility is required. Never invent answers; never paper over
|
|
57
|
+
a missing answer.
|
|
58
|
+
|
|
59
|
+
If the user declines to clarify a blocking question, stop and report the
|
|
60
|
+
plan as needing clarification. Do not produce a partial plan.
|
|
61
|
+
|
|
62
|
+
### 5. Allocate the next plan ID
|
|
63
|
+
|
|
64
|
+
Run `scripts/get-next-plan-id.cjs` to obtain the next available plan ID.
|
|
65
|
+
Pass `<root>` as the first argument when invoking the script from a working
|
|
66
|
+
directory that is not inside the project, otherwise no argument is required.
|
|
67
|
+
The script prints a single integer.
|
|
68
|
+
|
|
69
|
+
Compute the zero-padded form for directory naming (`{padded-id}--{slug}`)
|
|
70
|
+
and use the unpadded integer in the plan frontmatter and the final summary.
|
|
71
|
+
|
|
72
|
+
### 6. Emit the plan
|
|
73
|
+
|
|
74
|
+
Write the plan to:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
<root>/plans/{padded-id}--{slug}/plan-{padded-id}--{slug}.html
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The output must:
|
|
81
|
+
|
|
82
|
+
- Conform to `<root>/config/templates/PLAN_TEMPLATE.html`, including required
|
|
83
|
+
`<meta>` elements (at minimum `id`, `summary`, `created`) inside `<head>`.
|
|
84
|
+
- Contain the standard sections from the template body.
|
|
85
|
+
- Use semantic HTML, not free-form prose.
|
|
86
|
+
- Avoid time estimates, task lists, or code samples — those belong to the
|
|
87
|
+
later task-generation phase.
|
|
88
|
+
|
|
89
|
+
The `<slug>` is derived from the plan summary: lowercase, alphanumeric and
|
|
90
|
+
hyphens only, collapsed, trimmed.
|
|
91
|
+
|
|
92
|
+
### 7. Run post-plan hook
|
|
93
|
+
|
|
94
|
+
Execute `<root>/config/hooks/POST_PLAN.md` after the plan file is written.
|
|
95
|
+
|
|
96
|
+
### 8. Emit the structured summary
|
|
97
|
+
|
|
98
|
+
Conclude with exactly this block as the final output:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
Plan Summary:
|
|
104
|
+
- Plan ID: [numeric-id]
|
|
105
|
+
- Plan File: [absolute-path-to-plan-file]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The summary is consumed by downstream automation; keep the format exact.
|
|
109
|
+
|
|
110
|
+
## Failure Modes
|
|
111
|
+
|
|
112
|
+
- **No task-manager root found.** Stop, instruct the user to initialize the
|
|
113
|
+
project. Do not write any files.
|
|
114
|
+
- **User refuses to answer a clarifying question that blocks planning.**
|
|
115
|
+
Report `needs-clarification` and stop. Do not produce a plan.
|
|
116
|
+
- **Plan ID script fails.** Re-check the resolved root and re-run. If it
|
|
117
|
+
continues to fail, surface stderr to the user and stop — do not guess an ID.
|
|
118
|
+
- **Plan directory already exists for the allocated ID.** Re-run the
|
|
119
|
+
next-plan-id script (a concurrent run may have advanced it) and retry once.
|
|
120
|
+
If the conflict persists, stop and report.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/skill-scripts/find-task-manager-root.ts
|
|
31
|
+
var find_task_manager_root_exports = {};
|
|
32
|
+
__export(find_task_manager_root_exports, {
|
|
33
|
+
main: () => main
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(find_task_manager_root_exports);
|
|
36
|
+
|
|
37
|
+
// src/skill-scripts/shared/root.ts
|
|
38
|
+
var fs = __toESM(require("fs"));
|
|
39
|
+
var path = __toESM(require("path"));
|
|
40
|
+
var EXPECTED_SCHEMA = true ? 1 : 1;
|
|
41
|
+
var isValidTaskManagerRoot = (taskManagerPath) => {
|
|
42
|
+
try {
|
|
43
|
+
if (!fs.existsSync(taskManagerPath)) return false;
|
|
44
|
+
if (!fs.lstatSync(taskManagerPath).isDirectory()) return false;
|
|
45
|
+
const metadataPath = path.join(taskManagerPath, ".init-metadata.json");
|
|
46
|
+
if (!fs.existsSync(metadataPath)) return false;
|
|
47
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf8"));
|
|
48
|
+
return metadata && typeof metadata === "object" && "version" in metadata;
|
|
49
|
+
} catch (_err) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var getTaskManagerAt = (directory) => {
|
|
54
|
+
const taskManagerPath = path.join(directory, ".ai", "task-manager");
|
|
55
|
+
return isValidTaskManagerRoot(taskManagerPath) ? taskManagerPath : null;
|
|
56
|
+
};
|
|
57
|
+
var getParentPaths = (currentPath, acc = []) => {
|
|
58
|
+
const absolutePath = path.resolve(currentPath);
|
|
59
|
+
const nextAcc = [...acc, absolutePath];
|
|
60
|
+
const parentPath = path.dirname(absolutePath);
|
|
61
|
+
if (parentPath === absolutePath) return nextAcc;
|
|
62
|
+
return getParentPaths(parentPath, nextAcc);
|
|
63
|
+
};
|
|
64
|
+
var checkWorkspaceSchema = (metadataPath) => {
|
|
65
|
+
let metadata;
|
|
66
|
+
try {
|
|
67
|
+
metadata = JSON.parse(fs.readFileSync(metadataPath, "utf8"));
|
|
68
|
+
} catch {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const actual = typeof metadata.workspaceSchemaVersion === "number" ? metadata.workspaceSchemaVersion : 1;
|
|
72
|
+
if (actual === EXPECTED_SCHEMA) return;
|
|
73
|
+
if (actual < EXPECTED_SCHEMA) {
|
|
74
|
+
process.stderr.write(
|
|
75
|
+
`Workspace schema v${actual} is older than this skill requires (v${EXPECTED_SCHEMA}). Re-run \`npx @e0ipso/ai-task-manager init\` with the latest CLI to update.
|
|
76
|
+
`
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
process.stderr.write(
|
|
80
|
+
`This skill (built for workspace schema v${EXPECTED_SCHEMA}) is older than the workspace (v${actual}). Re-run \`npx skills add e0ipso/ai-task-manager\` to update skills.
|
|
81
|
+
`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
process.exit(1);
|
|
85
|
+
};
|
|
86
|
+
var findTaskManagerRoot = (startPath = process.cwd()) => {
|
|
87
|
+
const paths = getParentPaths(startPath);
|
|
88
|
+
const found = paths.find((p) => getTaskManagerAt(p));
|
|
89
|
+
if (!found) return null;
|
|
90
|
+
const root = getTaskManagerAt(found);
|
|
91
|
+
if (root) checkWorkspaceSchema(path.join(root, ".init-metadata.json"));
|
|
92
|
+
return root;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/skill-scripts/find-task-manager-root.ts
|
|
96
|
+
var main = () => {
|
|
97
|
+
const startPath = process.argv[2] || process.cwd();
|
|
98
|
+
const root = findTaskManagerRoot(startPath);
|
|
99
|
+
if (!root) {
|
|
100
|
+
process.stderr.write(
|
|
101
|
+
`Could not find .ai/task-manager root from ${startPath} or any parent directory.
|
|
102
|
+
`
|
|
103
|
+
);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
process.stdout.write(`${root}
|
|
107
|
+
`);
|
|
108
|
+
process.exit(0);
|
|
109
|
+
};
|
|
110
|
+
if (require.main === module) {
|
|
111
|
+
main();
|
|
112
|
+
}
|
|
113
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
114
|
+
0 && (module.exports = {
|
|
115
|
+
main
|
|
116
|
+
});
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/skill-scripts/get-next-plan-id.ts
|
|
31
|
+
var get_next_plan_id_exports = {};
|
|
32
|
+
__export(get_next_plan_id_exports, {
|
|
33
|
+
main: () => main
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(get_next_plan_id_exports);
|
|
36
|
+
|
|
37
|
+
// src/skill-scripts/shared/root.ts
|
|
38
|
+
var fs = __toESM(require("fs"));
|
|
39
|
+
var path = __toESM(require("path"));
|
|
40
|
+
var EXPECTED_SCHEMA = true ? 1 : 1;
|
|
41
|
+
var isValidTaskManagerRoot = (taskManagerPath) => {
|
|
42
|
+
try {
|
|
43
|
+
if (!fs.existsSync(taskManagerPath)) return false;
|
|
44
|
+
if (!fs.lstatSync(taskManagerPath).isDirectory()) return false;
|
|
45
|
+
const metadataPath = path.join(taskManagerPath, ".init-metadata.json");
|
|
46
|
+
if (!fs.existsSync(metadataPath)) return false;
|
|
47
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf8"));
|
|
48
|
+
return metadata && typeof metadata === "object" && "version" in metadata;
|
|
49
|
+
} catch (_err) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var getTaskManagerAt = (directory) => {
|
|
54
|
+
const taskManagerPath = path.join(directory, ".ai", "task-manager");
|
|
55
|
+
return isValidTaskManagerRoot(taskManagerPath) ? taskManagerPath : null;
|
|
56
|
+
};
|
|
57
|
+
var getParentPaths = (currentPath, acc = []) => {
|
|
58
|
+
const absolutePath = path.resolve(currentPath);
|
|
59
|
+
const nextAcc = [...acc, absolutePath];
|
|
60
|
+
const parentPath = path.dirname(absolutePath);
|
|
61
|
+
if (parentPath === absolutePath) return nextAcc;
|
|
62
|
+
return getParentPaths(parentPath, nextAcc);
|
|
63
|
+
};
|
|
64
|
+
var checkWorkspaceSchema = (metadataPath) => {
|
|
65
|
+
let metadata;
|
|
66
|
+
try {
|
|
67
|
+
metadata = JSON.parse(fs.readFileSync(metadataPath, "utf8"));
|
|
68
|
+
} catch {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const actual = typeof metadata.workspaceSchemaVersion === "number" ? metadata.workspaceSchemaVersion : 1;
|
|
72
|
+
if (actual === EXPECTED_SCHEMA) return;
|
|
73
|
+
if (actual < EXPECTED_SCHEMA) {
|
|
74
|
+
process.stderr.write(
|
|
75
|
+
`Workspace schema v${actual} is older than this skill requires (v${EXPECTED_SCHEMA}). Re-run \`npx @e0ipso/ai-task-manager init\` with the latest CLI to update.
|
|
76
|
+
`
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
process.stderr.write(
|
|
80
|
+
`This skill (built for workspace schema v${EXPECTED_SCHEMA}) is older than the workspace (v${actual}). Re-run \`npx skills add e0ipso/ai-task-manager\` to update skills.
|
|
81
|
+
`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
process.exit(1);
|
|
85
|
+
};
|
|
86
|
+
var findTaskManagerRoot = (startPath = process.cwd()) => {
|
|
87
|
+
const paths = getParentPaths(startPath);
|
|
88
|
+
const found = paths.find((p) => getTaskManagerAt(p));
|
|
89
|
+
if (!found) return null;
|
|
90
|
+
const root = getTaskManagerAt(found);
|
|
91
|
+
if (root) checkWorkspaceSchema(path.join(root, ".init-metadata.json"));
|
|
92
|
+
return root;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/skill-scripts/shared/plan-scan.ts
|
|
96
|
+
var fs2 = __toESM(require("fs"));
|
|
97
|
+
var path2 = __toESM(require("path"));
|
|
98
|
+
|
|
99
|
+
// src/skill-scripts/shared/frontmatter.ts
|
|
100
|
+
var ID_PATTERNS = [
|
|
101
|
+
/^\s*["']?id["']?\s*:\s*["']?([+-]?\d+)["']?\s*(?:#.*)?$/im,
|
|
102
|
+
/^\s*id\s*:\s*([+-]?\d+)\s*(?:#.*)?$/im,
|
|
103
|
+
/^\s*["']?id["']?\s*:\s*"([+-]?\d+)"\s*(?:#.*)?$/im,
|
|
104
|
+
/^\s*["']?id["']?\s*:\s*'([+-]?\d+)'\s*(?:#.*)?$/im,
|
|
105
|
+
/^\s*["']id["']\s*:\s*([+-]?\d+)\s*(?:#.*)?$/im,
|
|
106
|
+
/^\s*id\s*:\s*[|>]\s*([+-]?\d+)\s*$/im
|
|
107
|
+
];
|
|
108
|
+
var validateId = (rawId) => {
|
|
109
|
+
const id = parseInt(rawId, 10);
|
|
110
|
+
if (Number.isNaN(id) || id < 0 || id > Number.MAX_SAFE_INTEGER) return null;
|
|
111
|
+
return id;
|
|
112
|
+
};
|
|
113
|
+
var extractIdFromMarkdown = (content) => {
|
|
114
|
+
const frontmatterMatch = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---/);
|
|
115
|
+
if (!frontmatterMatch || !frontmatterMatch[1]) return null;
|
|
116
|
+
const block = frontmatterMatch[1];
|
|
117
|
+
for (const pattern of ID_PATTERNS) {
|
|
118
|
+
const match = block.match(pattern);
|
|
119
|
+
if (match && match[1]) {
|
|
120
|
+
const id = validateId(match[1]);
|
|
121
|
+
if (id !== null) return id;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
};
|
|
126
|
+
var extractIdFromHtml = (content) => {
|
|
127
|
+
const headMatch = content.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
128
|
+
const scope = headMatch && headMatch[1] ? headMatch[1] : content;
|
|
129
|
+
const metaPatterns = [
|
|
130
|
+
/<meta\s+[^>]*name\s*=\s*["']id["'][^>]*content\s*=\s*["']([+-]?\d+)["'][^>]*\/?>/i,
|
|
131
|
+
/<meta\s+[^>]*content\s*=\s*["']([+-]?\d+)["'][^>]*name\s*=\s*["']id["'][^>]*\/?>/i
|
|
132
|
+
];
|
|
133
|
+
for (const pattern of metaPatterns) {
|
|
134
|
+
const match = scope.match(pattern);
|
|
135
|
+
if (match && match[1]) {
|
|
136
|
+
const id = validateId(match[1]);
|
|
137
|
+
if (id !== null) return id;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
};
|
|
142
|
+
var extractPlanId = (content, filePath) => {
|
|
143
|
+
if (filePath.toLowerCase().endsWith(".html")) return extractIdFromHtml(content);
|
|
144
|
+
return extractIdFromMarkdown(content);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/skill-scripts/shared/plan-scan.ts
|
|
148
|
+
var PLAN_EXTENSIONS = [".md", ".html"];
|
|
149
|
+
var scanPlanDir = (planDirPath, dirName, isArchive) => {
|
|
150
|
+
let entries;
|
|
151
|
+
try {
|
|
152
|
+
entries = fs2.readdirSync(planDirPath, { withFileTypes: true });
|
|
153
|
+
} catch (_err) {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
return entries.filter((e) => e.isFile() && PLAN_EXTENSIONS.some((ext) => e.name.endsWith(ext))).flatMap((e) => {
|
|
157
|
+
const filePath = path2.join(planDirPath, e.name);
|
|
158
|
+
try {
|
|
159
|
+
const content = fs2.readFileSync(filePath, "utf8");
|
|
160
|
+
const id = extractPlanId(content, filePath);
|
|
161
|
+
if (id === null) return [];
|
|
162
|
+
return [{ id, file: filePath, dir: planDirPath, isArchive, name: dirName }];
|
|
163
|
+
} catch (_err) {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
var getAllPlans = (taskManagerRoot) => {
|
|
169
|
+
const sources = [
|
|
170
|
+
{ dir: path2.join(taskManagerRoot, "plans"), isArchive: false },
|
|
171
|
+
{ dir: path2.join(taskManagerRoot, "archive"), isArchive: true }
|
|
172
|
+
];
|
|
173
|
+
return sources.flatMap(({ dir, isArchive }) => {
|
|
174
|
+
if (!fs2.existsSync(dir)) return [];
|
|
175
|
+
let entries;
|
|
176
|
+
try {
|
|
177
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
178
|
+
} catch (_err) {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
return entries.filter((e) => e.isDirectory()).flatMap((e) => scanPlanDir(path2.join(dir, e.name), e.name, isArchive));
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
var computeNextPlanId = (taskManagerRoot) => {
|
|
185
|
+
const plans = getAllPlans(taskManagerRoot);
|
|
186
|
+
return plans.reduce((max, p) => Math.max(max, p.id), 0) + 1;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/skill-scripts/get-next-plan-id.ts
|
|
190
|
+
var main = () => {
|
|
191
|
+
const rootArg = process.argv[2];
|
|
192
|
+
let root;
|
|
193
|
+
if (rootArg) {
|
|
194
|
+
root = rootArg;
|
|
195
|
+
} else {
|
|
196
|
+
root = findTaskManagerRoot(process.cwd());
|
|
197
|
+
}
|
|
198
|
+
if (!root) {
|
|
199
|
+
process.stderr.write(
|
|
200
|
+
"No .ai/task-manager root found. Run this from inside an initialized task-manager workspace.\n"
|
|
201
|
+
);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
process.stdout.write(`${computeNextPlanId(root)}
|
|
205
|
+
`);
|
|
206
|
+
process.exit(0);
|
|
207
|
+
};
|
|
208
|
+
if (require.main === module) {
|
|
209
|
+
main();
|
|
210
|
+
}
|
|
211
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
212
|
+
0 && (module.exports = {
|
|
213
|
+
main
|
|
214
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-execute-blueprint
|
|
3
|
+
description: Execute an AI Task Manager plan blueprint for this repository. Use when the user asks to run, implement, or carry out a specific plan ID — discovers the local .ai/task-manager root, resolves the plan, validates or auto-generates tasks and the execution blueprint, optionally creates a feature branch, runs phases with lifecycle hooks, enforces validation gates, appends an execution summary, and archives the completed plan. Do not use for generic development work outside the AI Task Manager.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# task-execute-blueprint
|
|
7
|
+
|
|
8
|
+
Drive the end-to-end execution of an existing AI Task Manager plan blueprint. The skill is assistant-agnostic and self-contained: every script it invokes lives under this skill's `scripts/` directory and is referenced by relative path.
|
|
9
|
+
|
|
10
|
+
## Critical Rules
|
|
11
|
+
|
|
12
|
+
1. **Never skip validation gates** — a phase is not complete until `POST_PHASE.md` succeeds.
|
|
13
|
+
2. **Preserve dependency order** — never execute a task before all of its dependencies are completed.
|
|
14
|
+
3. **Maximize parallelism within each phase** — run all tasks whose dependencies are satisfied simultaneously.
|
|
15
|
+
4. **Fail safely and document everything** — halt on unrecoverable errors, and record all decisions, issues, and outcomes under "Noteworthy Events" in the execution summary.
|
|
16
|
+
|
|
17
|
+
## Inputs
|
|
18
|
+
|
|
19
|
+
The user supplies the numeric plan ID conversationally. Treat it as the only authoritative source of intent. Do not invent answers to clarifying questions — prompt the user instead.
|
|
20
|
+
|
|
21
|
+
## Operating Procedure
|
|
22
|
+
|
|
23
|
+
### 1. Locate the task-manager root
|
|
24
|
+
|
|
25
|
+
Run `scripts/find-task-manager-root.cjs` from the user's working directory. The script walks up looking for `.ai/task-manager/.init-metadata.json` and prints the absolute path of the resolved root on success.
|
|
26
|
+
|
|
27
|
+
If the script exits non-zero, the working directory is not inside an initialized task-manager workspace. Stop and ask the user to run the project initializer (e.g. `npx @e0ipso/ai-task-manager init`) before continuing. Do not attempt to execute a plan outside of a valid root.
|
|
28
|
+
|
|
29
|
+
For every subsequent step, treat the path printed by this script as `<root>`.
|
|
30
|
+
|
|
31
|
+
### 2. Resolve the plan
|
|
32
|
+
|
|
33
|
+
Run `scripts/validate-plan-blueprint.cjs <plan-id> planFile` to obtain the absolute path of the plan file. The same script also accepts these field names (single-field output mode) and exposes them on demand:
|
|
34
|
+
|
|
35
|
+
- `planDir` — absolute path of the plan directory
|
|
36
|
+
- `taskCount` — number of existing task files in that plan's `tasks/`
|
|
37
|
+
- `blueprintExists` — `yes` or `no`
|
|
38
|
+
- `taskManagerRoot` — absolute path of `<root>`
|
|
39
|
+
- `planId` — the resolved numeric plan ID
|
|
40
|
+
|
|
41
|
+
If the script exits non-zero, stop and ask the user to confirm the plan ID. Do not guess a different ID.
|
|
42
|
+
|
|
43
|
+
### 3. Validate tasks and blueprint existence
|
|
44
|
+
|
|
45
|
+
Inspect the `taskCount` and `blueprintExists` values returned by the validation script.
|
|
46
|
+
|
|
47
|
+
### 4. Auto-generate tasks and blueprint if missing
|
|
48
|
+
|
|
49
|
+
If `taskCount` is 0 or `blueprintExists` is `no`:
|
|
50
|
+
|
|
51
|
+
- Notify the user: "Tasks or execution blueprint not found. Generating tasks automatically..."
|
|
52
|
+
- Follow the `task-generate-tasks` skill for this plan ID. Execute its operating procedure in full, including running `POST_TASK_GENERATION_ALL.md` to produce the execution blueprint.
|
|
53
|
+
- After generation completes, re-run `scripts/validate-plan-blueprint.cjs <plan-id> planFile` (and the other fields) to refresh the resolved paths and counts.
|
|
54
|
+
|
|
55
|
+
If generation still leaves the plan without tasks or a blueprint, stop and report failure. Do not attempt execution without a valid blueprint.
|
|
56
|
+
|
|
57
|
+
### 5. Optionally create a feature branch
|
|
58
|
+
|
|
59
|
+
Run `scripts/create-feature-branch.cjs <plan-id>`. The script creates a branch named after the plan and prints the branch name. Continue execution regardless of whether a branch is created (some projects may skip this step).
|
|
60
|
+
|
|
61
|
+
### 6. Load project context and execution blueprint
|
|
62
|
+
|
|
63
|
+
Read these files, in order:
|
|
64
|
+
|
|
65
|
+
- `<root>/config/TASK_MANAGER.md` — directory conventions and project context.
|
|
66
|
+
- The plan document at the path returned by step 2.
|
|
67
|
+
- The plan's Execution Blueprint section — this defines the phase groupings and task dispatch order.
|
|
68
|
+
|
|
69
|
+
### 7. Execute phases in order
|
|
70
|
+
|
|
71
|
+
Use an internal task or todo tracker to monitor progress. For each phase defined in the Execution Blueprint:
|
|
72
|
+
|
|
73
|
+
#### 7a. Phase pre-execution
|
|
74
|
+
Read `<root>/config/hooks/PRE_PHASE.md` and execute its instructions before starting the phase.
|
|
75
|
+
|
|
76
|
+
#### 7b. Task dispatch
|
|
77
|
+
Identify all tasks scheduled for this phase whose dependencies are fully satisfied. Read `<root>/config/hooks/PRE_TASK_EXECUTION.md` and execute its instructions before starting any implementation work.
|
|
78
|
+
|
|
79
|
+
Deploy all selected agents simultaneously using your internal Task tool. Each agent MUST:
|
|
80
|
+
|
|
81
|
+
1. Read and execute `<root>/config/hooks/PRE_TASK_EXECUTION.md` before starting any implementation work.
|
|
82
|
+
2. Execute the task according to its requirements.
|
|
83
|
+
3. Monitor execution progress and capture outputs and artifacts.
|
|
84
|
+
4. Update task status in real-time.
|
|
85
|
+
|
|
86
|
+
Maximize parallelism within each phase. Run every task that is ready at the same time.
|
|
87
|
+
|
|
88
|
+
#### 7c. Phase completion verification
|
|
89
|
+
Ensure every task in the phase has status `completed`. Collect and review all task outputs. Document any issues or exceptions encountered.
|
|
90
|
+
|
|
91
|
+
#### 7d. Phase post-execution
|
|
92
|
+
Read `<root>/config/hooks/POST_PHASE.md` and execute its instructions. Do not proceed to the next phase until this hook succeeds.
|
|
93
|
+
|
|
94
|
+
Update the phase status to `completed` in the plan's Execution Blueprint section.
|
|
95
|
+
|
|
96
|
+
Repeat for the next phase until all phases are complete.
|
|
97
|
+
|
|
98
|
+
### 8. Post-execution validation
|
|
99
|
+
|
|
100
|
+
Read `<root>/config/hooks/POST_EXECUTION.md` and execute its instructions. If validation fails, halt execution. The plan remains in `plans/` for debugging.
|
|
101
|
+
|
|
102
|
+
### 9. Append execution summary
|
|
103
|
+
|
|
104
|
+
Append an execution summary section to the plan document using the format described in `<root>/config/templates/EXECUTION_SUMMARY_TEMPLATE.md`. Populate:
|
|
105
|
+
|
|
106
|
+
- **Status**: Completed Successfully
|
|
107
|
+
- **Completed Date**: current date
|
|
108
|
+
- **Results**: brief summary of deliverables
|
|
109
|
+
- **Noteworthy Events**: all decisions, issues, and outcomes encountered during execution. If none occurred, state "No significant issues encountered."
|
|
110
|
+
- **Necessary follow-ups**: any follow-up actions or optimizations
|
|
111
|
+
|
|
112
|
+
### 10. Archive the plan
|
|
113
|
+
|
|
114
|
+
Move the completed plan directory from `<root>/plans/<plan-folder>` to `<root>/archive/<plan-folder>`.
|
|
115
|
+
|
|
116
|
+
Preserve the entire folder structure (including all tasks and subdirectories) to maintain referential integrity. If the move fails, log the error but do not fail the overall execution — the implementation work is complete.
|
|
117
|
+
|
|
118
|
+
## Failure Modes
|
|
119
|
+
|
|
120
|
+
- **No task-manager root found.** Stop and instruct the user to initialize the project. Do not execute any tasks.
|
|
121
|
+
- **Plan ID does not resolve.** Stop and surface the script's stderr to the user. Do not guess a different ID.
|
|
122
|
+
- **Missing blueprint after auto-generation.** If the `task-generate-tasks` skill fails to produce tasks or a blueprint, stop and report failure. Do not attempt execution without a blueprint.
|
|
123
|
+
- **Hook failure.** If `PRE_PHASE.md`, `POST_PHASE.md`, or `POST_EXECUTION.md` fails, halt execution. The plan remains in `plans/` for debugging and potential re-execution.
|
|
124
|
+
- **Execution errors.** If a task fails, read `<root>/config/hooks/POST_ERROR_DETECTION.md`, document the error in Noteworthy Events, halt the phase, and request user direction before continuing.
|
|
125
|
+
|
|
126
|
+
## Execution Summary
|
|
127
|
+
|
|
128
|
+
Conclude with exactly this block as the final output:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
---
|
|
132
|
+
Execution Summary:
|
|
133
|
+
- Plan ID: [numeric-id]
|
|
134
|
+
- Status: Archived
|
|
135
|
+
- Location: [absolute path to archive directory]
|
|
136
|
+
---
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The summary is consumed by downstream automation; keep the format exact.
|