lalph 0.3.127 → 0.3.129
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.d.mts +1 -0
- package/dist/cli.mjs +41428 -39007
- package/dist/cli.mjs.map +1 -0
- package/package.json +26 -26
- package/src/ClankaModels.ts +11 -3
- package/src/CurrentIssueSource.ts +8 -8
- package/src/Editor.ts +2 -2
- package/src/GitFlow.ts +2 -2
- package/src/Github/Cli.ts +2 -2
- package/src/Github/TokenManager.ts +4 -4
- package/src/Github.ts +2 -2
- package/src/IssueSource.ts +2 -2
- package/src/Linear/TokenManager.ts +2 -2
- package/src/Linear.ts +14 -10
- package/src/Prd.ts +2 -2
- package/src/Presets.ts +2 -4
- package/src/Projects.ts +1 -2
- package/src/PromptGen.ts +119 -122
- package/src/Settings.ts +7 -7
- package/src/TaskTools.ts +2 -2
- package/src/Workers.ts +2 -2
- package/src/Worktree.ts +5 -5
- package/src/commands/edit.ts +13 -15
- package/src/commands/issue.ts +1 -1
- package/src/commands/plan.ts +3 -3
- package/src/domain/CliAgentPreset.ts +1 -1
- package/src/domain/GithubComment.ts +1 -1
- package/src/domain/PrdIssue.ts +8 -8
- package/src/domain/Project.ts +4 -2
- package/src/shared/schema.ts +2 -2
- package/src/Linear/LinearError.ts +0 -6
package/src/PromptGen.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { Effect, Layer,
|
|
1
|
+
import { Effect, Layer, Context } from "effect"
|
|
2
2
|
import { PrdIssue } from "./domain/PrdIssue.ts"
|
|
3
3
|
import { CurrentIssueSource } from "./CurrentIssueSource.ts"
|
|
4
4
|
import type { GitFlow } from "./GitFlow.ts"
|
|
5
5
|
|
|
6
|
-
export class PromptGen extends
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
make: Effect.gen(function* () {
|
|
10
|
-
const sourceMeta = yield* CurrentIssueSource
|
|
6
|
+
export class PromptGen extends Context.Service<PromptGen>()("lalph/PromptGen", {
|
|
7
|
+
make: Effect.gen(function* () {
|
|
8
|
+
const sourceMeta = yield* CurrentIssueSource
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const prdNotes = (options?: {
|
|
11
|
+
readonly specsDirectory?: string | undefined
|
|
12
|
+
}) => `## prd.yml file
|
|
15
13
|
|
|
16
14
|
**Important:** Wait 5 seconds between edits to allow the system to update the prd.yml file.
|
|
17
15
|
If adding more than 10 tasks, wait 10 seconds.
|
|
@@ -51,9 +49,9 @@ To remove a task, simply delete the item from the prd.yml file.
|
|
|
51
49
|
${JSON.stringify(PrdIssue.jsonSchema, null, 2)}
|
|
52
50
|
\`\`\``
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
const promptChoose = (options: {
|
|
53
|
+
readonly gitFlow: GitFlow["Service"]
|
|
54
|
+
}) => `Your job is to choose the next task to work on from the prd.yml file and save it in a task.json file.
|
|
57
55
|
**DO NOT** implement the task yet.
|
|
58
56
|
|
|
59
57
|
The following instructions should be done without interaction or asking for permission.
|
|
@@ -80,18 +78,18 @@ The following instructions should be done without interaction or asking for perm
|
|
|
80
78
|
"githubPrNumber": null
|
|
81
79
|
}
|
|
82
80
|
\`\`\`${
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
options.gitFlow.requiresGithubPr
|
|
82
|
+
? `
|
|
85
83
|
|
|
86
84
|
Set \`githubPrNumber\` to the PR number if one exists, otherwise use \`null\`.
|
|
87
85
|
`
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
: "\n\nLeave `githubPrNumber` as null."
|
|
87
|
+
}
|
|
90
88
|
`
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
const promptChooseClanka = (options: {
|
|
91
|
+
readonly gitFlow: GitFlow["Service"]
|
|
92
|
+
}) => `- Use the "listEligibleTasks" function to view the list of tasks that you can start working on.
|
|
95
93
|
- **NO NOT PARSE THE yaml OUTPUT IN ANY WAY**
|
|
96
94
|
- **DO NOT** implement the task yet.
|
|
97
95
|
- **DO NOT** use the "delegate" function for any step in this workflow
|
|
@@ -113,18 +111,18 @@ ${
|
|
|
113
111
|
: "\n Leave `githubPrNumber` as null."
|
|
114
112
|
}
|
|
115
113
|
`
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
const promptChooseRalph = (options: {
|
|
115
|
+
readonly specFile: string
|
|
116
|
+
}) => `- Read the spec file at \`${options.specFile}\` to understand the current project.
|
|
119
117
|
- Choose the next most important task to work on from the specification.
|
|
120
118
|
- If all of the tasks are complete then do nothing more. Otherwise, write the chosen task in a ".lalph/task.md" file.
|
|
121
119
|
|
|
122
120
|
Note: The task should be a specific, actionable item that can be completed in a reasonable amount of time.
|
|
123
121
|
`
|
|
124
122
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
const keyInformation = (options: {
|
|
124
|
+
readonly specsDirectory: string
|
|
125
|
+
}) => `## Important: Recording key information
|
|
128
126
|
|
|
129
127
|
This session will time out after a certain period, so make sure to record
|
|
130
128
|
key information that could speed up future work on the task in the description.
|
|
@@ -145,9 +143,9 @@ challenges faced.
|
|
|
145
143
|
|
|
146
144
|
${prdNotes(options)}`
|
|
147
145
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
const systemClanka = (options: {
|
|
147
|
+
readonly specsDirectory: string
|
|
148
|
+
}) => `## Important: Recording key information
|
|
151
149
|
|
|
152
150
|
This session will time out after a certain period, so make sure to record
|
|
153
151
|
key information that could speed up future work on the task in the description.
|
|
@@ -168,13 +166,13 @@ challenges faced.
|
|
|
168
166
|
|
|
169
167
|
${taskGuidelines(options)}`
|
|
170
168
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
169
|
+
const prompt = (options: {
|
|
170
|
+
readonly task: PrdIssue
|
|
171
|
+
readonly targetBranch: string | undefined
|
|
172
|
+
readonly specsDirectory: string
|
|
173
|
+
readonly githubPrNumber: number | undefined
|
|
174
|
+
readonly gitFlow: GitFlow["Service"]
|
|
175
|
+
}) => `# ${options.task.title}
|
|
178
176
|
|
|
179
177
|
Task ID: ${options.task.id}
|
|
180
178
|
|
|
@@ -183,10 +181,10 @@ ${options.task.description}
|
|
|
183
181
|
### Instructions
|
|
184
182
|
|
|
185
183
|
Your job is to implement the task described above.${
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
184
|
+
options.task.description.includes(options.specsDirectory)
|
|
185
|
+
? `\nMake sure to review the prd.yml for any key information that may help you with this task.`
|
|
186
|
+
: ""
|
|
187
|
+
}
|
|
190
188
|
|
|
191
189
|
1. ${options.gitFlow.setupInstructions(options)}
|
|
192
190
|
2. Implement the task.
|
|
@@ -199,24 +197,24 @@ Your job is to implement the task described above.${
|
|
|
199
197
|
\`description\`. More details below.
|
|
200
198
|
3. Run any checks / feedback loops, such as type checks, unit tests, or linting.
|
|
201
199
|
4. ${options.gitFlow.commitInstructions({
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
200
|
+
githubPrInstructions: sourceMeta.githubPrInstructions,
|
|
201
|
+
githubPrNumber: options.githubPrNumber,
|
|
202
|
+
taskId: options.task.id ?? "unknown",
|
|
203
|
+
targetBranch: options.targetBranch,
|
|
204
|
+
})}
|
|
207
205
|
5. **After ${options.gitFlow.requiresGithubPr ? "pushing" : "committing"}** your changes, update the prd.yml to reflect any changes in the task state.
|
|
208
206
|
- 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.
|
|
209
207
|
- If you believe the task is complete, update the \`state\` to "in-review".
|
|
210
208
|
|
|
211
209
|
${keyInformation(options)}`
|
|
212
210
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
211
|
+
const promptClanka = (options: {
|
|
212
|
+
readonly task: PrdIssue
|
|
213
|
+
readonly targetBranch: string | undefined
|
|
214
|
+
readonly specsDirectory: string
|
|
215
|
+
readonly githubPrNumber: number | undefined
|
|
216
|
+
readonly gitFlow: GitFlow["Service"]
|
|
217
|
+
}) => `# ${options.task.title}
|
|
220
218
|
|
|
221
219
|
Task ID: ${options.task.id}
|
|
222
220
|
|
|
@@ -225,10 +223,10 @@ ${options.task.description}
|
|
|
225
223
|
### Instructions
|
|
226
224
|
|
|
227
225
|
All steps must be done before the task can be considered complete.${
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
226
|
+
options.task.description.includes(options.specsDirectory)
|
|
227
|
+
? `\nMake sure to review the previous tasks (using "listTasks") for any key information that may help you with this task.`
|
|
228
|
+
: ""
|
|
229
|
+
}
|
|
232
230
|
|
|
233
231
|
1. ${options.gitFlow.setupInstructions(options)}
|
|
234
232
|
2. Implement the task.
|
|
@@ -238,21 +236,21 @@ All steps must be done before the task can be considered complete.${
|
|
|
238
236
|
\`description\`. More details below.
|
|
239
237
|
3. Run any checks / feedback loops, such as type checks, unit tests, or linting.
|
|
240
238
|
4. ${options.gitFlow.commitInstructions({
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
239
|
+
githubPrInstructions: sourceMeta.githubPrInstructions,
|
|
240
|
+
githubPrNumber: options.githubPrNumber,
|
|
241
|
+
taskId: options.task.id ?? "unknown",
|
|
242
|
+
targetBranch: options.targetBranch,
|
|
243
|
+
})}
|
|
246
244
|
5. **After ${options.gitFlow.requiresGithubPr ? "pushing" : "committing"}** your changes, update current task to reflect any changes in the task state.
|
|
247
245
|
- 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.
|
|
248
246
|
- If you believe the task is complete, update the \`state\` to "in-review".`
|
|
249
247
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
248
|
+
const promptRalph = (options: {
|
|
249
|
+
readonly task: string
|
|
250
|
+
readonly targetBranch: string | undefined
|
|
251
|
+
readonly specFile: string
|
|
252
|
+
readonly gitFlow: GitFlow["Service"]
|
|
253
|
+
}) => `${options.task}
|
|
256
254
|
|
|
257
255
|
## Project specification
|
|
258
256
|
|
|
@@ -268,16 +266,16 @@ All steps must be done before the task can be considered complete.
|
|
|
268
266
|
3. Run any checks / feedback loops, such as type checks, unit tests, or linting.
|
|
269
267
|
4. Update the specification implementation plan at \`${options.specFile}\` to reflect changes to task states.
|
|
270
268
|
4. ${options.gitFlow.commitInstructions({
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
269
|
+
githubPrInstructions: sourceMeta.githubPrInstructions,
|
|
270
|
+
githubPrNumber: undefined,
|
|
271
|
+
taskId: "unknown",
|
|
272
|
+
targetBranch: options.targetBranch,
|
|
273
|
+
})}
|
|
276
274
|
`
|
|
277
275
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
276
|
+
const promptResearch = (options: {
|
|
277
|
+
readonly task: PrdIssue
|
|
278
|
+
}) => `Your job is to gather all the necessary information and details to complete the task described below. Do not make any code changes yet, your job is just to research and gather information.
|
|
281
279
|
|
|
282
280
|
In the final report:
|
|
283
281
|
|
|
@@ -293,10 +291,10 @@ Title: ${options.task.title}
|
|
|
293
291
|
|
|
294
292
|
${options.task.description}`
|
|
295
293
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
294
|
+
const promptReview = (options: {
|
|
295
|
+
readonly prompt: string
|
|
296
|
+
readonly gitFlow: GitFlow["Service"]
|
|
297
|
+
}) => `A previous engineer has completed a task from the instructions below.
|
|
300
298
|
|
|
301
299
|
You job is to meticulously review their work to ensure it meets the task requirements,
|
|
302
300
|
follows best practices, and maintains high code quality. You should be extremely thorough
|
|
@@ -315,10 +313,10 @@ ${options.gitFlow.reviewInstructions}
|
|
|
315
313
|
|
|
316
314
|
${options.prompt}`
|
|
317
315
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
316
|
+
const promptTimeout = (options: {
|
|
317
|
+
readonly taskId: string
|
|
318
|
+
readonly specsDirectory: string
|
|
319
|
+
}) => `Your earlier attempt to complete the task with id \`${options.taskId}\` took too
|
|
322
320
|
long and has timed out. You can find the task details in the prd.yml file.
|
|
323
321
|
|
|
324
322
|
The following instructions should be done without interaction or asking for
|
|
@@ -336,10 +334,10 @@ permission.
|
|
|
336
334
|
|
|
337
335
|
${prdNotes(options)}`
|
|
338
336
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
337
|
+
const promptTimeoutRalph = (options: {
|
|
338
|
+
readonly task: string
|
|
339
|
+
readonly specFile: string
|
|
340
|
+
}) => `Your earlier attempt to complete the following task took too
|
|
343
341
|
long and has timed out.
|
|
344
342
|
|
|
345
343
|
The following instructions should be done without interaction or asking for
|
|
@@ -352,10 +350,10 @@ permission.
|
|
|
352
350
|
3. Commit the changes to the specification file without pushing.
|
|
353
351
|
`
|
|
354
352
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
353
|
+
const promptTimeoutClanka = (options: {
|
|
354
|
+
readonly taskId: string
|
|
355
|
+
readonly specsDirectory: string
|
|
356
|
+
}) => `Your earlier attempt to complete the task with id \`${options.taskId}\` took too
|
|
359
357
|
long and has timed out.
|
|
360
358
|
|
|
361
359
|
The following instructions should be done without interaction or asking for
|
|
@@ -369,10 +367,10 @@ permission.
|
|
|
369
367
|
- Make sure to setup task dependencies using the \`blockedBy\` field as needed.
|
|
370
368
|
5. If any specifications need updating based on your new understanding, update them.`
|
|
371
369
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
370
|
+
const planPrompt = (options: {
|
|
371
|
+
readonly plan: string
|
|
372
|
+
readonly specsDirectory: string
|
|
373
|
+
}) => `<request>
|
|
376
374
|
${options.plan}
|
|
377
375
|
</request>
|
|
378
376
|
|
|
@@ -434,10 +432,10 @@ ${options.plan}
|
|
|
434
432
|
\`${options.specsDirectory}\` directory, along with a brief overview of the specification.
|
|
435
433
|
If the README.md file does not exist, create it.`
|
|
436
434
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
435
|
+
const promptPlanTasks = (options: {
|
|
436
|
+
readonly specsDirectory: string
|
|
437
|
+
readonly specificationPath: string
|
|
438
|
+
}) => `Your job is to convert the implementation plan in the specification file at
|
|
441
439
|
\`${options.specificationPath}\` into tasks in the prd.yml file. Read the "### Adding tasks"
|
|
442
440
|
section below extremely carefully for guidelines on creating tasks.
|
|
443
441
|
|
|
@@ -455,10 +453,10 @@ setup dependencies between the tasks using the \`blockedBy\` field.
|
|
|
455
453
|
|
|
456
454
|
${prdNotes(options)}`
|
|
457
455
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
456
|
+
const promptPlanTasksClanka = (options: {
|
|
457
|
+
readonly specsDirectory: string
|
|
458
|
+
readonly specificationPath: string
|
|
459
|
+
}) => `Your job is to convert the implementation plan in the specification file at
|
|
462
460
|
\`${options.specificationPath}\` into tasks.
|
|
463
461
|
|
|
464
462
|
Before starting, read the entire task list to understand the context of existing tasks
|
|
@@ -472,26 +470,25 @@ Make sure to setup dependencies between the tasks using the \`blockedBy\` field.
|
|
|
472
470
|
|
|
473
471
|
**Important:** You are only creating or updating a plan, not implementing any tasks yet.`
|
|
474
472
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
) {
|
|
473
|
+
return {
|
|
474
|
+
promptChoose,
|
|
475
|
+
promptChooseClanka,
|
|
476
|
+
promptChooseRalph,
|
|
477
|
+
prompt,
|
|
478
|
+
promptRalph,
|
|
479
|
+
promptClanka,
|
|
480
|
+
promptResearch,
|
|
481
|
+
promptReview,
|
|
482
|
+
promptTimeout,
|
|
483
|
+
promptTimeoutClanka,
|
|
484
|
+
promptTimeoutRalph,
|
|
485
|
+
planPrompt,
|
|
486
|
+
promptPlanTasks,
|
|
487
|
+
promptPlanTasksClanka,
|
|
488
|
+
systemClanka,
|
|
489
|
+
} as const
|
|
490
|
+
}),
|
|
491
|
+
}) {
|
|
495
492
|
static layer = Layer.effect(this, this.make).pipe(
|
|
496
493
|
Layer.provide(CurrentIssueSource.layer),
|
|
497
494
|
)
|
package/src/Settings.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// oxlint-disable typescript/no-explicit-any
|
|
2
|
-
import { Cache, Effect, Layer, Option, Schema,
|
|
2
|
+
import { Cache, Effect, Layer, Option, Schema, Context } from "effect"
|
|
3
3
|
import { KeyValueStore } from "effect/unstable/persistence"
|
|
4
4
|
import { layerKvs, ProjectsKvs } from "./Kvs.ts"
|
|
5
5
|
import { allCliAgents } from "./domain/CliAgent.ts"
|
|
6
6
|
import { Project, ProjectId } from "./domain/Project.ts"
|
|
7
7
|
import { Reactivity } from "effect/unstable/reactivity"
|
|
8
8
|
|
|
9
|
-
export class Settings extends
|
|
9
|
+
export class Settings extends Context.Service<Settings>()("lalph/Settings", {
|
|
10
10
|
make: Effect.gen(function* () {
|
|
11
11
|
const kvs = yield* KeyValueStore.KeyValueStore
|
|
12
12
|
const projectKvs = yield* ProjectsKvs
|
|
@@ -27,9 +27,9 @@ export class Settings extends ServiceMap.Service<Settings>()("lalph/Settings", {
|
|
|
27
27
|
readonly projectId: ProjectId
|
|
28
28
|
readonly setting: ProjectSetting<string, Schema.Codec<any, any>>
|
|
29
29
|
}) {
|
|
30
|
-
const services = yield* projectKvs.
|
|
30
|
+
const services = yield* projectKvs.contextEffect(options.projectId)
|
|
31
31
|
const store = KeyValueStore.toSchemaStore(
|
|
32
|
-
|
|
32
|
+
Context.get(services, KeyValueStore.KeyValueStore),
|
|
33
33
|
options.setting.schema,
|
|
34
34
|
)
|
|
35
35
|
return yield* Effect.orDie(store.get(options.setting.name))
|
|
@@ -82,9 +82,9 @@ export class Settings extends ServiceMap.Service<Settings>()("lalph/Settings", {
|
|
|
82
82
|
value: Option.Option<S["Type"]>,
|
|
83
83
|
) {
|
|
84
84
|
const projectId = yield* CurrentProjectId
|
|
85
|
-
const services = yield* projectKvs.
|
|
85
|
+
const services = yield* projectKvs.contextEffect(projectId)
|
|
86
86
|
const s = KeyValueStore.toSchemaStore(
|
|
87
|
-
|
|
87
|
+
Context.get(services, KeyValueStore.KeyValueStore),
|
|
88
88
|
setting.schema,
|
|
89
89
|
)
|
|
90
90
|
const setCache = Cache.set(
|
|
@@ -150,7 +150,7 @@ export class Settings extends ServiceMap.Service<Settings>()("lalph/Settings", {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
export class CurrentProjectId extends
|
|
153
|
+
export class CurrentProjectId extends Context.Service<
|
|
154
154
|
CurrentProjectId,
|
|
155
155
|
ProjectId
|
|
156
156
|
>()("lalph/CurrentProjectId") {}
|
package/src/TaskTools.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Deferred, Effect, Random, Schema,
|
|
1
|
+
import { Deferred, Effect, Random, Schema, Context, Struct } from "effect"
|
|
2
2
|
import { Tool, Toolkit } from "effect/unstable/ai"
|
|
3
3
|
import { PrdIssue } from "./domain/PrdIssue.ts"
|
|
4
4
|
import { IssueSource } from "./IssueSource.ts"
|
|
5
5
|
import { CurrentProjectId } from "./Settings.ts"
|
|
6
6
|
import * as Yaml from "yaml"
|
|
7
7
|
|
|
8
|
-
export class ChosenTaskDeferred extends
|
|
8
|
+
export class ChosenTaskDeferred extends Context.Reference(
|
|
9
9
|
"lalph/TaskTools/ChosenTaskDeferred",
|
|
10
10
|
{
|
|
11
11
|
defaultValue: Deferred.makeUnsafe<{
|
package/src/Workers.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
FiberMap,
|
|
6
6
|
HashMap,
|
|
7
7
|
pipe,
|
|
8
|
-
|
|
8
|
+
Context,
|
|
9
9
|
Stream,
|
|
10
10
|
} from "effect"
|
|
11
11
|
import { Atom, AtomRegistry } from "effect/unstable/reactivity"
|
|
@@ -57,7 +57,7 @@ export const activeWorkerLoggingAtom = Atom.make(
|
|
|
57
57
|
}),
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
-
export class CurrentWorkerState extends
|
|
60
|
+
export class CurrentWorkerState extends Context.Service<
|
|
61
61
|
CurrentWorkerState,
|
|
62
62
|
{
|
|
63
63
|
readonly state: Atom.Writable<WorkerState>
|
package/src/Worktree.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
Path,
|
|
11
11
|
PlatformError,
|
|
12
12
|
Schema,
|
|
13
|
-
|
|
13
|
+
Context,
|
|
14
14
|
Stream,
|
|
15
15
|
} from "effect"
|
|
16
16
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
|
|
@@ -23,7 +23,7 @@ import { parseBranch } from "./shared/git.ts"
|
|
|
23
23
|
import { resolveLalphDirectory } from "./shared/lalphDirectory.ts"
|
|
24
24
|
import { withStallTimeout } from "./shared/stream.ts"
|
|
25
25
|
|
|
26
|
-
export class Worktree extends
|
|
26
|
+
export class Worktree extends Context.Service<Worktree>()("lalph/Worktree", {
|
|
27
27
|
make: Effect.gen(function* () {
|
|
28
28
|
const fs = yield* FileSystem.FileSystem
|
|
29
29
|
const pathService = yield* Path.Path
|
|
@@ -243,7 +243,7 @@ const makeExecHelpers = Effect.fnUntraced(function* (options: {
|
|
|
243
243
|
|
|
244
244
|
const execWithOutput = (options: { readonly cliAgent: AnyCliAgent }) =>
|
|
245
245
|
Effect.fnUntraced(function* (command: ChildProcess.Command) {
|
|
246
|
-
const handle = yield* provide(command
|
|
246
|
+
const handle = yield* provide(command)
|
|
247
247
|
|
|
248
248
|
yield* handle.all.pipe(
|
|
249
249
|
Stream.decodeText(),
|
|
@@ -265,7 +265,7 @@ const makeExecHelpers = Effect.fnUntraced(function* (options: {
|
|
|
265
265
|
const registry = yield* AtomRegistry.AtomRegistry
|
|
266
266
|
const worker = yield* CurrentWorkerState
|
|
267
267
|
|
|
268
|
-
const handle = yield* provide(command
|
|
268
|
+
const handle = yield* provide(command)
|
|
269
269
|
|
|
270
270
|
yield* handle.all.pipe(
|
|
271
271
|
Stream.decodeText(),
|
|
@@ -297,7 +297,7 @@ const makeExecHelpers = Effect.fnUntraced(function* (options: {
|
|
|
297
297
|
const registry = yield* AtomRegistry.AtomRegistry
|
|
298
298
|
const worker = yield* CurrentWorkerState
|
|
299
299
|
|
|
300
|
-
const handle = yield* provide(command
|
|
300
|
+
const handle = yield* provide(command)
|
|
301
301
|
|
|
302
302
|
yield* handle.all.pipe(
|
|
303
303
|
Stream.decodeText(),
|
package/src/commands/edit.ts
CHANGED
|
@@ -4,24 +4,22 @@ import { Prd } from "../Prd.ts"
|
|
|
4
4
|
import { layerProjectIdPrompt } from "../Projects.ts"
|
|
5
5
|
import { Editor } from "../Editor.ts"
|
|
6
6
|
|
|
7
|
-
const handler = Command.withHandler(
|
|
8
|
-
Effect.fnUntraced(
|
|
9
|
-
function* () {
|
|
10
|
-
const prd = yield* Prd
|
|
11
|
-
const editor = yield* Editor
|
|
12
|
-
yield* editor.edit(prd.path)
|
|
13
|
-
},
|
|
14
|
-
Effect.provide([
|
|
15
|
-
Prd.layerLocalProvided.pipe(Layer.provideMerge(layerProjectIdPrompt)),
|
|
16
|
-
Editor.layer,
|
|
17
|
-
]),
|
|
18
|
-
),
|
|
19
|
-
)
|
|
20
|
-
|
|
21
7
|
export const commandEdit = Command.make("edit").pipe(
|
|
22
8
|
Command.withDescription(
|
|
23
9
|
"Open the selected project's .lalph/prd.yml in your editor.",
|
|
24
10
|
),
|
|
25
11
|
Command.withAlias("e"),
|
|
26
|
-
|
|
12
|
+
Command.withHandler(
|
|
13
|
+
Effect.fnUntraced(
|
|
14
|
+
function* () {
|
|
15
|
+
const prd = yield* Prd
|
|
16
|
+
const editor = yield* Editor
|
|
17
|
+
yield* editor.edit(prd.path)
|
|
18
|
+
},
|
|
19
|
+
Effect.provide([
|
|
20
|
+
Prd.layerLocalProvided.pipe(Layer.provideMerge(layerProjectIdPrompt)),
|
|
21
|
+
Editor.layer,
|
|
22
|
+
]),
|
|
23
|
+
),
|
|
24
|
+
),
|
|
27
25
|
)
|
package/src/commands/issue.ts
CHANGED
package/src/commands/plan.ts
CHANGED
|
@@ -62,9 +62,9 @@ export const commandPlan = Command.make("plan", {
|
|
|
62
62
|
const editor = yield* Editor
|
|
63
63
|
const fs = yield* FileSystem.FileSystem
|
|
64
64
|
|
|
65
|
-
const thePlan = yield*
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
const thePlan = yield* Option.match(file, {
|
|
66
|
+
onNone: () => editor.editTemp({ suffix: ".md" }),
|
|
67
|
+
onSome: (path) => fs.readFileString(path).pipe(Effect.asSome),
|
|
68
68
|
})
|
|
69
69
|
|
|
70
70
|
if (Option.isNone(thePlan)) return
|
|
@@ -16,7 +16,7 @@ export class CliAgentPreset extends Schema.Class<CliAgentPreset>(
|
|
|
16
16
|
extraArgs: Schema.Array(Schema.String),
|
|
17
17
|
sourceMetadata: Schema.Record(Schema.String, Schema.Any),
|
|
18
18
|
}) {
|
|
19
|
-
static defaultId = CliAgentPresetId.
|
|
19
|
+
static defaultId = CliAgentPresetId.make("default")
|
|
20
20
|
|
|
21
21
|
decodeMetadata<S extends Schema.Top>(
|
|
22
22
|
source: string,
|
package/src/domain/PrdIssue.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Schema, Array, Equal, SchemaGetter } from "effect"
|
|
1
|
+
import { Schema, Array, Equal, SchemaGetter, Effect } from "effect"
|
|
2
2
|
import * as Yaml from "yaml"
|
|
3
3
|
import { withEncodeDefault } from "../shared/schema.ts"
|
|
4
4
|
|
|
@@ -9,19 +9,19 @@ export class PrdIssue extends Schema.Class<PrdIssue>("PrdIssue")({
|
|
|
9
9
|
"The unique identifier of the issue. If null, it is considered a new issue.",
|
|
10
10
|
documentation: "The unique identifier of the issue.",
|
|
11
11
|
})
|
|
12
|
-
.pipe(withEncodeDefault((
|
|
12
|
+
.pipe(withEncodeDefault(Effect.succeed(null))),
|
|
13
13
|
title: Schema.String.annotate({
|
|
14
14
|
description: "The title of the issue",
|
|
15
15
|
}),
|
|
16
16
|
description: Schema.String.annotate({
|
|
17
17
|
description: "The description of the issue in markdown format.",
|
|
18
|
-
}).pipe(withEncodeDefault((
|
|
18
|
+
}).pipe(withEncodeDefault(Effect.succeed(""))),
|
|
19
19
|
priority: Schema.Finite.annotate({
|
|
20
20
|
description:
|
|
21
21
|
"The priority of the issue. 0 = No priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low.",
|
|
22
22
|
documentation:
|
|
23
23
|
"The priority of the issue. 0 = No priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low.",
|
|
24
|
-
}).pipe(withEncodeDefault((
|
|
24
|
+
}).pipe(withEncodeDefault(Effect.succeed(3))),
|
|
25
25
|
estimate: Schema.NullOr(Schema.Finite)
|
|
26
26
|
.annotate({
|
|
27
27
|
description:
|
|
@@ -29,7 +29,7 @@ export class PrdIssue extends Schema.Class<PrdIssue>("PrdIssue")({
|
|
|
29
29
|
documentation:
|
|
30
30
|
"Null if no estimate is set. Roughly 1 point = 1 hour of work.",
|
|
31
31
|
})
|
|
32
|
-
.pipe(withEncodeDefault((
|
|
32
|
+
.pipe(withEncodeDefault(Effect.succeed(null))),
|
|
33
33
|
state: Schema.Literals([
|
|
34
34
|
"backlog",
|
|
35
35
|
"todo",
|
|
@@ -41,18 +41,18 @@ export class PrdIssue extends Schema.Class<PrdIssue>("PrdIssue")({
|
|
|
41
41
|
description: "The state of the issue.",
|
|
42
42
|
documentation: "The state of the issue.",
|
|
43
43
|
})
|
|
44
|
-
.pipe(withEncodeDefault((
|
|
44
|
+
.pipe(withEncodeDefault(Effect.succeed("todo"))),
|
|
45
45
|
blockedBy: Schema.Array(Schema.String)
|
|
46
46
|
.annotate({
|
|
47
47
|
description:
|
|
48
48
|
"An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on.",
|
|
49
49
|
documentation: "An array of issue IDs that block this issue.",
|
|
50
50
|
})
|
|
51
|
-
.pipe(withEncodeDefault((
|
|
51
|
+
.pipe(withEncodeDefault(Effect.succeed([]))),
|
|
52
52
|
autoMerge: Schema.Boolean.annotate({
|
|
53
53
|
description:
|
|
54
54
|
"Whether the issue should be auto-merged when complete. Read-only field",
|
|
55
|
-
}).pipe(withEncodeDefault((
|
|
55
|
+
}).pipe(withEncodeDefault(Effect.succeed(false))),
|
|
56
56
|
}) {
|
|
57
57
|
static FromInput = Schema.Union([
|
|
58
58
|
Schema.String,
|