@joshski/dust 0.1.104 → 0.1.106
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/artifacts/index.d.ts +3 -3
- package/dist/artifacts/workflow-tasks.d.ts +3 -3
- package/dist/artifacts.js +54 -64
- package/dist/dust.js +194 -184
- package/dist/patch/task.d.ts +2 -1
- package/dist/patch.js +25 -27
- package/dist/types.d.ts +1 -1
- package/dist/validation.js +8 -7
- package/package.json +1 -1
|
@@ -5,11 +5,11 @@ import { extractTitle } from '../markdown/markdown-utilities';
|
|
|
5
5
|
import { type Principle } from './principles';
|
|
6
6
|
import { type Task } from './tasks';
|
|
7
7
|
import { type ParsedArtifact, type ParsedMarkdownLink, type ParsedSection, parseArtifact } from './parsed-artifact';
|
|
8
|
-
import { type AllWorkflowTasks, CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllWorkflowTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, parseResolvedQuestions, type TaskType, type WorkflowTaskMatch
|
|
9
|
-
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedArtifact, ParsedCaptureIdeaTask, ParsedIdeaContent, ParsedMarkdownLink, ParsedSection, Principle, Task, TaskType, WorkflowTaskMatch,
|
|
8
|
+
import { type AllWorkflowTasks, CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllWorkflowTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, parseResolvedQuestions, type TaskType, type WorkflowTaskMatch } from './workflow-tasks';
|
|
9
|
+
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedArtifact, ParsedCaptureIdeaTask, ParsedIdeaContent, ParsedMarkdownLink, ParsedSection, Principle, Task, TaskType, WorkflowTaskMatch, };
|
|
10
10
|
export interface TaskGraphNode {
|
|
11
11
|
task: Task;
|
|
12
|
-
workflowType:
|
|
12
|
+
workflowType: TaskType | null;
|
|
13
13
|
}
|
|
14
14
|
export interface TaskGraph {
|
|
15
15
|
nodes: TaskGraphNode[];
|
|
@@ -21,15 +21,15 @@ export interface ParsedCaptureIdeaTask {
|
|
|
21
21
|
* 6. Add .md extension
|
|
22
22
|
*/
|
|
23
23
|
export declare function titleToFilename(title: string): string;
|
|
24
|
-
export
|
|
24
|
+
export declare const VALID_TASK_TYPES: readonly ["implement", "capture", "refine", "decompose", "shelve"];
|
|
25
|
+
export type TaskType = (typeof VALID_TASK_TYPES)[number];
|
|
25
26
|
/**
|
|
26
27
|
* Extracts and validates the task type from the ## Task Type section.
|
|
27
28
|
* Returns the task type if found and valid, null otherwise.
|
|
28
29
|
*/
|
|
29
30
|
export declare function parseTaskType(content: string): TaskType | null;
|
|
30
|
-
export type WorkflowTaskType = 'refine-idea' | 'decompose-idea' | 'shelve-idea' | 'expedite-idea';
|
|
31
31
|
export interface WorkflowTaskMatch {
|
|
32
|
-
type:
|
|
32
|
+
type: TaskType;
|
|
33
33
|
ideaSlug: string;
|
|
34
34
|
taskSlug: string;
|
|
35
35
|
resolvedQuestions: OpenQuestionResponse[];
|
package/dist/artifacts.js
CHANGED
|
@@ -556,39 +556,25 @@ function parseTaskType(content) {
|
|
|
556
556
|
}
|
|
557
557
|
return null;
|
|
558
558
|
}
|
|
559
|
-
function taskTypeToWorkflowType(taskType) {
|
|
560
|
-
switch (taskType) {
|
|
561
|
-
case "refine":
|
|
562
|
-
return "refine-idea";
|
|
563
|
-
case "decompose":
|
|
564
|
-
return "decompose-idea";
|
|
565
|
-
case "shelve":
|
|
566
|
-
return "shelve-idea";
|
|
567
|
-
case "implement":
|
|
568
|
-
return "expedite-idea";
|
|
569
|
-
default:
|
|
570
|
-
return null;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
559
|
var WORKFLOW_HINT_PATHS = {
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
560
|
+
refine: "config/hints/refine-idea.md",
|
|
561
|
+
decompose: "config/hints/decompose-idea.md",
|
|
562
|
+
shelve: "config/hints/shelve-idea.md",
|
|
563
|
+
capture: "config/hints/add-idea.md",
|
|
564
|
+
implement: "config/hints/expedite-idea.md"
|
|
579
565
|
};
|
|
580
|
-
async function readWorkflowHint(fileSystem, dustPath,
|
|
581
|
-
const hintPath = `${dustPath}/${WORKFLOW_HINT_PATHS[
|
|
566
|
+
async function readWorkflowHint(fileSystem, dustPath, taskType) {
|
|
567
|
+
const hintPath = `${dustPath}/${WORKFLOW_HINT_PATHS[taskType]}`;
|
|
582
568
|
if (!fileSystem.exists(hintPath)) {
|
|
583
569
|
return null;
|
|
584
570
|
}
|
|
585
571
|
return fileSystem.readFile(hintPath);
|
|
586
572
|
}
|
|
587
573
|
var WORKFLOW_SECTION_HEADINGS = [
|
|
588
|
-
{ type: "refine
|
|
589
|
-
{ type: "decompose
|
|
590
|
-
{ type: "shelve
|
|
591
|
-
{ type: "
|
|
574
|
+
{ type: "refine", heading: "Refines Idea" },
|
|
575
|
+
{ type: "decompose", heading: "Decomposes Idea" },
|
|
576
|
+
{ type: "shelve", heading: "Shelves Idea" },
|
|
577
|
+
{ type: "implement", heading: "Expedites Idea" }
|
|
592
578
|
];
|
|
593
579
|
function extractIdeaSlugFromSection(content, sectionHeading) {
|
|
594
580
|
const lines = content.split(`
|
|
@@ -663,15 +649,30 @@ async function findAllWorkflowTasks(fileSystem, dustPath) {
|
|
|
663
649
|
});
|
|
664
650
|
}
|
|
665
651
|
}
|
|
666
|
-
|
|
667
|
-
const
|
|
668
|
-
if (
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
652
|
+
if (taskType) {
|
|
653
|
+
const heading = WORKFLOW_SECTION_HEADINGS.find((h) => h.type === taskType)?.heading;
|
|
654
|
+
if (heading) {
|
|
655
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
656
|
+
if (linkedSlug) {
|
|
657
|
+
workflowTasksByIdeaSlug.set(linkedSlug, {
|
|
658
|
+
type: taskType,
|
|
659
|
+
ideaSlug: linkedSlug,
|
|
660
|
+
taskSlug,
|
|
661
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
} else {
|
|
666
|
+
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
667
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
668
|
+
if (linkedSlug) {
|
|
669
|
+
workflowTasksByIdeaSlug.set(linkedSlug, {
|
|
670
|
+
type,
|
|
671
|
+
ideaSlug: linkedSlug,
|
|
672
|
+
taskSlug,
|
|
673
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
674
|
+
});
|
|
675
|
+
}
|
|
675
676
|
}
|
|
676
677
|
}
|
|
677
678
|
}
|
|
@@ -700,11 +701,17 @@ async function findWorkflowTaskForIdea(fileSystem, dustPath, ideaSlug) {
|
|
|
700
701
|
function findWorkflowMatch(content, ideaSlug, taskSlug) {
|
|
701
702
|
const taskType = parseTaskType(content);
|
|
702
703
|
if (taskType) {
|
|
703
|
-
const
|
|
704
|
-
if (
|
|
705
|
-
const
|
|
706
|
-
if (
|
|
707
|
-
return
|
|
704
|
+
const heading = WORKFLOW_SECTION_HEADINGS.find((h) => h.type === taskType)?.heading;
|
|
705
|
+
if (heading) {
|
|
706
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
707
|
+
if (linkedSlug === ideaSlug) {
|
|
708
|
+
return {
|
|
709
|
+
type: taskType,
|
|
710
|
+
ideaSlug,
|
|
711
|
+
taskSlug,
|
|
712
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
713
|
+
};
|
|
714
|
+
}
|
|
708
715
|
}
|
|
709
716
|
}
|
|
710
717
|
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
@@ -720,22 +727,6 @@ function findWorkflowMatch(content, ideaSlug, taskSlug) {
|
|
|
720
727
|
}
|
|
721
728
|
return null;
|
|
722
729
|
}
|
|
723
|
-
function findWorkflowMatchByType(content, ideaSlug, taskSlug, workflowType) {
|
|
724
|
-
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
725
|
-
if (type !== workflowType)
|
|
726
|
-
continue;
|
|
727
|
-
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
728
|
-
if (linkedSlug === ideaSlug) {
|
|
729
|
-
return {
|
|
730
|
-
type: workflowType,
|
|
731
|
-
ideaSlug,
|
|
732
|
-
taskSlug,
|
|
733
|
-
resolvedQuestions: parseResolvedQuestions(content)
|
|
734
|
-
};
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
return null;
|
|
738
|
-
}
|
|
739
730
|
async function readIdeaTitle(fileSystem, dustPath, ideaSlug) {
|
|
740
731
|
const ideaPath = `${dustPath}/ideas/${ideaSlug}.md`;
|
|
741
732
|
if (!fileSystem.exists(ideaPath)) {
|
|
@@ -845,15 +836,14 @@ ${definitionOfDone.map((item) => `- ${item}`).join(`
|
|
|
845
836
|
`)}
|
|
846
837
|
`;
|
|
847
838
|
}
|
|
848
|
-
async function createIdeaTransitionTask(fileSystem, dustPath,
|
|
839
|
+
async function createIdeaTransitionTask(fileSystem, dustPath, taskType, prefix, ideaSlug, openingSentenceTemplate, definitionOfDone, ideaSectionHeading, taskOptions) {
|
|
849
840
|
const ideaTitle = await readIdeaTitle(fileSystem, dustPath, ideaSlug);
|
|
850
841
|
const taskTitle = `${prefix}${ideaTitle}`;
|
|
851
842
|
const filename = titleToFilename(taskTitle);
|
|
852
843
|
const filePath = `${dustPath}/tasks/${filename}`;
|
|
853
844
|
const baseOpeningSentence = openingSentenceTemplate(ideaTitle);
|
|
854
|
-
const hint = await readWorkflowHint(fileSystem, dustPath,
|
|
845
|
+
const hint = await readWorkflowHint(fileSystem, dustPath, taskType);
|
|
855
846
|
const ideaSection = { heading: ideaSectionHeading, ideaTitle, ideaSlug };
|
|
856
|
-
const taskType = workflowType === "refine-idea" ? "refine" : workflowType === "decompose-idea" ? "decompose" : workflowType === "shelve-idea" ? "shelve" : "implement";
|
|
857
847
|
const content = renderTask(taskTitle, baseOpeningSentence, definitionOfDone, ideaSection, taskType, {
|
|
858
848
|
description: taskOptions?.description,
|
|
859
849
|
resolvedQuestions: taskOptions?.resolvedQuestions,
|
|
@@ -864,7 +854,7 @@ async function createIdeaTransitionTask(fileSystem, dustPath, workflowType, pref
|
|
|
864
854
|
}
|
|
865
855
|
async function createRefineIdeaTask(fileSystem, dustPath, ideaSlug, description, openQuestionResponses, dustCommand) {
|
|
866
856
|
const cmd = dustCommand ?? "dust";
|
|
867
|
-
return createIdeaTransitionTask(fileSystem, dustPath, "refine
|
|
857
|
+
return createIdeaTransitionTask(fileSystem, dustPath, "refine", "Refine Idea: ", ideaSlug, (ideaTitle) => `Thoroughly research this idea and refine it into a well-defined proposal. Read the idea file, explore the codebase for relevant context, and identify any ambiguity. Where aspects are unclear or could go multiple ways, add open questions to the idea file. Run \`${cmd} principles\` for alignment and \`${cmd} facts\` for relevant design decisions. See [${ideaTitle}](../ideas/${ideaSlug}.md). If you add open questions, use \`## Open Questions\` with \`### Question?\` headings and one or more \`#### Option\` headings beneath each question, and only add questions that are meaningful decisions worth asking.`, [
|
|
868
858
|
"Idea is thoroughly researched with relevant codebase context",
|
|
869
859
|
"Open questions are added for any ambiguous or underspecified aspects",
|
|
870
860
|
"Open questions follow the required heading format and focus on high-value decisions",
|
|
@@ -876,7 +866,7 @@ async function createRefineIdeaTask(fileSystem, dustPath, ideaSlug, description,
|
|
|
876
866
|
}
|
|
877
867
|
async function decomposeIdea(fileSystem, dustPath, options, dustCommand) {
|
|
878
868
|
const cmd = dustCommand ?? "dust";
|
|
879
|
-
return createIdeaTransitionTask(fileSystem, dustPath, "decompose
|
|
869
|
+
return createIdeaTransitionTask(fileSystem, dustPath, "decompose", "Decompose Idea: ", options.ideaSlug, (ideaTitle) => `Create one or more well-defined tasks from this idea. Prefer smaller, narrowly scoped tasks that each deliver a thin but complete vertical slice of working software -- a path through the system that can be tested end-to-end -- rather than component-oriented tasks (like "add schema" or "build endpoint") that only work once all tasks are done. Split the idea into multiple tasks if it covers more than one logical change. Run \`${cmd} principles\` to link relevant principles and \`${cmd} facts\` for design decisions that should inform the task. See [${ideaTitle}](../ideas/${options.ideaSlug}.md).`, [
|
|
880
870
|
"One or more new tasks are created in .dust/tasks/",
|
|
881
871
|
"Task's Principles section links to relevant principles from .dust/principles/",
|
|
882
872
|
"The original idea is deleted or updated to reflect remaining scope"
|
|
@@ -886,11 +876,11 @@ async function decomposeIdea(fileSystem, dustPath, options, dustCommand) {
|
|
|
886
876
|
});
|
|
887
877
|
}
|
|
888
878
|
async function createShelveIdeaTask(fileSystem, dustPath, ideaSlug, description, _dustCommand) {
|
|
889
|
-
return createIdeaTransitionTask(fileSystem, dustPath, "shelve
|
|
879
|
+
return createIdeaTransitionTask(fileSystem, dustPath, "shelve", "Shelve Idea: ", ideaSlug, (ideaTitle) => `Archive this idea and remove it from the active backlog. See [${ideaTitle}](../ideas/${ideaSlug}.md).`, ["Idea file is deleted", "Rationale is recorded in the commit message"], "Shelves Idea", { description });
|
|
890
880
|
}
|
|
891
881
|
async function createExpediteIdeaTask(fileSystem, dustPath, ideaSlug, description, dustCommand) {
|
|
892
882
|
const cmd = dustCommand ?? "dust";
|
|
893
|
-
return createIdeaTransitionTask(fileSystem, dustPath, "
|
|
883
|
+
return createIdeaTransitionTask(fileSystem, dustPath, "implement", "Expedite Idea: ", ideaSlug, (ideaTitle) => `Research this idea briefly. If confident the implementation is straightforward (clear scope, minimal risk, no open questions), implement directly and commit. Otherwise, create one or more narrowly-scoped task files in \`.dust/tasks/\`. Run \`${cmd} principles\` and \`${cmd} facts\` for relevant context. See [${ideaTitle}](../ideas/${ideaSlug}.md).`, [
|
|
894
884
|
"Idea is implemented directly OR one or more new tasks are created in `.dust/tasks/`",
|
|
895
885
|
"If tasks were created, they link to relevant principles from `.dust/principles/`",
|
|
896
886
|
"Changes are committed with a clear commit message"
|
|
@@ -910,7 +900,7 @@ async function createIdeaTask(fileSystem, dustPath, options) {
|
|
|
910
900
|
const filename2 = titleToFilename(taskTitle2);
|
|
911
901
|
const filePath2 = `${dustPath}/tasks/${filename2}`;
|
|
912
902
|
const baseOpeningSentence2 = `Research this idea briefly. If confident the implementation is straightforward (clear scope, minimal risk, no open questions), implement directly and commit. Otherwise, create one or more narrowly-scoped task files in \`.dust/tasks/\`. Run \`${cmd} principles\` and \`${cmd} facts\` for relevant context.`;
|
|
913
|
-
const hint2 = await readWorkflowHint(fileSystem, dustPath, "
|
|
903
|
+
const hint2 = await readWorkflowHint(fileSystem, dustPath, "implement");
|
|
914
904
|
const repositoryHintsSection2 = renderRepositoryHintsSection(hint2 ?? undefined);
|
|
915
905
|
const content2 = `# ${taskTitle2}
|
|
916
906
|
|
|
@@ -942,7 +932,7 @@ ${repositoryHintsSection2}
|
|
|
942
932
|
const filename = titleToFilename(taskTitle);
|
|
943
933
|
const filePath = `${dustPath}/tasks/${filename}`;
|
|
944
934
|
const baseOpeningSentence = `Research this idea thoroughly, then create one or more idea files in \`.dust/ideas/\`. Read the codebase for relevant context, flesh out the description, and identify any ambiguity. Where aspects are unclear or could go multiple ways, add open questions to the idea file. If you add open questions, use \`## Open Questions\` with \`### Question?\` headings and one or more \`#### Option\` headings beneath each question, and only add questions that are meaningful decisions worth asking. Run \`${cmd} principles\` and \`${cmd} facts\` for relevant context.`;
|
|
945
|
-
const hint = await readWorkflowHint(fileSystem, dustPath, "
|
|
935
|
+
const hint = await readWorkflowHint(fileSystem, dustPath, "capture");
|
|
946
936
|
const repositoryHintsSection = renderRepositoryHintsSection(hint ?? undefined);
|
|
947
937
|
const content = `# ${taskTitle}
|
|
948
938
|
|
package/dist/dust.js
CHANGED
|
@@ -7,7 +7,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
7
7
|
var require_package = __commonJS((exports, module) => {
|
|
8
8
|
module.exports = {
|
|
9
9
|
name: "@joshski/dust",
|
|
10
|
-
version: "0.1.
|
|
10
|
+
version: "0.1.106",
|
|
11
11
|
description: "Flow state for AI coding agents",
|
|
12
12
|
type: "module",
|
|
13
13
|
bin: {
|
|
@@ -712,7 +712,7 @@ async function loadSettings(cwd, fileSystem, runtime) {
|
|
|
712
712
|
}
|
|
713
713
|
|
|
714
714
|
// lib/version.ts
|
|
715
|
-
var DUST_VERSION = "0.1.
|
|
715
|
+
var DUST_VERSION = "0.1.106";
|
|
716
716
|
|
|
717
717
|
// lib/cli/middleware.ts
|
|
718
718
|
function applyMiddleware(middlewares, execute) {
|
|
@@ -5153,15 +5153,198 @@ function extractFirstSentence2(paragraph) {
|
|
|
5153
5153
|
return match ? match[1] : null;
|
|
5154
5154
|
}
|
|
5155
5155
|
|
|
5156
|
-
// lib/
|
|
5157
|
-
var
|
|
5158
|
-
var
|
|
5156
|
+
// lib/artifacts/workflow-tasks.ts
|
|
5157
|
+
var CAPTURE_IDEA_PREFIX = "Add Idea: ";
|
|
5158
|
+
var EXPEDITE_IDEA_PREFIX = "Expedite Idea: ";
|
|
5159
|
+
function titleToFilename(title) {
|
|
5160
|
+
return `${title.toLowerCase().replace(/\./g, "-").replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
5161
|
+
}
|
|
5162
|
+
var VALID_TASK_TYPES = [
|
|
5159
5163
|
"implement",
|
|
5160
5164
|
"capture",
|
|
5161
5165
|
"refine",
|
|
5162
5166
|
"decompose",
|
|
5163
5167
|
"shelve"
|
|
5164
|
-
]
|
|
5168
|
+
];
|
|
5169
|
+
function parseTaskType(content) {
|
|
5170
|
+
const lines = content.split(`
|
|
5171
|
+
`);
|
|
5172
|
+
let inSection = false;
|
|
5173
|
+
let inCodeFence = false;
|
|
5174
|
+
for (const line of lines) {
|
|
5175
|
+
if (line.startsWith("```")) {
|
|
5176
|
+
inCodeFence = !inCodeFence;
|
|
5177
|
+
continue;
|
|
5178
|
+
}
|
|
5179
|
+
if (inCodeFence)
|
|
5180
|
+
continue;
|
|
5181
|
+
if (line.startsWith("## ")) {
|
|
5182
|
+
inSection = line.trimEnd() === "## Task Type";
|
|
5183
|
+
continue;
|
|
5184
|
+
}
|
|
5185
|
+
if (!inSection)
|
|
5186
|
+
continue;
|
|
5187
|
+
if (line.startsWith("# "))
|
|
5188
|
+
break;
|
|
5189
|
+
const trimmed = line.trim();
|
|
5190
|
+
if (trimmed && VALID_TASK_TYPES.includes(trimmed)) {
|
|
5191
|
+
return trimmed;
|
|
5192
|
+
}
|
|
5193
|
+
}
|
|
5194
|
+
return null;
|
|
5195
|
+
}
|
|
5196
|
+
var WORKFLOW_SECTION_HEADINGS = [
|
|
5197
|
+
{ type: "refine", heading: "Refines Idea" },
|
|
5198
|
+
{ type: "decompose", heading: "Decomposes Idea" },
|
|
5199
|
+
{ type: "shelve", heading: "Shelves Idea" },
|
|
5200
|
+
{ type: "implement", heading: "Expedites Idea" }
|
|
5201
|
+
];
|
|
5202
|
+
function extractIdeaSlugFromSection(content, sectionHeading) {
|
|
5203
|
+
const lines = content.split(`
|
|
5204
|
+
`);
|
|
5205
|
+
let inSection = false;
|
|
5206
|
+
let inCodeFence = false;
|
|
5207
|
+
for (const line of lines) {
|
|
5208
|
+
if (line.startsWith("```")) {
|
|
5209
|
+
inCodeFence = !inCodeFence;
|
|
5210
|
+
continue;
|
|
5211
|
+
}
|
|
5212
|
+
if (inCodeFence)
|
|
5213
|
+
continue;
|
|
5214
|
+
if (line.startsWith("## ")) {
|
|
5215
|
+
inSection = line.trimEnd() === `## ${sectionHeading}`;
|
|
5216
|
+
continue;
|
|
5217
|
+
}
|
|
5218
|
+
if (!inSection)
|
|
5219
|
+
continue;
|
|
5220
|
+
if (line.startsWith("# "))
|
|
5221
|
+
break;
|
|
5222
|
+
const linkMatch = line.match(MARKDOWN_LINK_PATTERN);
|
|
5223
|
+
if (linkMatch) {
|
|
5224
|
+
const target = linkMatch[2];
|
|
5225
|
+
const slugMatch = target.match(/([^/]+)\.md$/);
|
|
5226
|
+
if (slugMatch) {
|
|
5227
|
+
return slugMatch[1];
|
|
5228
|
+
}
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
return null;
|
|
5232
|
+
}
|
|
5233
|
+
async function findAllWorkflowTasks(fileSystem, dustPath) {
|
|
5234
|
+
const tasksPath = `${dustPath}/tasks`;
|
|
5235
|
+
const captureIdeaTasks = [];
|
|
5236
|
+
const workflowTasksByIdeaSlug = new Map;
|
|
5237
|
+
if (!fileSystem.exists(tasksPath)) {
|
|
5238
|
+
return { captureIdeaTasks, workflowTasksByIdeaSlug };
|
|
5239
|
+
}
|
|
5240
|
+
const files = await fileSystem.readdir(tasksPath);
|
|
5241
|
+
for (const file of files.filter((f) => f.endsWith(".md")).toSorted()) {
|
|
5242
|
+
const content = await fileSystem.readFile(`${tasksPath}/${file}`);
|
|
5243
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
5244
|
+
if (!titleMatch)
|
|
5245
|
+
continue;
|
|
5246
|
+
const title = titleMatch[1].trim();
|
|
5247
|
+
const taskSlug = file.replace(/\.md$/, "");
|
|
5248
|
+
const taskType = parseTaskType(content);
|
|
5249
|
+
if (taskType === "capture" || taskType === "implement") {
|
|
5250
|
+
let ideaTitle = null;
|
|
5251
|
+
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
5252
|
+
ideaTitle = title.slice(CAPTURE_IDEA_PREFIX.length);
|
|
5253
|
+
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
5254
|
+
ideaTitle = title.slice(EXPEDITE_IDEA_PREFIX.length);
|
|
5255
|
+
}
|
|
5256
|
+
if (ideaTitle) {
|
|
5257
|
+
captureIdeaTasks.push({
|
|
5258
|
+
taskSlug,
|
|
5259
|
+
ideaTitle
|
|
5260
|
+
});
|
|
5261
|
+
}
|
|
5262
|
+
} else if (!taskType) {
|
|
5263
|
+
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
5264
|
+
captureIdeaTasks.push({
|
|
5265
|
+
taskSlug,
|
|
5266
|
+
ideaTitle: title.slice(CAPTURE_IDEA_PREFIX.length)
|
|
5267
|
+
});
|
|
5268
|
+
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
5269
|
+
captureIdeaTasks.push({
|
|
5270
|
+
taskSlug,
|
|
5271
|
+
ideaTitle: title.slice(EXPEDITE_IDEA_PREFIX.length)
|
|
5272
|
+
});
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
if (taskType) {
|
|
5276
|
+
const heading = WORKFLOW_SECTION_HEADINGS.find((h) => h.type === taskType)?.heading;
|
|
5277
|
+
if (heading) {
|
|
5278
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
5279
|
+
if (linkedSlug) {
|
|
5280
|
+
workflowTasksByIdeaSlug.set(linkedSlug, {
|
|
5281
|
+
type: taskType,
|
|
5282
|
+
ideaSlug: linkedSlug,
|
|
5283
|
+
taskSlug,
|
|
5284
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
5285
|
+
});
|
|
5286
|
+
}
|
|
5287
|
+
}
|
|
5288
|
+
} else {
|
|
5289
|
+
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
5290
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
5291
|
+
if (linkedSlug) {
|
|
5292
|
+
workflowTasksByIdeaSlug.set(linkedSlug, {
|
|
5293
|
+
type,
|
|
5294
|
+
ideaSlug: linkedSlug,
|
|
5295
|
+
taskSlug,
|
|
5296
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
5297
|
+
});
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
return { captureIdeaTasks, workflowTasksByIdeaSlug };
|
|
5303
|
+
}
|
|
5304
|
+
function parseResolvedQuestions(content) {
|
|
5305
|
+
const lines = content.split(`
|
|
5306
|
+
`);
|
|
5307
|
+
const results = [];
|
|
5308
|
+
let inSection = false;
|
|
5309
|
+
let currentQuestion = null;
|
|
5310
|
+
let inCodeFence = false;
|
|
5311
|
+
for (const line of lines) {
|
|
5312
|
+
if (line.startsWith("```")) {
|
|
5313
|
+
inCodeFence = !inCodeFence;
|
|
5314
|
+
continue;
|
|
5315
|
+
}
|
|
5316
|
+
if (inCodeFence)
|
|
5317
|
+
continue;
|
|
5318
|
+
if (line.startsWith("## ")) {
|
|
5319
|
+
inSection = line.trimEnd() === "## Resolved Questions";
|
|
5320
|
+
currentQuestion = null;
|
|
5321
|
+
continue;
|
|
5322
|
+
}
|
|
5323
|
+
if (!inSection)
|
|
5324
|
+
continue;
|
|
5325
|
+
if (line.startsWith("# "))
|
|
5326
|
+
break;
|
|
5327
|
+
if (line.startsWith("### ")) {
|
|
5328
|
+
currentQuestion = line.slice(4).trimEnd();
|
|
5329
|
+
continue;
|
|
5330
|
+
}
|
|
5331
|
+
if (currentQuestion !== null) {
|
|
5332
|
+
const decisionMatch = line.match(/^\*\*Decision:\*\*\s*(.+)$/);
|
|
5333
|
+
if (decisionMatch) {
|
|
5334
|
+
results.push({
|
|
5335
|
+
question: currentQuestion,
|
|
5336
|
+
chosenOption: decisionMatch[1].trimEnd()
|
|
5337
|
+
});
|
|
5338
|
+
currentQuestion = null;
|
|
5339
|
+
}
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
return results;
|
|
5343
|
+
}
|
|
5344
|
+
|
|
5345
|
+
// lib/lint/validators/content-validator.ts
|
|
5346
|
+
var REQUIRED_TASK_HEADINGS = ["Task Type", "Blocked By", "Definition of Done"];
|
|
5347
|
+
var ALLOWED_TASK_TYPES = new Set(VALID_TASK_TYPES);
|
|
5165
5348
|
var MAX_OPENING_SENTENCE_LENGTH = 150;
|
|
5166
5349
|
var NON_IMPERATIVE_STARTERS = new Set([
|
|
5167
5350
|
"the",
|
|
@@ -9586,180 +9769,6 @@ async function parsePrinciple(fileSystem, dustPath, slug) {
|
|
|
9586
9769
|
};
|
|
9587
9770
|
}
|
|
9588
9771
|
|
|
9589
|
-
// lib/artifacts/workflow-tasks.ts
|
|
9590
|
-
var CAPTURE_IDEA_PREFIX = "Add Idea: ";
|
|
9591
|
-
var EXPEDITE_IDEA_PREFIX = "Expedite Idea: ";
|
|
9592
|
-
function titleToFilename(title) {
|
|
9593
|
-
return `${title.toLowerCase().replace(/\./g, "-").replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
9594
|
-
}
|
|
9595
|
-
var VALID_TASK_TYPES = [
|
|
9596
|
-
"implement",
|
|
9597
|
-
"capture",
|
|
9598
|
-
"refine",
|
|
9599
|
-
"decompose",
|
|
9600
|
-
"shelve"
|
|
9601
|
-
];
|
|
9602
|
-
function parseTaskType(content) {
|
|
9603
|
-
const lines = content.split(`
|
|
9604
|
-
`);
|
|
9605
|
-
let inSection = false;
|
|
9606
|
-
let inCodeFence = false;
|
|
9607
|
-
for (const line of lines) {
|
|
9608
|
-
if (line.startsWith("```")) {
|
|
9609
|
-
inCodeFence = !inCodeFence;
|
|
9610
|
-
continue;
|
|
9611
|
-
}
|
|
9612
|
-
if (inCodeFence)
|
|
9613
|
-
continue;
|
|
9614
|
-
if (line.startsWith("## ")) {
|
|
9615
|
-
inSection = line.trimEnd() === "## Task Type";
|
|
9616
|
-
continue;
|
|
9617
|
-
}
|
|
9618
|
-
if (!inSection)
|
|
9619
|
-
continue;
|
|
9620
|
-
if (line.startsWith("# "))
|
|
9621
|
-
break;
|
|
9622
|
-
const trimmed = line.trim();
|
|
9623
|
-
if (trimmed && VALID_TASK_TYPES.includes(trimmed)) {
|
|
9624
|
-
return trimmed;
|
|
9625
|
-
}
|
|
9626
|
-
}
|
|
9627
|
-
return null;
|
|
9628
|
-
}
|
|
9629
|
-
var WORKFLOW_SECTION_HEADINGS = [
|
|
9630
|
-
{ type: "refine-idea", heading: "Refines Idea" },
|
|
9631
|
-
{ type: "decompose-idea", heading: "Decomposes Idea" },
|
|
9632
|
-
{ type: "shelve-idea", heading: "Shelves Idea" },
|
|
9633
|
-
{ type: "expedite-idea", heading: "Expedites Idea" }
|
|
9634
|
-
];
|
|
9635
|
-
function extractIdeaSlugFromSection(content, sectionHeading) {
|
|
9636
|
-
const lines = content.split(`
|
|
9637
|
-
`);
|
|
9638
|
-
let inSection = false;
|
|
9639
|
-
let inCodeFence = false;
|
|
9640
|
-
for (const line of lines) {
|
|
9641
|
-
if (line.startsWith("```")) {
|
|
9642
|
-
inCodeFence = !inCodeFence;
|
|
9643
|
-
continue;
|
|
9644
|
-
}
|
|
9645
|
-
if (inCodeFence)
|
|
9646
|
-
continue;
|
|
9647
|
-
if (line.startsWith("## ")) {
|
|
9648
|
-
inSection = line.trimEnd() === `## ${sectionHeading}`;
|
|
9649
|
-
continue;
|
|
9650
|
-
}
|
|
9651
|
-
if (!inSection)
|
|
9652
|
-
continue;
|
|
9653
|
-
if (line.startsWith("# "))
|
|
9654
|
-
break;
|
|
9655
|
-
const linkMatch = line.match(MARKDOWN_LINK_PATTERN);
|
|
9656
|
-
if (linkMatch) {
|
|
9657
|
-
const target = linkMatch[2];
|
|
9658
|
-
const slugMatch = target.match(/([^/]+)\.md$/);
|
|
9659
|
-
if (slugMatch) {
|
|
9660
|
-
return slugMatch[1];
|
|
9661
|
-
}
|
|
9662
|
-
}
|
|
9663
|
-
}
|
|
9664
|
-
return null;
|
|
9665
|
-
}
|
|
9666
|
-
async function findAllWorkflowTasks(fileSystem, dustPath) {
|
|
9667
|
-
const tasksPath = `${dustPath}/tasks`;
|
|
9668
|
-
const captureIdeaTasks = [];
|
|
9669
|
-
const workflowTasksByIdeaSlug = new Map;
|
|
9670
|
-
if (!fileSystem.exists(tasksPath)) {
|
|
9671
|
-
return { captureIdeaTasks, workflowTasksByIdeaSlug };
|
|
9672
|
-
}
|
|
9673
|
-
const files = await fileSystem.readdir(tasksPath);
|
|
9674
|
-
for (const file of files.filter((f) => f.endsWith(".md")).toSorted()) {
|
|
9675
|
-
const content = await fileSystem.readFile(`${tasksPath}/${file}`);
|
|
9676
|
-
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
9677
|
-
if (!titleMatch)
|
|
9678
|
-
continue;
|
|
9679
|
-
const title = titleMatch[1].trim();
|
|
9680
|
-
const taskSlug = file.replace(/\.md$/, "");
|
|
9681
|
-
const taskType = parseTaskType(content);
|
|
9682
|
-
if (taskType === "capture" || taskType === "implement") {
|
|
9683
|
-
let ideaTitle = null;
|
|
9684
|
-
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
9685
|
-
ideaTitle = title.slice(CAPTURE_IDEA_PREFIX.length);
|
|
9686
|
-
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
9687
|
-
ideaTitle = title.slice(EXPEDITE_IDEA_PREFIX.length);
|
|
9688
|
-
}
|
|
9689
|
-
if (ideaTitle) {
|
|
9690
|
-
captureIdeaTasks.push({
|
|
9691
|
-
taskSlug,
|
|
9692
|
-
ideaTitle
|
|
9693
|
-
});
|
|
9694
|
-
}
|
|
9695
|
-
} else if (!taskType) {
|
|
9696
|
-
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
9697
|
-
captureIdeaTasks.push({
|
|
9698
|
-
taskSlug,
|
|
9699
|
-
ideaTitle: title.slice(CAPTURE_IDEA_PREFIX.length)
|
|
9700
|
-
});
|
|
9701
|
-
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
9702
|
-
captureIdeaTasks.push({
|
|
9703
|
-
taskSlug,
|
|
9704
|
-
ideaTitle: title.slice(EXPEDITE_IDEA_PREFIX.length)
|
|
9705
|
-
});
|
|
9706
|
-
}
|
|
9707
|
-
}
|
|
9708
|
-
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
9709
|
-
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
9710
|
-
if (linkedSlug) {
|
|
9711
|
-
workflowTasksByIdeaSlug.set(linkedSlug, {
|
|
9712
|
-
type,
|
|
9713
|
-
ideaSlug: linkedSlug,
|
|
9714
|
-
taskSlug,
|
|
9715
|
-
resolvedQuestions: parseResolvedQuestions(content)
|
|
9716
|
-
});
|
|
9717
|
-
}
|
|
9718
|
-
}
|
|
9719
|
-
}
|
|
9720
|
-
return { captureIdeaTasks, workflowTasksByIdeaSlug };
|
|
9721
|
-
}
|
|
9722
|
-
function parseResolvedQuestions(content) {
|
|
9723
|
-
const lines = content.split(`
|
|
9724
|
-
`);
|
|
9725
|
-
const results = [];
|
|
9726
|
-
let inSection = false;
|
|
9727
|
-
let currentQuestion = null;
|
|
9728
|
-
let inCodeFence = false;
|
|
9729
|
-
for (const line of lines) {
|
|
9730
|
-
if (line.startsWith("```")) {
|
|
9731
|
-
inCodeFence = !inCodeFence;
|
|
9732
|
-
continue;
|
|
9733
|
-
}
|
|
9734
|
-
if (inCodeFence)
|
|
9735
|
-
continue;
|
|
9736
|
-
if (line.startsWith("## ")) {
|
|
9737
|
-
inSection = line.trimEnd() === "## Resolved Questions";
|
|
9738
|
-
currentQuestion = null;
|
|
9739
|
-
continue;
|
|
9740
|
-
}
|
|
9741
|
-
if (!inSection)
|
|
9742
|
-
continue;
|
|
9743
|
-
if (line.startsWith("# "))
|
|
9744
|
-
break;
|
|
9745
|
-
if (line.startsWith("### ")) {
|
|
9746
|
-
currentQuestion = line.slice(4).trimEnd();
|
|
9747
|
-
continue;
|
|
9748
|
-
}
|
|
9749
|
-
if (currentQuestion !== null) {
|
|
9750
|
-
const decisionMatch = line.match(/^\*\*Decision:\*\*\s*(.+)$/);
|
|
9751
|
-
if (decisionMatch) {
|
|
9752
|
-
results.push({
|
|
9753
|
-
question: currentQuestion,
|
|
9754
|
-
chosenOption: decisionMatch[1].trimEnd()
|
|
9755
|
-
});
|
|
9756
|
-
currentQuestion = null;
|
|
9757
|
-
}
|
|
9758
|
-
}
|
|
9759
|
-
}
|
|
9760
|
-
return results;
|
|
9761
|
-
}
|
|
9762
|
-
|
|
9763
9772
|
// lib/artifacts/index.ts
|
|
9764
9773
|
var ARTIFACT_TYPES = [
|
|
9765
9774
|
"facts",
|
|
@@ -11018,13 +11027,14 @@ function getCorePrinciplesPath() {
|
|
|
11018
11027
|
// lib/cli/commands/list.ts
|
|
11019
11028
|
function workflowTypeToStatus(type) {
|
|
11020
11029
|
switch (type) {
|
|
11021
|
-
case "refine
|
|
11030
|
+
case "refine":
|
|
11022
11031
|
return "refining";
|
|
11023
|
-
case "decompose
|
|
11032
|
+
case "decompose":
|
|
11024
11033
|
return "decomposing";
|
|
11025
|
-
case "shelve
|
|
11034
|
+
case "shelve":
|
|
11026
11035
|
return "shelving";
|
|
11027
|
-
case "
|
|
11036
|
+
case "implement":
|
|
11037
|
+
case "capture":
|
|
11028
11038
|
return "expediting";
|
|
11029
11039
|
}
|
|
11030
11040
|
}
|
package/dist/patch/task.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Task serialization and patch building functions.
|
|
3
3
|
*/
|
|
4
|
+
import type { TaskType } from '../artifacts/workflow-tasks';
|
|
4
5
|
export interface StandardTaskInput {
|
|
5
6
|
type?: undefined;
|
|
6
7
|
title: string;
|
|
@@ -10,7 +11,7 @@ export interface StandardTaskInput {
|
|
|
10
11
|
definitionOfDone: string[];
|
|
11
12
|
}
|
|
12
13
|
export interface WorkflowTaskInput {
|
|
13
|
-
type: 'capture
|
|
14
|
+
type: Extract<TaskType, 'capture' | 'refine' | 'decompose' | 'shelve'>;
|
|
14
15
|
ideaSlug: string;
|
|
15
16
|
definitionOfDone?: string[];
|
|
16
17
|
}
|
package/dist/patch.js
CHANGED
|
@@ -142,6 +142,13 @@ function extractFirstSentence(paragraph) {
|
|
|
142
142
|
function titleToFilename(title) {
|
|
143
143
|
return `${title.toLowerCase().replace(/\./g, "-").replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
144
144
|
}
|
|
145
|
+
var VALID_TASK_TYPES = [
|
|
146
|
+
"implement",
|
|
147
|
+
"capture",
|
|
148
|
+
"refine",
|
|
149
|
+
"decompose",
|
|
150
|
+
"shelve"
|
|
151
|
+
];
|
|
145
152
|
|
|
146
153
|
// lib/artifacts/index.ts
|
|
147
154
|
var ARTIFACT_TYPES = [
|
|
@@ -237,13 +244,7 @@ function validateAuditHeadings(artifact) {
|
|
|
237
244
|
|
|
238
245
|
// lib/lint/validators/content-validator.ts
|
|
239
246
|
var REQUIRED_TASK_HEADINGS = ["Task Type", "Blocked By", "Definition of Done"];
|
|
240
|
-
var ALLOWED_TASK_TYPES = new Set(
|
|
241
|
-
"implement",
|
|
242
|
-
"capture",
|
|
243
|
-
"refine",
|
|
244
|
-
"decompose",
|
|
245
|
-
"shelve"
|
|
246
|
-
]);
|
|
247
|
+
var ALLOWED_TASK_TYPES = new Set(VALID_TASK_TYPES);
|
|
247
248
|
var MAX_OPENING_SENTENCE_LENGTH = 150;
|
|
248
249
|
var NON_IMPERATIVE_STARTERS = new Set([
|
|
249
250
|
"the",
|
|
@@ -1115,30 +1116,28 @@ function buildPrincipleFiles(input, slug) {
|
|
|
1115
1116
|
|
|
1116
1117
|
// lib/patch/task.ts
|
|
1117
1118
|
var WORKFLOW_SECTION_HEADINGS = {
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1119
|
+
capture: "Captures Idea",
|
|
1120
|
+
refine: "Refines Idea",
|
|
1121
|
+
decompose: "Decomposes Idea",
|
|
1122
|
+
shelve: "Shelves Idea"
|
|
1122
1123
|
};
|
|
1123
1124
|
var WORKFLOW_TITLE_PREFIXES = {
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1125
|
+
capture: "Add Idea: ",
|
|
1126
|
+
refine: "Refine Idea: ",
|
|
1127
|
+
decompose: "Decompose Idea: ",
|
|
1128
|
+
shelve: "Shelve Idea: "
|
|
1128
1129
|
};
|
|
1129
1130
|
var WORKFLOW_OPENING_SENTENCES = {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1131
|
+
capture: "Research this idea thoroughly and create an idea file.",
|
|
1132
|
+
refine: "Thoroughly research this idea and refine it into a well-defined proposal.",
|
|
1133
|
+
decompose: "Create one or more well-defined tasks from this idea.",
|
|
1134
|
+
shelve: "Archive this idea and remove it from the active backlog."
|
|
1134
1135
|
};
|
|
1135
1136
|
var WORKFLOW_DEFAULT_DEFINITION_OF_DONE = {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
]
|
|
1140
|
-
"decompose-idea": ["One or more new tasks are created in .dust/tasks/"],
|
|
1141
|
-
"shelve-idea": ["Idea file is deleted"]
|
|
1137
|
+
capture: ["Idea file is created in .dust/ideas/"],
|
|
1138
|
+
refine: ["Idea is thoroughly researched with relevant codebase context"],
|
|
1139
|
+
decompose: ["One or more new tasks are created in .dust/tasks/"],
|
|
1140
|
+
shelve: ["Idea file is deleted"]
|
|
1142
1141
|
};
|
|
1143
1142
|
function ideaSlugToTitle(slug) {
|
|
1144
1143
|
return slug.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
@@ -1200,7 +1199,6 @@ function serializeWorkflowTask(input) {
|
|
|
1200
1199
|
const ideaSection = `## ${sectionHeading}
|
|
1201
1200
|
|
|
1202
1201
|
- [${ideaTitle}](../ideas/${input.ideaSlug}.md)`;
|
|
1203
|
-
const taskType = input.type === "capture-idea" ? "capture" : input.type === "refine-idea" ? "refine" : input.type === "decompose-idea" ? "decompose" : "shelve";
|
|
1204
1202
|
return `# ${title}
|
|
1205
1203
|
|
|
1206
1204
|
${openingSentence}
|
|
@@ -1209,7 +1207,7 @@ ${ideaSection}
|
|
|
1209
1207
|
|
|
1210
1208
|
## Task Type
|
|
1211
1209
|
|
|
1212
|
-
${
|
|
1210
|
+
${input.type}
|
|
1213
1211
|
|
|
1214
1212
|
## Blocked By
|
|
1215
1213
|
|
package/dist/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type { AgentSessionEvent, EventMessage } from './agent-events';
|
|
|
8
8
|
export type { Idea, IdeaOpenQuestion, IdeaOption, ParsedIdeaContent, } from './artifacts/ideas';
|
|
9
9
|
export type { ArtifactType, TaskGraph, TaskGraphNode } from './artifacts/index';
|
|
10
10
|
export type { Task } from './artifacts/tasks';
|
|
11
|
-
export type { CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, IdeaInProgress, OpenQuestionResponse, ParsedCaptureIdeaTask, WorkflowTaskMatch,
|
|
11
|
+
export type { CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, IdeaInProgress, OpenQuestionResponse, ParsedCaptureIdeaTask, WorkflowTaskMatch, } from './artifacts/workflow-tasks';
|
|
12
12
|
export type { Repository } from './bucket/repository';
|
|
13
13
|
export type { ToolExecutionErrorResult, ToolExecutionRequestMessage, ToolExecutionResult, ToolExecutionResultMessage, ToolExecutionSuccessResult, ToolExecutionToolNotFoundResult, } from './bucket/tool-execution-protocol';
|
|
14
14
|
export { isToolExecutionRequestMessage, isToolExecutionResultMessage, } from './bucket/tool-execution-protocol';
|
package/dist/validation.js
CHANGED
|
@@ -207,6 +207,13 @@ function extractFirstSentence(paragraph) {
|
|
|
207
207
|
function titleToFilename(title) {
|
|
208
208
|
return `${title.toLowerCase().replace(/\./g, "-").replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
209
209
|
}
|
|
210
|
+
var VALID_TASK_TYPES = [
|
|
211
|
+
"implement",
|
|
212
|
+
"capture",
|
|
213
|
+
"refine",
|
|
214
|
+
"decompose",
|
|
215
|
+
"shelve"
|
|
216
|
+
];
|
|
210
217
|
|
|
211
218
|
// lib/artifacts/index.ts
|
|
212
219
|
var ARTIFACT_TYPES = [
|
|
@@ -234,13 +241,7 @@ function validateAuditHeadings(artifact) {
|
|
|
234
241
|
|
|
235
242
|
// lib/lint/validators/content-validator.ts
|
|
236
243
|
var REQUIRED_TASK_HEADINGS = ["Task Type", "Blocked By", "Definition of Done"];
|
|
237
|
-
var ALLOWED_TASK_TYPES = new Set(
|
|
238
|
-
"implement",
|
|
239
|
-
"capture",
|
|
240
|
-
"refine",
|
|
241
|
-
"decompose",
|
|
242
|
-
"shelve"
|
|
243
|
-
]);
|
|
244
|
+
var ALLOWED_TASK_TYPES = new Set(VALID_TASK_TYPES);
|
|
244
245
|
var MAX_OPENING_SENTENCE_LENGTH = 150;
|
|
245
246
|
var NON_IMPERATIVE_STARTERS = new Set([
|
|
246
247
|
"the",
|