lalph 0.1.108 → 0.1.110

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/cli.mjs CHANGED
@@ -149176,18 +149176,7 @@ If for any reason you get stuck on a task, mark the task back as "todo" by updat
149176
149176
  challenges faced.
149177
149177
 
149178
149178
  ${prdNotes(options)}`;
149179
- const promptInstructions = (options) => `You are to read all of the following sections, and then output
149180
- step by step instructions for another AI agent to fullfil the task. Make sure to
149181
- do some quick research to understand the task before writing the instructions.
149182
-
149183
- Save the instructions in a markdown file called ".lalph/instructions.md".
149184
-
149185
- **DO NOT** start working on the task yet, only output the instructions.
149186
- Do everything you can to help the agent succeed.
149187
-
149188
- "Help others achieve their dreams and you will achieve yours."
149189
-
149190
- # The task
149179
+ const prompt = (options) => `# The task
149191
149180
 
149192
149181
  ID: ${options.task.id}
149193
149182
  Task: ${options.task.title}
@@ -149220,9 +149209,6 @@ ${options.task.description}
149220
149209
  - Rewrite the notes in the description to include only the key discoveries and information that could speed up future work on other tasks. Make sure to preserve important information such as specification file references.
149221
149210
  - If you believe the task is complete, update the \`state\` to "in-review".
149222
149211
 
149223
- ${keyInformation(options)}`;
149224
- const prompt = (options) => `${options.prompt}
149225
-
149226
149212
  ${keyInformation(options)}`;
149227
149213
  const promptReview = (options) => `A previous AI agent has completed a task from the instructions below.
149228
149214
 
@@ -149232,9 +149218,10 @@ ${options.gitFlow.reviewInstructions}
149232
149218
 
149233
149219
  # Prevous instructions (only for context, do not repeat)
149234
149220
 
149235
- ${options.prompt}
149221
+ ${options.prompt}`;
149222
+ const promptReviewCustom = (options) => `${options.prompt}
149236
149223
 
149237
- ${keyInformation(options)}`;
149224
+ ${prdNotes(options)}`;
149238
149225
  const promptTimeout = (options) => `Your earlier attempt to complete the task with id \`${options.taskId}\` took too
149239
149226
  long and has timed out. You can find the task details in the prd.yml file.
149240
149227
 
@@ -149283,9 +149270,9 @@ ${prdNotes(options)}`;
149283
149270
  ${prdNotes(options)}`;
149284
149271
  return {
149285
149272
  promptChoose,
149286
- promptInstructions,
149287
149273
  prompt,
149288
149274
  promptReview,
149275
+ promptReviewCustom,
149289
149276
  promptTimeout,
149290
149277
  planPrompt
149291
149278
  };
@@ -149695,6 +149682,20 @@ const getOrSelectCliAgent = gen(function* () {
149695
149682
  });
149696
149683
  const commandAgent = make$34("agent").pipe(withDescription("Select the CLI agent to use"), withHandler(() => selectCliAgent.pipe(provide$1(Settings.layer))));
149697
149684
 
149685
+ //#endregion
149686
+ //#region src/Agents/worker.ts
149687
+ const agentWorker = fnUntraced(function* (options) {
149688
+ const pathService = yield* Path$1;
149689
+ const worktree = yield* Worktree;
149690
+ return yield* pipe(options.cliAgent.command({
149691
+ prompt: options.prompt,
149692
+ prdFilePath: pathService.join(".lalph", "prd.yml")
149693
+ }), setCwd(worktree.directory), options.commandPrefix).pipe(worktree.execWithStallTimeout({
149694
+ cliAgent: options.cliAgent,
149695
+ stallTimeout: options.stallTimeout
149696
+ }));
149697
+ });
149698
+
149698
149699
  //#endregion
149699
149700
  //#region src/shared/fs.ts
149700
149701
  const makeWaitForFile = gen(function* () {
@@ -149786,49 +149787,6 @@ After making any changes, commit them to the same branch. Do not git push your c
149786
149787
  })).pipe(provide$3(layer));
149787
149788
  var GitFlowError = class extends TaggedError("GitFlowError") {};
149788
149789
 
149789
- //#endregion
149790
- //#region src/Agents/instructor.ts
149791
- const agentInstructor = fnUntraced(function* (options) {
149792
- const fs = yield* FileSystem;
149793
- const pathService = yield* Path$1;
149794
- const worktree = yield* Worktree;
149795
- const promptGen = yield* PromptGen;
149796
- const gitFlow = yield* GitFlow;
149797
- const waitForFile = yield* makeWaitForFile;
149798
- yield* pipe(options.cliAgent.command({
149799
- prompt: promptGen.promptInstructions({
149800
- task: options.task,
149801
- targetBranch: getOrUndefined(options.targetBranch),
149802
- specsDirectory: options.specsDirectory,
149803
- githubPrNumber: options.githubPrNumber,
149804
- gitFlow
149805
- }),
149806
- prdFilePath: pathService.join(".lalph", "prd.yml")
149807
- }), setCwd(worktree.directory), options.commandPrefix, worktree.execWithStallTimeout({
149808
- cliAgent: options.cliAgent,
149809
- stallTimeout: options.stallTimeout
149810
- }), raceFirst(waitForFile(pathService.join(worktree.directory, ".lalph"), "instructions.md")));
149811
- return yield* fs.readFileString(pathService.join(worktree.directory, ".lalph", "instructions.md"));
149812
- });
149813
-
149814
- //#endregion
149815
- //#region src/Agents/worker.ts
149816
- const agentWorker = fnUntraced(function* (options) {
149817
- const pathService = yield* Path$1;
149818
- const worktree = yield* Worktree;
149819
- const promptGen = yield* PromptGen;
149820
- return yield* pipe(options.cliAgent.command({
149821
- prompt: promptGen.prompt({
149822
- prompt: options.instructions,
149823
- specsDirectory: options.specsDirectory
149824
- }),
149825
- prdFilePath: pathService.join(".lalph", "prd.yml")
149826
- }), setCwd(worktree.directory), options.commandPrefix).pipe(worktree.execWithStallTimeout({
149827
- cliAgent: options.cliAgent,
149828
- stallTimeout: options.stallTimeout
149829
- }));
149830
- });
149831
-
149832
149790
  //#endregion
149833
149791
  //#region src/Agents/chooser.ts
149834
149792
  const agentChooser = fnUntraced(function* (options) {
@@ -149867,15 +149825,22 @@ const ChosenTask = fromJsonString(Struct({
149867
149825
  //#endregion
149868
149826
  //#region src/Agents/reviewer.ts
149869
149827
  const agentReviewer = fnUntraced(function* (options) {
149828
+ const fs = yield* FileSystem;
149870
149829
  const pathService = yield* Path$1;
149871
149830
  const worktree = yield* Worktree;
149872
149831
  const promptGen = yield* PromptGen;
149873
149832
  const gitFlow = yield* GitFlow;
149833
+ const customInstructions = yield* pipe(fs.readFileString(pathService.join(worktree.directory, "LALPH_REVIEW.md")), option$1);
149874
149834
  return yield* pipe(options.cliAgent.command({
149875
- prompt: promptGen.promptReview({
149876
- prompt: options.instructions,
149877
- specsDirectory: options.specsDirectory,
149878
- gitFlow
149835
+ prompt: match$7(customInstructions, {
149836
+ onNone: () => promptGen.promptReview({
149837
+ prompt: options.instructions,
149838
+ gitFlow
149839
+ }),
149840
+ onSome: (prompt) => promptGen.promptReviewCustom({
149841
+ prompt,
149842
+ specsDirectory: options.specsDirectory
149843
+ })
149879
149844
  }),
149880
149845
  prdFilePath: pathService.join(".lalph", "prd.yml")
149881
149846
  }), setCwd(worktree.directory), options.commandPrefix).pipe(worktree.execWithStallTimeout({
@@ -149954,24 +149919,20 @@ const run = fnUntraced(function* (options) {
149954
149919
  const feedback = yield* gh.prFeedbackMd(chosenTask.githubPrNumber);
149955
149920
  yield* fs.writeFileString(pathService.join(worktree.directory, ".lalph", "feedback.md"), feedback);
149956
149921
  }
149957
- registry.update(currentWorker.state, (s) => s.transitionTo(WorkerStatus.Instructing({ issueId: taskId })));
149958
- const instructions = yield* agentInstructor({
149959
- stallTimeout: options.stallTimeout,
149960
- commandPrefix: options.commandPrefix,
149961
- specsDirectory: options.specsDirectory,
149962
- targetBranch: options.targetBranch,
149963
- task: chosenTask.prd,
149964
- cliAgent,
149965
- githubPrNumber: chosenTask.githubPrNumber ?? void 0
149966
- }).pipe(withSpan("Main.agentInstructor"));
149967
149922
  yield* gen(function* () {
149968
149923
  registry.update(currentWorker.state, (s) => s.transitionTo(WorkerStatus.Working({ issueId: taskId })));
149969
- const exitCode = yield* agentWorker({
149924
+ const instructions = (yield* PromptGen).prompt({
149970
149925
  specsDirectory: options.specsDirectory,
149926
+ targetBranch: getOrUndefined(options.targetBranch),
149927
+ task: chosenTask.prd,
149928
+ githubPrNumber: chosenTask.githubPrNumber ?? void 0,
149929
+ gitFlow
149930
+ });
149931
+ const exitCode = yield* agentWorker({
149971
149932
  stallTimeout: options.stallTimeout,
149972
149933
  cliAgent,
149973
149934
  commandPrefix: options.commandPrefix,
149974
- instructions
149935
+ prompt: instructions
149975
149936
  }).pipe(withSpan("Main.agentWorker"));
149976
149937
  yield* log$1(`Agent exited with code: ${exitCode}`);
149977
149938
  if (options.review) {
@@ -150014,7 +149975,7 @@ const stallMinutes = integer("stall-minutes").pipe(withDescription$1("If no acti
150014
149975
  const specsDirectory = directory("specs").pipe(withDescription$1("Directory to store plan specifications. Env variable: LALPH_SPECS"), withAlias("s"), withFallbackConfig(string$4("LALPH_SPECS")), withDefault(".specs"));
150015
149976
  const commitMode = boolean("commit").pipe(withDescription$1("Commit to the target branch instead of creating PRs"));
150016
149977
  const verbose = boolean("verbose").pipe(withDescription$1("Enable verbose logging"), withAlias("v"));
150017
- const review = boolean("review").pipe(withDescription$1("Enabled the AI peer-review step"));
149978
+ const review = boolean("review").pipe(withDescription$1("Enable the AI peer-review step. Will use LALPH_REVIEW.md if present."));
150018
149979
  const reset = boolean("reset").pipe(withDescription$1("Reset the current issue source before running"), withAlias("r"));
150019
149980
  const commandRoot = make$34("lalph", {
150020
149981
  iterations,
@@ -150213,7 +150174,7 @@ const commandSource = make$34("source").pipe(withDescription("Select the issue s
150213
150174
 
150214
150175
  //#endregion
150215
150176
  //#region package.json
150216
- var version = "0.1.108";
150177
+ var version = "0.1.110";
150217
150178
 
150218
150179
  //#endregion
150219
150180
  //#region src/Tracing.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.1.108",
4
+ "version": "0.1.110",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -1,4 +1,4 @@
1
- import { Duration, Effect, Path, pipe } from "effect"
1
+ import { Duration, Effect, FileSystem, Option, Path, pipe } from "effect"
2
2
  import { PromptGen } from "../PromptGen.ts"
3
3
  import { ChildProcess } from "effect/unstable/process"
4
4
  import { Worktree } from "../Worktree.ts"
@@ -14,17 +14,30 @@ export const agentReviewer = Effect.fnUntraced(function* (options: {
14
14
  ) => ChildProcess.Command
15
15
  readonly instructions: string
16
16
  }) {
17
+ const fs = yield* FileSystem.FileSystem
17
18
  const pathService = yield* Path.Path
18
19
  const worktree = yield* Worktree
19
20
  const promptGen = yield* PromptGen
20
21
  const gitFlow = yield* GitFlow
21
22
 
23
+ const customInstructions = yield* pipe(
24
+ fs.readFileString(pathService.join(worktree.directory, "LALPH_REVIEW.md")),
25
+ Effect.option,
26
+ )
27
+
22
28
  const cliCommand = pipe(
23
29
  options.cliAgent.command({
24
- prompt: promptGen.promptReview({
25
- prompt: options.instructions,
26
- specsDirectory: options.specsDirectory,
27
- gitFlow,
30
+ prompt: Option.match(customInstructions, {
31
+ onNone: () =>
32
+ promptGen.promptReview({
33
+ prompt: options.instructions,
34
+ gitFlow,
35
+ }),
36
+ onSome: (prompt) =>
37
+ promptGen.promptReviewCustom({
38
+ prompt,
39
+ specsDirectory: options.specsDirectory,
40
+ }),
28
41
  }),
29
42
  prdFilePath: pathService.join(".lalph", "prd.yml"),
30
43
  }),
@@ -1,28 +1,22 @@
1
1
  import { Duration, Effect, Path, pipe } from "effect"
2
- import { PromptGen } from "../PromptGen.ts"
3
2
  import { ChildProcess } from "effect/unstable/process"
4
3
  import { Worktree } from "../Worktree.ts"
5
4
  import type { CliAgent } from "../domain/CliAgent.ts"
6
5
 
7
6
  export const agentWorker = Effect.fnUntraced(function* (options: {
8
- readonly specsDirectory: string
9
7
  readonly stallTimeout: Duration.Duration
10
8
  readonly cliAgent: CliAgent
11
9
  readonly commandPrefix: (
12
10
  command: ChildProcess.Command,
13
11
  ) => ChildProcess.Command
14
- readonly instructions: string
12
+ readonly prompt: string
15
13
  }) {
16
14
  const pathService = yield* Path.Path
17
15
  const worktree = yield* Worktree
18
- const promptGen = yield* PromptGen
19
16
 
20
17
  const cliCommand = pipe(
21
18
  options.cliAgent.command({
22
- prompt: promptGen.prompt({
23
- prompt: options.instructions,
24
- specsDirectory: options.specsDirectory,
25
- }),
19
+ prompt: options.prompt,
26
20
  prdFilePath: pathService.join(".lalph", "prd.yml"),
27
21
  }),
28
22
  ChildProcess.setCwd(worktree.directory),
package/src/PromptGen.ts CHANGED
@@ -137,24 +137,13 @@ challenges faced.
137
137
 
138
138
  ${prdNotes(options)}`
139
139
 
140
- const promptInstructions = (options: {
140
+ const prompt = (options: {
141
141
  readonly task: PrdIssue
142
142
  readonly targetBranch: string | undefined
143
143
  readonly specsDirectory: string
144
144
  readonly githubPrNumber: number | undefined
145
145
  readonly gitFlow: GitFlow["Service"]
146
- }) => `You are to read all of the following sections, and then output
147
- step by step instructions for another AI agent to fullfil the task. Make sure to
148
- do some quick research to understand the task before writing the instructions.
149
-
150
- Save the instructions in a markdown file called ".lalph/instructions.md".
151
-
152
- **DO NOT** start working on the task yet, only output the instructions.
153
- Do everything you can to help the agent succeed.
154
-
155
- "Help others achieve their dreams and you will achieve yours."
156
-
157
- # The task
146
+ }) => `# The task
158
147
 
159
148
  ID: ${options.task.id}
160
149
  Task: ${options.task.title}
@@ -187,18 +176,10 @@ ${options.task.description}
187
176
  - Rewrite the notes in the description to include only the key discoveries and information that could speed up future work on other tasks. Make sure to preserve important information such as specification file references.
188
177
  - If you believe the task is complete, update the \`state\` to "in-review".
189
178
 
190
- ${keyInformation(options)}`
191
-
192
- const prompt = (options: {
193
- readonly prompt: string
194
- readonly specsDirectory: string
195
- }) => `${options.prompt}
196
-
197
179
  ${keyInformation(options)}`
198
180
 
199
181
  const promptReview = (options: {
200
182
  readonly prompt: string
201
- readonly specsDirectory: string
202
183
  readonly gitFlow: GitFlow["Service"]
203
184
  }) => `A previous AI agent has completed a task from the instructions below.
204
185
 
@@ -208,9 +189,14 @@ ${options.gitFlow.reviewInstructions}
208
189
 
209
190
  # Prevous instructions (only for context, do not repeat)
210
191
 
211
- ${options.prompt}
192
+ ${options.prompt}`
212
193
 
213
- ${keyInformation(options)}`
194
+ const promptReviewCustom = (options: {
195
+ readonly prompt: string
196
+ readonly specsDirectory: string
197
+ }) => `${options.prompt}
198
+
199
+ ${prdNotes(options)}`
214
200
 
215
201
  const promptTimeout = (options: {
216
202
  readonly taskId: string
@@ -267,9 +253,9 @@ ${prdNotes(options)}`
267
253
 
268
254
  return {
269
255
  promptChoose,
270
- promptInstructions,
271
256
  prompt,
272
257
  promptReview,
258
+ promptReviewCustom,
273
259
  promptTimeout,
274
260
  planPrompt,
275
261
  } as const
@@ -24,7 +24,6 @@ import {
24
24
  resetInProgress,
25
25
  } from "../IssueSources.ts"
26
26
  import { GithubCli } from "../Github/Cli.ts"
27
- import { agentInstructor } from "../Agents/instructor.ts"
28
27
  import { agentWorker } from "../Agents/worker.ts"
29
28
  import { agentChooser } from "../Agents/chooser.ts"
30
29
  import { RunnerStalled } from "../domain/Errors.ts"
@@ -143,42 +142,33 @@ const run = Effect.fnUntraced(
143
142
  )
144
143
  }
145
144
 
146
- // 2. Generate instructions
147
- // -----------------------
148
-
149
- registry.update(currentWorker.state, (s) =>
150
- s.transitionTo(WorkerStatus.Instructing({ issueId: taskId })),
151
- )
152
-
153
- const instructions = yield* agentInstructor({
154
- stallTimeout: options.stallTimeout,
155
- commandPrefix: options.commandPrefix,
156
- specsDirectory: options.specsDirectory,
157
- targetBranch: options.targetBranch,
158
- task: chosenTask.prd,
159
- cliAgent,
160
- githubPrNumber: chosenTask.githubPrNumber ?? undefined,
161
- }).pipe(Effect.withSpan("Main.agentInstructor"))
162
-
163
145
  yield* Effect.gen(function* () {
164
146
  //
165
- // 3. Work on task
147
+ // 2. Work on task
166
148
  // -----------------------
167
149
 
168
150
  registry.update(currentWorker.state, (s) =>
169
151
  s.transitionTo(WorkerStatus.Working({ issueId: taskId })),
170
152
  )
171
153
 
172
- const exitCode = yield* agentWorker({
154
+ const promptGen = yield* PromptGen
155
+ const instructions = promptGen.prompt({
173
156
  specsDirectory: options.specsDirectory,
157
+ targetBranch: Option.getOrUndefined(options.targetBranch),
158
+ task: chosenTask.prd,
159
+ githubPrNumber: chosenTask.githubPrNumber ?? undefined,
160
+ gitFlow,
161
+ })
162
+
163
+ const exitCode = yield* agentWorker({
174
164
  stallTimeout: options.stallTimeout,
175
165
  cliAgent,
176
166
  commandPrefix: options.commandPrefix,
177
- instructions,
167
+ prompt: instructions,
178
168
  }).pipe(Effect.withSpan("Main.agentWorker"))
179
169
  yield* Effect.log(`Agent exited with code: ${exitCode}`)
180
170
 
181
- // 4. Review task
171
+ // 3. Review task
182
172
  // -----------------------
183
173
 
184
174
  if (options.review) {
@@ -302,7 +292,9 @@ const verbose = Flag.boolean("verbose").pipe(
302
292
  )
303
293
 
304
294
  const review = Flag.boolean("review").pipe(
305
- Flag.withDescription("Enabled the AI peer-review step"),
295
+ Flag.withDescription(
296
+ "Enable the AI peer-review step. Will use LALPH_REVIEW.md if present.",
297
+ ),
306
298
  )
307
299
 
308
300
  // handled in cli.ts
@@ -32,7 +32,6 @@ export class WorkerState extends Data.Class<{
32
32
  export type WorkerStatus = Data.TaggedEnum<{
33
33
  Booting: {}
34
34
  ChoosingTask: {}
35
- Instructing: { issueId: string }
36
35
  Working: { issueId: string }
37
36
  Reviewing: { issueId: string }
38
37
  Merging: { issueId: string }
@@ -1,55 +0,0 @@
1
- import { Duration, Effect, FileSystem, Option, Path, pipe } from "effect"
2
- import { PromptGen } from "../PromptGen.ts"
3
- import { ChildProcess } from "effect/unstable/process"
4
- import { Worktree } from "../Worktree.ts"
5
- import type { CliAgent } from "../domain/CliAgent.ts"
6
- import type { PrdIssue } from "../domain/PrdIssue.ts"
7
- import { makeWaitForFile } from "../shared/fs.ts"
8
- import { GitFlow } from "../GitFlow.ts"
9
-
10
- export const agentInstructor = Effect.fnUntraced(function* (options: {
11
- readonly targetBranch: Option.Option<string>
12
- readonly specsDirectory: string
13
- readonly stallTimeout: Duration.Duration
14
- readonly commandPrefix: (
15
- command: ChildProcess.Command,
16
- ) => ChildProcess.Command
17
- readonly cliAgent: CliAgent
18
- readonly task: PrdIssue
19
- readonly githubPrNumber: number | undefined
20
- }) {
21
- const fs = yield* FileSystem.FileSystem
22
- const pathService = yield* Path.Path
23
- const worktree = yield* Worktree
24
- const promptGen = yield* PromptGen
25
- const gitFlow = yield* GitFlow
26
- const waitForFile = yield* makeWaitForFile
27
-
28
- yield* pipe(
29
- options.cliAgent.command({
30
- prompt: promptGen.promptInstructions({
31
- task: options.task,
32
- targetBranch: Option.getOrUndefined(options.targetBranch),
33
- specsDirectory: options.specsDirectory,
34
- githubPrNumber: options.githubPrNumber,
35
- gitFlow,
36
- }),
37
- prdFilePath: pathService.join(".lalph", "prd.yml"),
38
- }),
39
- ChildProcess.setCwd(worktree.directory),
40
- options.commandPrefix,
41
- worktree.execWithStallTimeout({
42
- cliAgent: options.cliAgent,
43
- stallTimeout: options.stallTimeout,
44
- }),
45
- Effect.raceFirst(
46
- waitForFile(
47
- pathService.join(worktree.directory, ".lalph"),
48
- "instructions.md",
49
- ),
50
- ),
51
- )
52
- return yield* fs.readFileString(
53
- pathService.join(worktree.directory, ".lalph", "instructions.md"),
54
- )
55
- })