lalph 0.2.2 → 0.2.4
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 +65 -56
- package/package.json +1 -1
- package/src/Projects.ts +47 -22
- package/src/commands/issue.ts +1 -5
- package/src/commands/plan.ts +26 -13
- package/src/commands/projects/add.ts +2 -10
- package/src/commands/projects/edit.ts +9 -49
- package/src/commands/projects/rm.ts +2 -0
package/dist/cli.mjs
CHANGED
|
@@ -7188,7 +7188,7 @@ const getOption = /* @__PURE__ */ dual(2, (self, service) => {
|
|
|
7188
7188
|
* @since 4.0.0
|
|
7189
7189
|
* @category Utils
|
|
7190
7190
|
*/
|
|
7191
|
-
const merge$
|
|
7191
|
+
const merge$6 = /* @__PURE__ */ dual(2, (self, that) => {
|
|
7192
7192
|
if (self.mapUnsafe.size === 0) return that;
|
|
7193
7193
|
if (that.mapUnsafe.size === 0) return self;
|
|
7194
7194
|
const map = new Map(self.mapUnsafe);
|
|
@@ -9159,7 +9159,7 @@ const servicesWith$1 = (f) => withFiber$1((fiber) => f(fiber.services));
|
|
|
9159
9159
|
/** @internal */
|
|
9160
9160
|
const provideServices$1 = /* @__PURE__ */ dual(2, (self, services) => {
|
|
9161
9161
|
if (effectIsExit(self)) return self;
|
|
9162
|
-
return updateServices$1(self, merge$
|
|
9162
|
+
return updateServices$1(self, merge$6(services));
|
|
9163
9163
|
});
|
|
9164
9164
|
/** @internal */
|
|
9165
9165
|
const provideService$1 = function() {
|
|
@@ -11960,6 +11960,38 @@ const mergeAllEffect = (layers, memoMap, scope) => {
|
|
|
11960
11960
|
* @category zipping
|
|
11961
11961
|
*/
|
|
11962
11962
|
const mergeAll = (...layers) => fromBuild((memoMap, scope) => mergeAllEffect(layers, memoMap, scope));
|
|
11963
|
+
/**
|
|
11964
|
+
* Merges this layer with the specified layer concurrently, producing a new layer with combined input and output types.
|
|
11965
|
+
*
|
|
11966
|
+
* This is a binary version of `mergeAll` that merges exactly two layers or one layer with an array of layers.
|
|
11967
|
+
* The layers are built concurrently and their outputs are combined.
|
|
11968
|
+
*
|
|
11969
|
+
* @example
|
|
11970
|
+
* ```ts
|
|
11971
|
+
* import { Effect, Layer, ServiceMap } from "effect"
|
|
11972
|
+
*
|
|
11973
|
+
* class Database extends ServiceMap.Service<Database, {
|
|
11974
|
+
* readonly query: (sql: string) => Effect.Effect<string>
|
|
11975
|
+
* }>()("Database") {}
|
|
11976
|
+
*
|
|
11977
|
+
* class Logger extends ServiceMap.Service<Logger, {
|
|
11978
|
+
* readonly log: (msg: string) => Effect.Effect<void>
|
|
11979
|
+
* }>()("Logger") {}
|
|
11980
|
+
*
|
|
11981
|
+
* const dbLayer = Layer.succeed(Database)({
|
|
11982
|
+
* query: (sql: string) => Effect.succeed("result")
|
|
11983
|
+
* })
|
|
11984
|
+
* const loggerLayer = Layer.succeed(Logger)({
|
|
11985
|
+
* log: (msg: string) => Effect.sync(() => console.log(msg))
|
|
11986
|
+
* })
|
|
11987
|
+
*
|
|
11988
|
+
* const mergedLayer = Layer.merge(dbLayer, loggerLayer)
|
|
11989
|
+
* ```
|
|
11990
|
+
*
|
|
11991
|
+
* @since 2.0.0
|
|
11992
|
+
* @category zipping
|
|
11993
|
+
*/
|
|
11994
|
+
const merge$5 = /* @__PURE__ */ dual(2, (self, that) => mergeAll(self, ...Array.isArray(that) ? that : [that]));
|
|
11963
11995
|
const provideWith = (self, that, f) => fromBuild((memoMap, scope) => flatMap$4(Array.isArray(that) ? mergeAllEffect(that, memoMap, scope) : that.build(memoMap, scope), (context) => self.build(memoMap, scope).pipe(provideServices$1(context), map$11((merged) => f(merged, context)))));
|
|
11964
11996
|
/**
|
|
11965
11997
|
* Feeds the output services of this builder into the input of the specified
|
|
@@ -12102,7 +12134,7 @@ const provide$3 = /* @__PURE__ */ dual(2, (self, that) => provideWith(self, that
|
|
|
12102
12134
|
* @since 2.0.0
|
|
12103
12135
|
* @category utils
|
|
12104
12136
|
*/
|
|
12105
|
-
const provideMerge = /* @__PURE__ */ dual(2, (self, that) => provideWith(self, that, (self, that) => merge$
|
|
12137
|
+
const provideMerge = /* @__PURE__ */ dual(2, (self, that) => provideWith(self, that, (self, that) => merge$6(that, self)));
|
|
12106
12138
|
/**
|
|
12107
12139
|
* Constructs a layer dynamically based on the output of this layer.
|
|
12108
12140
|
*
|
|
@@ -50856,7 +50888,7 @@ const TypeId$27 = "~effect/Cache";
|
|
|
50856
50888
|
*/
|
|
50857
50889
|
const makeWith$1 = (options) => servicesWith$1((services) => {
|
|
50858
50890
|
const self = Object.create(Proto$12);
|
|
50859
|
-
self.lookup = (key) => updateServices$1(options.lookup(key), (input) => merge$
|
|
50891
|
+
self.lookup = (key) => updateServices$1(options.lookup(key), (input) => merge$6(services, input));
|
|
50860
50892
|
self.map = make$45();
|
|
50861
50893
|
self.capacity = options.capacity;
|
|
50862
50894
|
self.timeToLive = options.timeToLive ? (exit, key) => fromDurationInputUnsafe(options.timeToLive(exit, key)) : defaultTimeToLive;
|
|
@@ -58544,7 +58576,7 @@ const SpanNameGenerator$1 = /* @__PURE__ */ Reference("effect/http/HttpClient/Sp
|
|
|
58544
58576
|
/**
|
|
58545
58577
|
* @since 4.0.0
|
|
58546
58578
|
*/
|
|
58547
|
-
const layerMergedServices = (effect) => effect$1(HttpClient)(servicesWith((services) => map$8(effect, (client) => transformResponse(client, updateServices((input) => merge$
|
|
58579
|
+
const layerMergedServices = (effect) => effect$1(HttpClient)(servicesWith((services) => map$8(effect, (client) => transformResponse(client, updateServices((input) => merge$6(services, input))))));
|
|
58548
58580
|
const responseRegistry = /* @__PURE__ */ (() => {
|
|
58549
58581
|
if ("FinalizationRegistry" in globalThis && globalThis.FinalizationRegistry) {
|
|
58550
58582
|
const registry = /* @__PURE__ */ new FinalizationRegistry((controller) => {
|
|
@@ -59849,7 +59881,7 @@ const fromWebSocket = (acquire, options) => withFiber((fiber) => {
|
|
|
59849
59881
|
latch.openUnsafe();
|
|
59850
59882
|
if (opts?.onOpen) yield* opts.onOpen;
|
|
59851
59883
|
return yield* join(fiberSet).pipe(catchFilter(SocketCloseError.filterClean((_) => !closeCodeIsError(_)), (_) => void_$1));
|
|
59852
|
-
})).pipe(updateServices((input) => merge$
|
|
59884
|
+
})).pipe(updateServices((input) => merge$6(acquireContext, input)), ensuring$2(sync(() => {
|
|
59853
59885
|
latch.closeUnsafe();
|
|
59854
59886
|
currentWS = void 0;
|
|
59855
59887
|
})));
|
|
@@ -151176,7 +151208,7 @@ const agentTimeout = fnUntraced(function* (options) {
|
|
|
151176
151208
|
//#region src/Projects.ts
|
|
151177
151209
|
const layerProjectIdPrompt = effect$1(CurrentProjectId, gen(function* () {
|
|
151178
151210
|
return (yield* selectProject).id;
|
|
151179
|
-
})).pipe(provide$3(Settings.layer));
|
|
151211
|
+
})).pipe(provide$3(Settings.layer), provide$3(CurrentIssueSource.layer));
|
|
151180
151212
|
const allProjects = new Setting("projects", Array$1(Project$1));
|
|
151181
151213
|
const getAllProjects = Settings.get(allProjects).pipe(map$8(getOrElse$1(() => [])));
|
|
151182
151214
|
const projectById = fnUntraced(function* (projectId) {
|
|
@@ -151242,17 +151274,16 @@ const welcomeWizard = gen(function* () {
|
|
|
151242
151274
|
" '--'",
|
|
151243
151275
|
"",
|
|
151244
151276
|
"Welcome! Let's add your first project.",
|
|
151245
|
-
"Projects let you configure how lalph runs tasks
|
|
151246
|
-
"(like issue filters, concurrency, and git flow).",
|
|
151277
|
+
"Projects let you configure how lalph runs tasks.",
|
|
151247
151278
|
""
|
|
151248
151279
|
].join("\n");
|
|
151249
151280
|
console.log(welcome);
|
|
151250
|
-
return yield*
|
|
151281
|
+
return yield* addOrUpdateProject();
|
|
151251
151282
|
});
|
|
151252
|
-
const
|
|
151283
|
+
const addOrUpdateProject = fnUntraced(function* (existing) {
|
|
151253
151284
|
const projects = yield* getAllProjects;
|
|
151254
|
-
const id = yield* text$2({
|
|
151255
|
-
message: "
|
|
151285
|
+
const id = existing ? existing.id : yield* text$2({
|
|
151286
|
+
message: "Project name",
|
|
151256
151287
|
validate(input) {
|
|
151257
151288
|
input = input.trim();
|
|
151258
151289
|
if (input.length === 0) return fail$4("Project name cannot be empty");
|
|
@@ -151261,7 +151292,7 @@ const addProject = gen(function* () {
|
|
|
151261
151292
|
}
|
|
151262
151293
|
});
|
|
151263
151294
|
const concurrency = yield* integer$2({
|
|
151264
|
-
message: "Concurrency",
|
|
151295
|
+
message: "Concurrency (number of tasks to run in parallel)",
|
|
151265
151296
|
min: 1
|
|
151266
151297
|
});
|
|
151267
151298
|
const targetBranch = pipe(yield* text$2({ message: "Target branch (leave empty to use HEAD)" }), trim, liftPredicate(isNonEmpty));
|
|
@@ -151269,22 +151300,27 @@ const addProject = gen(function* () {
|
|
|
151269
151300
|
message: "Git flow",
|
|
151270
151301
|
choices: [{
|
|
151271
151302
|
title: "Pull Request",
|
|
151303
|
+
description: "Create a pull request for each task",
|
|
151272
151304
|
value: "pr"
|
|
151273
151305
|
}, {
|
|
151274
151306
|
title: "Commit",
|
|
151307
|
+
description: "Tasks are committed directly to the target branch",
|
|
151275
151308
|
value: "commit"
|
|
151276
151309
|
}]
|
|
151277
151310
|
});
|
|
151278
151311
|
const reviewAgent = yield* toggle({ message: "Enable review agent?" });
|
|
151279
151312
|
const project = new Project$1({
|
|
151280
151313
|
id: ProjectId.makeUnsafe(id),
|
|
151281
|
-
enabled: true,
|
|
151314
|
+
enabled: existing ? existing.enabled : true,
|
|
151282
151315
|
concurrency,
|
|
151283
151316
|
targetBranch,
|
|
151284
151317
|
gitFlow,
|
|
151285
151318
|
reviewAgent
|
|
151286
151319
|
});
|
|
151287
|
-
yield* Settings.set(allProjects, some$2([...projects, project]));
|
|
151320
|
+
yield* Settings.set(allProjects, some$2(existing ? projects.map((p) => p.id === project.id ? project : p) : [...projects, project]));
|
|
151321
|
+
const source = yield* IssueSource;
|
|
151322
|
+
yield* source.reset.pipe(provideService(CurrentProjectId, project.id));
|
|
151323
|
+
yield* source.settings(project.id);
|
|
151288
151324
|
return project;
|
|
151289
151325
|
});
|
|
151290
151326
|
|
|
@@ -151477,8 +151513,12 @@ const commandRoot = make$35("lalph", {
|
|
|
151477
151513
|
//#endregion
|
|
151478
151514
|
//#region src/commands/plan.ts
|
|
151479
151515
|
const dangerous = boolean("dangerous").pipe(withAlias("d"), withDescription$1("Enable dangerous mode (skip permission prompts) during plan generation"));
|
|
151480
|
-
const
|
|
151481
|
-
|
|
151516
|
+
const withNewProject = boolean("new").pipe(withAlias("n"), withDescription$1("Create a new project before starting plan mode"));
|
|
151517
|
+
const commandPlan = make$35("plan", {
|
|
151518
|
+
dangerous,
|
|
151519
|
+
withNewProject
|
|
151520
|
+
}).pipe(withDescription("Iterate on an issue plan and create PRD tasks"), withHandler(fnUntraced(function* ({ dangerous, withNewProject }) {
|
|
151521
|
+
const project = withNewProject ? yield* addOrUpdateProject() : yield* selectProject;
|
|
151482
151522
|
const { specsDirectory } = yield* commandRoot;
|
|
151483
151523
|
const commandPrefix = yield* getCommandPrefix;
|
|
151484
151524
|
yield* plan({
|
|
@@ -151487,7 +151527,7 @@ const commandPlan = make$35("plan", { dangerous }).pipe(withDescription("Iterate
|
|
|
151487
151527
|
commandPrefix,
|
|
151488
151528
|
dangerous
|
|
151489
151529
|
}).pipe(provideService(CurrentProjectId, project.id));
|
|
151490
|
-
}, provide$1(Settings.layer))));
|
|
151530
|
+
}, provide$1([Settings.layer, CurrentIssueSource.layer]))));
|
|
151491
151531
|
const plan = fnUntraced(function* (options) {
|
|
151492
151532
|
const fs = yield* FileSystem;
|
|
151493
151533
|
const pathService = yield* Path$1;
|
|
@@ -151573,7 +151613,7 @@ const handler$1 = flow(withHandler(fnUntraced(function* () {
|
|
|
151573
151613
|
}));
|
|
151574
151614
|
console.log(`Created issue with ID: ${created.id}`);
|
|
151575
151615
|
console.log(`URL: ${created.url}`);
|
|
151576
|
-
}, scoped$1)), provide(
|
|
151616
|
+
}, scoped$1)), provide(merge$5(layerProjectIdPrompt, CurrentIssueSource.layer)));
|
|
151577
151617
|
const commandIssue = make$35("issue").pipe(withDescription("Create a new issue in the selected issue source"), handler$1);
|
|
151578
151618
|
const commandIssueAlias = make$35("i").pipe(withDescription("Alias for 'issue' command"), handler$1);
|
|
151579
151619
|
|
|
@@ -151598,7 +151638,7 @@ const commandSource = make$35("source").pipe(withDescription("Select the issue s
|
|
|
151598
151638
|
|
|
151599
151639
|
//#endregion
|
|
151600
151640
|
//#region package.json
|
|
151601
|
-
var version = "0.2.
|
|
151641
|
+
var version = "0.2.4";
|
|
151602
151642
|
|
|
151603
151643
|
//#endregion
|
|
151604
151644
|
//#region src/commands/projects/ls.ts
|
|
@@ -151626,10 +151666,7 @@ const commandProjectsLs = make$35("ls").pipe(withDescription("List all configure
|
|
|
151626
151666
|
|
|
151627
151667
|
//#endregion
|
|
151628
151668
|
//#region src/commands/projects/add.ts
|
|
151629
|
-
const commandProjectsAdd = make$35("add").pipe(withDescription("Add a new project"), withHandler(
|
|
151630
|
-
const project = yield* addProject;
|
|
151631
|
-
yield* (yield* IssueSource).settings(project.id);
|
|
151632
|
-
})), provide(Settings.layer), provide(CurrentIssueSource.layer));
|
|
151669
|
+
const commandProjectsAdd = make$35("add").pipe(withDescription("Add a new project"), withHandler(() => addOrUpdateProject()), provide(Settings.layer), provide(CurrentIssueSource.layer));
|
|
151633
151670
|
|
|
151634
151671
|
//#endregion
|
|
151635
151672
|
//#region src/commands/projects/rm.ts
|
|
@@ -151639,41 +151676,13 @@ const commandProjectsRm = make$35("rm").pipe(withDescription("Remove a project")
|
|
|
151639
151676
|
const project = yield* selectProject;
|
|
151640
151677
|
const newProjects = projects.filter((p) => p.id !== project.id);
|
|
151641
151678
|
yield* Settings.set(allProjects, some$2(newProjects));
|
|
151642
|
-
})), provide(Settings.layer));
|
|
151679
|
+
})), provide(Settings.layer), provide(CurrentIssueSource.layer));
|
|
151643
151680
|
|
|
151644
151681
|
//#endregion
|
|
151645
151682
|
//#region src/commands/projects/edit.ts
|
|
151646
151683
|
const commandProjectsEdit = make$35("edit").pipe(withDescription("Modify a project"), withHandler(fnUntraced(function* () {
|
|
151647
|
-
|
|
151648
|
-
|
|
151649
|
-
const project = yield* selectProject;
|
|
151650
|
-
const concurrency = yield* integer$2({
|
|
151651
|
-
message: "Concurrency",
|
|
151652
|
-
min: 1
|
|
151653
|
-
});
|
|
151654
|
-
const targetBranch = pipe(yield* text$2({ message: "Target branch (leave empty to use HEAD)" }), trim, liftPredicate(isNonEmpty));
|
|
151655
|
-
const gitFlow = yield* select({
|
|
151656
|
-
message: "Git flow",
|
|
151657
|
-
choices: [{
|
|
151658
|
-
title: "Pull Request",
|
|
151659
|
-
value: "pr"
|
|
151660
|
-
}, {
|
|
151661
|
-
title: "Commit",
|
|
151662
|
-
value: "commit"
|
|
151663
|
-
}]
|
|
151664
|
-
});
|
|
151665
|
-
const reviewAgent = yield* toggle({ message: "Enable review agent?" });
|
|
151666
|
-
const nextProject = new Project$1({
|
|
151667
|
-
...project,
|
|
151668
|
-
concurrency,
|
|
151669
|
-
targetBranch,
|
|
151670
|
-
gitFlow,
|
|
151671
|
-
reviewAgent
|
|
151672
|
-
});
|
|
151673
|
-
yield* Settings.set(allProjects, some$2(map$12(projects, (p) => p.id === nextProject.id ? nextProject : p)));
|
|
151674
|
-
const source = yield* IssueSource;
|
|
151675
|
-
yield* source.reset.pipe(provideService(CurrentProjectId, nextProject.id));
|
|
151676
|
-
yield* source.settings(project.id);
|
|
151684
|
+
if ((yield* getAllProjects).length === 0) return yield* log$1("No projects available to edit.");
|
|
151685
|
+
yield* addOrUpdateProject(yield* selectProject);
|
|
151677
151686
|
})), provide(Settings.layer), provide(CurrentIssueSource.layer));
|
|
151678
151687
|
|
|
151679
151688
|
//#endregion
|
package/package.json
CHANGED
package/src/Projects.ts
CHANGED
|
@@ -13,6 +13,8 @@ import { Project, ProjectId } from "./domain/Project.ts"
|
|
|
13
13
|
import { AsyncResult, Atom } from "effect/unstable/reactivity"
|
|
14
14
|
import { CurrentProjectId, Setting, Settings } from "./Settings.ts"
|
|
15
15
|
import { Prompt } from "effect/unstable/cli"
|
|
16
|
+
import { IssueSource } from "./IssueSource.ts"
|
|
17
|
+
import { CurrentIssueSource } from "./IssueSources.ts"
|
|
16
18
|
|
|
17
19
|
export const layerProjectIdPrompt = Layer.effect(
|
|
18
20
|
CurrentProjectId,
|
|
@@ -20,7 +22,7 @@ export const layerProjectIdPrompt = Layer.effect(
|
|
|
20
22
|
const project = yield* selectProject
|
|
21
23
|
return project.id
|
|
22
24
|
}),
|
|
23
|
-
).pipe(Layer.provide(Settings.layer))
|
|
25
|
+
).pipe(Layer.provide(Settings.layer), Layer.provide(CurrentIssueSource.layer))
|
|
24
26
|
|
|
25
27
|
export const allProjects = new Setting("projects", Schema.Array(Project))
|
|
26
28
|
|
|
@@ -134,30 +136,33 @@ export const welcomeWizard = Effect.gen(function* () {
|
|
|
134
136
|
" '--'",
|
|
135
137
|
"",
|
|
136
138
|
"Welcome! Let's add your first project.",
|
|
137
|
-
"Projects let you configure how lalph runs tasks
|
|
138
|
-
"(like issue filters, concurrency, and git flow).",
|
|
139
|
+
"Projects let you configure how lalph runs tasks.",
|
|
139
140
|
"",
|
|
140
141
|
].join("\n")
|
|
141
142
|
console.log(welcome)
|
|
142
|
-
return yield*
|
|
143
|
+
return yield* addOrUpdateProject()
|
|
143
144
|
})
|
|
144
145
|
|
|
145
|
-
export const
|
|
146
|
+
export const addOrUpdateProject = Effect.fnUntraced(function* (
|
|
147
|
+
existing?: Project,
|
|
148
|
+
) {
|
|
146
149
|
const projects = yield* getAllProjects
|
|
147
|
-
const id =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
const id = existing
|
|
151
|
+
? existing.id
|
|
152
|
+
: yield* Prompt.text({
|
|
153
|
+
message: "Project name",
|
|
154
|
+
validate(input) {
|
|
155
|
+
input = input.trim()
|
|
156
|
+
if (input.length === 0) {
|
|
157
|
+
return Effect.fail("Project name cannot be empty")
|
|
158
|
+
} else if (projects.some((p) => p.id === input)) {
|
|
159
|
+
return Effect.fail("Project already exists")
|
|
160
|
+
}
|
|
161
|
+
return Effect.succeed(input)
|
|
162
|
+
},
|
|
163
|
+
})
|
|
159
164
|
const concurrency = yield* Prompt.integer({
|
|
160
|
-
message: "Concurrency",
|
|
165
|
+
message: "Concurrency (number of tasks to run in parallel)",
|
|
161
166
|
min: 1,
|
|
162
167
|
})
|
|
163
168
|
const targetBranch = pipe(
|
|
@@ -170,8 +175,16 @@ export const addProject = Effect.gen(function* () {
|
|
|
170
175
|
const gitFlow = yield* Prompt.select({
|
|
171
176
|
message: "Git flow",
|
|
172
177
|
choices: [
|
|
173
|
-
{
|
|
174
|
-
|
|
178
|
+
{
|
|
179
|
+
title: "Pull Request",
|
|
180
|
+
description: "Create a pull request for each task",
|
|
181
|
+
value: "pr",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
title: "Commit",
|
|
185
|
+
description: "Tasks are committed directly to the target branch",
|
|
186
|
+
value: "commit",
|
|
187
|
+
},
|
|
175
188
|
] as const,
|
|
176
189
|
})
|
|
177
190
|
const reviewAgent = yield* Prompt.toggle({
|
|
@@ -180,12 +193,24 @@ export const addProject = Effect.gen(function* () {
|
|
|
180
193
|
|
|
181
194
|
const project = new Project({
|
|
182
195
|
id: ProjectId.makeUnsafe(id),
|
|
183
|
-
enabled: true,
|
|
196
|
+
enabled: existing ? existing.enabled : true,
|
|
184
197
|
concurrency,
|
|
185
198
|
targetBranch,
|
|
186
199
|
gitFlow,
|
|
187
200
|
reviewAgent,
|
|
188
201
|
})
|
|
189
|
-
yield* Settings.set(
|
|
202
|
+
yield* Settings.set(
|
|
203
|
+
allProjects,
|
|
204
|
+
Option.some(
|
|
205
|
+
existing
|
|
206
|
+
? projects.map((p) => (p.id === project.id ? project : p))
|
|
207
|
+
: [...projects, project],
|
|
208
|
+
),
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
const source = yield* IssueSource
|
|
212
|
+
yield* source.reset.pipe(Effect.provideService(CurrentProjectId, project.id))
|
|
213
|
+
yield* source.settings(project.id)
|
|
214
|
+
|
|
190
215
|
return project
|
|
191
216
|
})
|
package/src/commands/issue.ts
CHANGED
|
@@ -93,11 +93,7 @@ const handler = flow(
|
|
|
93
93
|
console.log(`URL: ${created.url}`)
|
|
94
94
|
}, Effect.scoped),
|
|
95
95
|
),
|
|
96
|
-
Command.provide(
|
|
97
|
-
Layer.mergeAll(CurrentIssueSource.layer).pipe(
|
|
98
|
-
Layer.provideMerge(layerProjectIdPrompt),
|
|
99
|
-
),
|
|
100
|
-
),
|
|
96
|
+
Command.provide(Layer.merge(layerProjectIdPrompt, CurrentIssueSource.layer)),
|
|
101
97
|
)
|
|
102
98
|
|
|
103
99
|
export const commandIssue = Command.make("issue").pipe(
|
package/src/commands/plan.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { Command, Flag } from "effect/unstable/cli"
|
|
|
8
8
|
import { CurrentIssueSource } from "../IssueSources.ts"
|
|
9
9
|
import { commandRoot } from "./root.ts"
|
|
10
10
|
import { CurrentProjectId, Settings } from "../Settings.ts"
|
|
11
|
-
import { selectProject } from "../Projects.ts"
|
|
11
|
+
import { addOrUpdateProject, selectProject } from "../Projects.ts"
|
|
12
12
|
|
|
13
13
|
const dangerous = Flag.boolean("dangerous").pipe(
|
|
14
14
|
Flag.withAlias("d"),
|
|
@@ -17,20 +17,33 @@ const dangerous = Flag.boolean("dangerous").pipe(
|
|
|
17
17
|
),
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const withNewProject = Flag.boolean("new").pipe(
|
|
21
|
+
Flag.withAlias("n"),
|
|
22
|
+
Flag.withDescription("Create a new project before starting plan mode"),
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
export const commandPlan = Command.make("plan", {
|
|
26
|
+
dangerous,
|
|
27
|
+
withNewProject,
|
|
28
|
+
}).pipe(
|
|
21
29
|
Command.withDescription("Iterate on an issue plan and create PRD tasks"),
|
|
22
30
|
Command.withHandler(
|
|
23
|
-
Effect.fnUntraced(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
specsDirectory
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
Effect.fnUntraced(
|
|
32
|
+
function* ({ dangerous, withNewProject }) {
|
|
33
|
+
const project = withNewProject
|
|
34
|
+
? yield* addOrUpdateProject()
|
|
35
|
+
: yield* selectProject
|
|
36
|
+
const { specsDirectory } = yield* commandRoot
|
|
37
|
+
const commandPrefix = yield* getCommandPrefix
|
|
38
|
+
yield* plan({
|
|
39
|
+
specsDirectory,
|
|
40
|
+
targetBranch: project.targetBranch,
|
|
41
|
+
commandPrefix,
|
|
42
|
+
dangerous,
|
|
43
|
+
}).pipe(Effect.provideService(CurrentProjectId, project.id))
|
|
44
|
+
},
|
|
45
|
+
Effect.provide([Settings.layer, CurrentIssueSource.layer]),
|
|
46
|
+
),
|
|
34
47
|
),
|
|
35
48
|
)
|
|
36
49
|
const plan = Effect.fnUntraced(
|
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
1
|
import { Command } from "effect/unstable/cli"
|
|
3
|
-
import {
|
|
2
|
+
import { addOrUpdateProject } from "../../Projects.ts"
|
|
4
3
|
import { CurrentIssueSource } from "../../IssueSources.ts"
|
|
5
|
-
import { IssueSource } from "../../IssueSource.ts"
|
|
6
4
|
import { Settings } from "../../Settings.ts"
|
|
7
5
|
|
|
8
6
|
export const commandProjectsAdd = Command.make("add").pipe(
|
|
9
7
|
Command.withDescription("Add a new project"),
|
|
10
|
-
Command.withHandler(
|
|
11
|
-
Effect.fnUntraced(function* () {
|
|
12
|
-
const project = yield* addProject
|
|
13
|
-
const source = yield* IssueSource
|
|
14
|
-
yield* source.settings(project.id)
|
|
15
|
-
}),
|
|
16
|
-
),
|
|
8
|
+
Command.withHandler(() => addOrUpdateProject()),
|
|
17
9
|
Command.provide(Settings.layer),
|
|
18
10
|
Command.provide(CurrentIssueSource.layer),
|
|
19
11
|
)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Command
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { Effect } from "effect"
|
|
2
|
+
import { Command } from "effect/unstable/cli"
|
|
3
|
+
import {
|
|
4
|
+
addOrUpdateProject,
|
|
5
|
+
getAllProjects,
|
|
6
|
+
selectProject,
|
|
7
|
+
} from "../../Projects.ts"
|
|
8
|
+
import { Settings } from "../../Settings.ts"
|
|
7
9
|
import { CurrentIssueSource } from "../../IssueSources.ts"
|
|
8
10
|
|
|
9
11
|
export const commandProjectsEdit = Command.make("edit").pipe(
|
|
@@ -15,49 +17,7 @@ export const commandProjectsEdit = Command.make("edit").pipe(
|
|
|
15
17
|
return yield* Effect.log("No projects available to edit.")
|
|
16
18
|
}
|
|
17
19
|
const project = yield* selectProject
|
|
18
|
-
|
|
19
|
-
message: "Concurrency",
|
|
20
|
-
min: 1,
|
|
21
|
-
})
|
|
22
|
-
const targetBranch = pipe(
|
|
23
|
-
yield* Prompt.text({
|
|
24
|
-
message: "Target branch (leave empty to use HEAD)",
|
|
25
|
-
}),
|
|
26
|
-
String.trim,
|
|
27
|
-
Option.liftPredicate(String.isNonEmpty),
|
|
28
|
-
)
|
|
29
|
-
const gitFlow = yield* Prompt.select({
|
|
30
|
-
message: "Git flow",
|
|
31
|
-
choices: [
|
|
32
|
-
{ title: "Pull Request", value: "pr" },
|
|
33
|
-
{ title: "Commit", value: "commit" },
|
|
34
|
-
] as const,
|
|
35
|
-
})
|
|
36
|
-
const reviewAgent = yield* Prompt.toggle({
|
|
37
|
-
message: "Enable review agent?",
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const nextProject = new Project({
|
|
41
|
-
...project,
|
|
42
|
-
concurrency,
|
|
43
|
-
targetBranch,
|
|
44
|
-
gitFlow,
|
|
45
|
-
reviewAgent,
|
|
46
|
-
})
|
|
47
|
-
yield* Settings.set(
|
|
48
|
-
allProjects,
|
|
49
|
-
Option.some(
|
|
50
|
-
Array.map(projects, (p) =>
|
|
51
|
-
p.id === nextProject.id ? nextProject : p,
|
|
52
|
-
),
|
|
53
|
-
),
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
const source = yield* IssueSource
|
|
57
|
-
yield* source.reset.pipe(
|
|
58
|
-
Effect.provideService(CurrentProjectId, nextProject.id),
|
|
59
|
-
)
|
|
60
|
-
yield* source.settings(project.id)
|
|
20
|
+
yield* addOrUpdateProject(project)
|
|
61
21
|
}),
|
|
62
22
|
),
|
|
63
23
|
Command.provide(Settings.layer),
|
|
@@ -2,6 +2,7 @@ import { Effect, Option } from "effect"
|
|
|
2
2
|
import { Command } from "effect/unstable/cli"
|
|
3
3
|
import { allProjects, getAllProjects, selectProject } from "../../Projects.ts"
|
|
4
4
|
import { Settings } from "../../Settings.ts"
|
|
5
|
+
import { CurrentIssueSource } from "../../IssueSources.ts"
|
|
5
6
|
|
|
6
7
|
export const commandProjectsRm = Command.make("rm").pipe(
|
|
7
8
|
Command.withDescription("Remove a project"),
|
|
@@ -17,4 +18,5 @@ export const commandProjectsRm = Command.make("rm").pipe(
|
|
|
17
18
|
}),
|
|
18
19
|
),
|
|
19
20
|
Command.provide(Settings.layer),
|
|
21
|
+
Command.provide(CurrentIssueSource.layer),
|
|
20
22
|
)
|