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 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$5 = /* @__PURE__ */ dual(2, (self, that) => {
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$5(services));
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$5(that, self)));
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$5(services, input));
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$5(services, input))))));
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$5(acquireContext, input)), ensuring$2(sync(() => {
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 and integrations",
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* addProject;
151281
+ return yield* addOrUpdateProject();
151251
151282
  });
151252
- const addProject = gen(function* () {
151283
+ const addOrUpdateProject = fnUntraced(function* (existing) {
151253
151284
  const projects = yield* getAllProjects;
151254
- const id = yield* text$2({
151255
- message: "Name",
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 commandPlan = make$35("plan", { dangerous }).pipe(withDescription("Iterate on an issue plan and create PRD tasks"), withHandler(fnUntraced(function* ({ dangerous }) {
151481
- const project = yield* selectProject;
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(mergeAll(CurrentIssueSource.layer).pipe(provideMerge(layerProjectIdPrompt))));
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.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(fnUntraced(function* () {
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
- const projects = yield* getAllProjects;
151648
- if (projects.length === 0) return yield* log$1("No projects available to edit.");
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.2.2",
4
+ "version": "0.2.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
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 and integrations",
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* addProject
143
+ return yield* addOrUpdateProject()
143
144
  })
144
145
 
145
- export const addProject = Effect.gen(function* () {
146
+ export const addOrUpdateProject = Effect.fnUntraced(function* (
147
+ existing?: Project,
148
+ ) {
146
149
  const projects = yield* getAllProjects
147
- const id = yield* Prompt.text({
148
- message: "Name",
149
- validate(input) {
150
- input = input.trim()
151
- if (input.length === 0) {
152
- return Effect.fail("Project name cannot be empty")
153
- } else if (projects.some((p) => p.id === input)) {
154
- return Effect.fail("Project already exists")
155
- }
156
- return Effect.succeed(input)
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
- { title: "Pull Request", value: "pr" },
174
- { title: "Commit", value: "commit" },
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(allProjects, Option.some([...projects, project]))
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
  })
@@ -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(
@@ -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
- export const commandPlan = Command.make("plan", { dangerous }).pipe(
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(function* ({ dangerous }) {
24
- const project = yield* selectProject
25
- const { specsDirectory } = yield* commandRoot
26
- const commandPrefix = yield* getCommandPrefix
27
- yield* plan({
28
- specsDirectory,
29
- targetBranch: project.targetBranch,
30
- commandPrefix,
31
- dangerous,
32
- }).pipe(Effect.provideService(CurrentProjectId, project.id))
33
- }, Effect.provide(Settings.layer)),
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 { addProject } from "../../Projects.ts"
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 { Array, Effect, Option, pipe, String } from "effect"
2
- import { Command, Prompt } from "effect/unstable/cli"
3
- import { allProjects, getAllProjects, selectProject } from "../../Projects.ts"
4
- import { CurrentProjectId, Settings } from "../../Settings.ts"
5
- import { Project } from "../../domain/Project.ts"
6
- import { IssueSource } from "../../IssueSource.ts"
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
- const concurrency = yield* Prompt.integer({
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
  )