@joshski/dust 0.1.31 → 0.1.32

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/dust.js CHANGED
@@ -435,7 +435,7 @@ function extractOpeningSentence(content) {
435
435
  // lib/workflow-tasks.ts
436
436
  var IDEA_TRANSITION_PREFIXES = [
437
437
  "Refine Idea: ",
438
- "Create Task From Idea: ",
438
+ "Decompose Idea: ",
439
439
  "Shelve Idea: "
440
440
  ];
441
441
  function titleToFilename(title) {
@@ -1050,25 +1050,33 @@ async function lintMarkdown(dependencies) {
1050
1050
 
1051
1051
  // lib/cli/commands/check.ts
1052
1052
  var DEFAULT_CHECK_TIMEOUT_MS = 13000;
1053
+ async function runSingleCheck(check, cwd, runner) {
1054
+ const timeoutMs = check.timeoutMilliseconds ?? DEFAULT_CHECK_TIMEOUT_MS;
1055
+ const startTime = Date.now();
1056
+ const result = await runner.run(check.command, cwd, timeoutMs);
1057
+ const durationMs = Date.now() - startTime;
1058
+ return {
1059
+ name: check.name,
1060
+ command: check.command,
1061
+ exitCode: result.exitCode,
1062
+ output: result.output,
1063
+ hints: check.hints,
1064
+ durationMs,
1065
+ timedOut: result.timedOut,
1066
+ timeoutSeconds: timeoutMs / 1000
1067
+ };
1068
+ }
1053
1069
  async function runConfiguredChecks(checks, cwd, runner) {
1054
- const promises = checks.map(async (check) => {
1055
- const timeoutMs = check.timeoutMilliseconds ?? DEFAULT_CHECK_TIMEOUT_MS;
1056
- const startTime = Date.now();
1057
- const result = await runner.run(check.command, cwd, timeoutMs);
1058
- const durationMs = Date.now() - startTime;
1059
- return {
1060
- name: check.name,
1061
- command: check.command,
1062
- exitCode: result.exitCode,
1063
- output: result.output,
1064
- hints: check.hints,
1065
- durationMs,
1066
- timedOut: result.timedOut,
1067
- timeoutSeconds: timeoutMs / 1000
1068
- };
1069
- });
1070
+ const promises = checks.map((check) => runSingleCheck(check, cwd, runner));
1070
1071
  return Promise.all(promises);
1071
1072
  }
1073
+ async function runConfiguredChecksSerially(checks, cwd, runner) {
1074
+ const results = [];
1075
+ for (const check of checks) {
1076
+ results.push(await runSingleCheck(check, cwd, runner));
1077
+ }
1078
+ return results;
1079
+ }
1072
1080
  async function runValidationCheck(dependencies) {
1073
1081
  const outputLines = [];
1074
1082
  const bufferedContext = {
@@ -1131,7 +1139,13 @@ function displayResults(results, context) {
1131
1139
  return failed.length > 0 ? 1 : 0;
1132
1140
  }
1133
1141
  async function check(dependencies, shellRunner = defaultShellRunner) {
1134
- const { context, fileSystem, settings } = dependencies;
1142
+ const {
1143
+ arguments: commandArguments,
1144
+ context,
1145
+ fileSystem,
1146
+ settings
1147
+ } = dependencies;
1148
+ const serial = commandArguments.includes("--serial");
1135
1149
  if (!settings.checks || settings.checks.length === 0) {
1136
1150
  context.stderr("Error: No checks configured in .dust/config/settings.json");
1137
1151
  context.stderr("");
@@ -1144,9 +1158,20 @@ async function check(dependencies, shellRunner = defaultShellRunner) {
1144
1158
  context.stderr(" }");
1145
1159
  return { exitCode: 1 };
1146
1160
  }
1147
- const checkPromises = [];
1148
1161
  const dustPath = `${context.cwd}/.dust`;
1149
- if (fileSystem.exists(dustPath)) {
1162
+ const hasDustDir = fileSystem.exists(dustPath);
1163
+ if (serial) {
1164
+ const results2 = [];
1165
+ if (hasDustDir) {
1166
+ results2.push(await runValidationCheck(dependencies));
1167
+ }
1168
+ const configuredResults = await runConfiguredChecksSerially(settings.checks, context.cwd, shellRunner);
1169
+ results2.push(...configuredResults);
1170
+ const exitCode2 = displayResults(results2, context);
1171
+ return { exitCode: exitCode2 };
1172
+ }
1173
+ const checkPromises = [];
1174
+ if (hasDustDir) {
1150
1175
  checkPromises.push(runValidationCheck(dependencies));
1151
1176
  }
1152
1177
  checkPromises.push(runConfiguredChecks(settings.checks, context.cwd, shellRunner));
@@ -16,12 +16,13 @@ export declare function findAllCaptureIdeaTasks(fileSystem: FileSystem, dustPath
16
16
  * 6. Add .md extension
17
17
  */
18
18
  export declare function titleToFilename(title: string): string;
19
- export type WorkflowTaskType = 'refine' | 'create-task' | 'shelve';
19
+ export type WorkflowTaskType = 'refine' | 'decompose-idea' | 'shelve';
20
20
  export interface WorkflowTaskMatch {
21
21
  type: WorkflowTaskType;
22
+ ideaSlug: string;
22
23
  taskSlug: string;
23
24
  }
24
- export declare function findWorkflowTask(fileSystem: FileSystem, dustPath: string, ideaSlug: string): Promise<WorkflowTaskMatch | null>;
25
+ export declare function findWorkflowTaskForIdea(fileSystem: FileSystem, dustPath: string, ideaSlug: string): Promise<WorkflowTaskMatch | null>;
25
26
  export interface CreateIdeaTransitionTaskResult {
26
27
  filePath: string;
27
28
  }
@@ -29,12 +30,12 @@ export interface OpenQuestionResponse {
29
30
  question: string;
30
31
  chosenOption: string;
31
32
  }
32
- export interface CreateTaskFromIdeaOptions {
33
+ export interface DecomposeIdeaOptions {
33
34
  ideaSlug: string;
34
35
  description?: string;
35
36
  openQuestionResponses?: OpenQuestionResponse[];
36
37
  }
37
38
  export declare function createRefineIdeaTask(fileSystem: FileSystem, dustPath: string, ideaSlug: string, description?: string): Promise<CreateIdeaTransitionTaskResult>;
38
- export declare function createTaskFromIdea(fileSystem: FileSystem, dustPath: string, options: CreateTaskFromIdeaOptions): Promise<CreateIdeaTransitionTaskResult>;
39
+ export declare function decomposeIdea(fileSystem: FileSystem, dustPath: string, options: DecomposeIdeaOptions): Promise<CreateIdeaTransitionTaskResult>;
39
40
  export declare function createShelveIdeaTask(fileSystem: FileSystem, dustPath: string, ideaSlug: string, description?: string): Promise<CreateIdeaTransitionTaskResult>;
40
41
  export declare function createCaptureIdeaTask(fileSystem: FileSystem, dustPath: string, title: string, description: string): Promise<CreateIdeaTransitionTaskResult>;
@@ -1,7 +1,7 @@
1
1
  // lib/workflow-tasks.ts
2
2
  var IDEA_TRANSITION_PREFIXES = [
3
3
  "Refine Idea: ",
4
- "Create Task From Idea: ",
4
+ "Decompose Idea: ",
5
5
  "Shelve Idea: "
6
6
  ];
7
7
  var CAPTURE_IDEA_PREFIX = "Add Idea: ";
@@ -31,17 +31,17 @@ function titleToFilename(title) {
31
31
  }
32
32
  var WORKFLOW_TASK_TYPES = [
33
33
  { type: "refine", prefix: "Refine Idea: " },
34
- { type: "create-task", prefix: "Create Task From Idea: " },
34
+ { type: "decompose-idea", prefix: "Decompose Idea: " },
35
35
  { type: "shelve", prefix: "Shelve Idea: " }
36
36
  ];
37
- async function findWorkflowTask(fileSystem, dustPath, ideaSlug) {
37
+ async function findWorkflowTaskForIdea(fileSystem, dustPath, ideaSlug) {
38
38
  const ideaTitle = await readIdeaTitle(fileSystem, dustPath, ideaSlug);
39
39
  for (const { type, prefix } of WORKFLOW_TASK_TYPES) {
40
40
  const filename = titleToFilename(`${prefix}${ideaTitle}`);
41
41
  const filePath = `${dustPath}/tasks/${filename}`;
42
42
  if (fileSystem.exists(filePath)) {
43
43
  const taskSlug = filename.replace(/\.md$/, "");
44
- return { type, taskSlug };
44
+ return { type, ideaSlug, taskSlug };
45
45
  }
46
46
  }
47
47
  return null;
@@ -111,9 +111,9 @@ async function createRefineIdeaTask(fileSystem, dustPath, ideaSlug, description)
111
111
  "Idea file is updated with findings"
112
112
  ], { description });
113
113
  }
114
- async function createTaskFromIdea(fileSystem, dustPath, options) {
115
- return createIdeaTask(fileSystem, dustPath, "Create Task From Idea: ", options.ideaSlug, (ideaTitle) => `Create a well-defined task from this idea. Review \`.dust/goals/\` to link relevant goals and \`.dust/facts/\` for design decisions that should inform the task. See [${ideaTitle}](../ideas/${options.ideaSlug}.md).`, [
116
- "A new task is created in .dust/tasks/",
114
+ async function decomposeIdea(fileSystem, dustPath, options) {
115
+ return createIdeaTask(fileSystem, dustPath, "Decompose Idea: ", options.ideaSlug, (ideaTitle) => `Create one or more well-defined tasks from this idea. Prefer smaller, narrowly scoped tasks -- split the idea into multiple tasks if it covers more than one logical change. Review \`.dust/goals/\` to link relevant goals and \`.dust/facts/\` for design decisions that should inform the task. See [${ideaTitle}](../ideas/${options.ideaSlug}.md).`, [
116
+ "One or more new tasks are created in .dust/tasks/",
117
117
  "Task's Goals section links to relevant goals from .dust/goals/",
118
118
  "The original idea is deleted or updated to reflect remaining scope"
119
119
  ], {
@@ -147,9 +147,9 @@ async function createCaptureIdeaTask(fileSystem, dustPath, title, description) {
147
147
  }
148
148
  export {
149
149
  titleToFilename,
150
- findWorkflowTask,
150
+ findWorkflowTaskForIdea,
151
151
  findAllCaptureIdeaTasks,
152
- createTaskFromIdea,
152
+ decomposeIdea,
153
153
  createShelveIdeaTask,
154
154
  createRefineIdeaTask,
155
155
  createCaptureIdeaTask,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joshski/dust",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "Flow state for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,10 +1,4 @@
1
1
  🤖 Hello {{agentName}}, welcome to dust!
2
- {{#if agentInstructions}}
3
-
4
- ## Project Instructions
5
-
6
- {{agentInstructions}}
7
- {{/if}}
8
2
 
9
3
  CRITICAL: You MUST run exactly ONE of the commands below before doing anything else.
10
4
 
@@ -29,3 +23,9 @@ Determine the user's intent and run the matching command NOW:
29
23
  If none of the above clearly apply, run this to see all available commands.
30
24
 
31
25
  Do NOT proceed without running one of these commands.
26
+ {{#if agentInstructions}}
27
+
28
+ ---
29
+
30
+ {{agentInstructions}}
31
+ {{/if}}
@@ -1,10 +1,4 @@
1
1
  🤖 Hello {{agentName}}, welcome to dust!
2
- {{#if agentInstructions}}
3
-
4
- ## Project Instructions
5
-
6
- {{agentInstructions}}
7
- {{/if}}
8
2
 
9
3
  CRITICAL: You MUST run exactly ONE of the commands below before doing anything else.
10
4
 
@@ -29,3 +23,9 @@ Determine the user's intent and run the matching command NOW:
29
23
  If none of the above clearly apply, run this to see all available commands.
30
24
 
31
25
  Do NOT proceed without running one of these commands.
26
+ {{#if agentInstructions}}
27
+
28
+ ---
29
+
30
+ {{agentInstructions}}
31
+ {{/if}}