lalph 0.3.24 → 0.3.25

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/README.md CHANGED
@@ -70,14 +70,17 @@ lalph projects toggle
70
70
 
71
71
  ## Plan mode
72
72
 
73
- Plan mode opens an editor so you can write a high-level plan. On save, lalph
74
- generates a specification under `--specs` and then creates PRD tasks from it.
73
+ Plan mode opens an editor so you can write a high-level plan. You can also pass
74
+ `--file` / `-f` with a markdown file path to skip the editor. On save (or file
75
+ read), lalph generates a specification under `--specs` and then creates PRD
76
+ tasks from it.
75
77
 
76
78
  Use `--dangerous` to skip permission prompts during spec generation, and `--new`
77
79
  to create a project before starting plan mode.
78
80
 
79
81
  ```bash
80
82
  lalph plan
83
+ lalph plan --file ./my-plan.md
81
84
  lalph plan tasks .specs/my-spec.md
82
85
  ```
83
86
 
package/dist/cli.mjs CHANGED
@@ -49627,6 +49627,35 @@ const directory$1 = (kind, name, options) => path$1(kind, name, {
49627
49627
  mustExist: options?.mustExist
49628
49628
  });
49629
49629
  /**
49630
+ * Creates a file path parameter.
49631
+ *
49632
+ * This is a convenience function that creates a path parameter with a
49633
+ * `pathType` set to `"file"` and a default type name of `"file"`.
49634
+ *
49635
+ * @example
49636
+ * ```ts
49637
+ * import * as Param from "effect/unstable/cli/Param"
49638
+ *
49639
+ * // @internal - this module is not exported publicly
49640
+ *
49641
+ * // Basic file parameter
49642
+ * const outputFile = Param.file(Param.flagKind, "output")
49643
+ *
49644
+ * // File that must exist
49645
+ * const inputFile = Param.file(Param.flagKind, "input", { mustExist: true })
49646
+ *
49647
+ * // Usage: --output result.txt --input existing-file.txt
49648
+ * ```
49649
+ *
49650
+ * @since 4.0.0
49651
+ * @category constructors
49652
+ */
49653
+ const file$2 = (kind, name, options) => path$1(kind, name, {
49654
+ pathType: "file",
49655
+ typeName: "file",
49656
+ mustExist: options?.mustExist
49657
+ });
49658
+ /**
49630
49659
  * Creates an empty sentinel parameter that always fails to parse.
49631
49660
  *
49632
49661
  * This is useful for creating placeholder parameters or for combinators.
@@ -51323,6 +51352,26 @@ const choiceWithValue = (name, choices) => choiceWithValue$1(flagKind, name, cho
51323
51352
  */
51324
51353
  const choice = (name, choices) => choice$1(flagKind, name, choices);
51325
51354
  /**
51355
+ * Creates a file path flag that accepts file paths with optional existence validation.
51356
+ *
51357
+ * @example
51358
+ * ```ts
51359
+ * import { Flag } from "effect/unstable/cli"
51360
+ *
51361
+ * // Basic file flag
51362
+ * const inputFlag = Flag.file("input")
51363
+ * // Usage: --input ./data.json
51364
+ *
51365
+ * // File that must exist
51366
+ * const configFlag = Flag.file("config", { mustExist: true })
51367
+ * // Usage: --config ./config.yaml (file must exist)
51368
+ * ```
51369
+ *
51370
+ * @since 4.0.0
51371
+ * @category constructors
51372
+ */
51373
+ const file$1 = (name, options) => file$2(flagKind, name, options);
51374
+ /**
51326
51375
  * Creates a directory path flag that accepts directory paths with optional existence validation.
51327
51376
  *
51328
51377
  * @example
@@ -155771,11 +155820,18 @@ var Editor = class extends Service$1()("lalph/Editor", { make: gen(function* ()
155771
155820
  //#region src/commands/plan.ts
155772
155821
  const dangerous = boolean("dangerous").pipe(withAlias("d"), withDescription$1("Skip permission prompts while generating the specification from your plan"));
155773
155822
  const withNewProject = boolean("new").pipe(withAlias("n"), withDescription$1("Create a new project (via prompts) before starting plan mode"));
155823
+ const file = file$1("file", { mustExist: true }).pipe(withAlias("f"), withDescription$1("Read the plan from a markdown file instead of opening an editor"), optional);
155774
155824
  const commandPlan = make$36("plan", {
155775
155825
  dangerous,
155776
- withNewProject
155777
- }).pipe(withDescription("Open an editor to draft a plan; on save, generate a specification under --specs and then create PRD tasks from it. Use --new to create a project first; use --dangerous to skip permission prompts during spec generation."), withHandler(fnUntraced(function* ({ dangerous, withNewProject }) {
155778
- const thePlan = yield* (yield* Editor).editTemp({ suffix: ".md" });
155826
+ withNewProject,
155827
+ file
155828
+ }).pipe(withDescription("Draft a plan in your editor (or use --file); then generate a specification under --specs and create PRD tasks from it. Use --new to create a project first, and --dangerous to skip permission prompts during spec generation."), withHandler(fnUntraced(function* ({ dangerous, withNewProject, file }) {
155829
+ const editor = yield* Editor;
155830
+ const fs = yield* FileSystem;
155831
+ const thePlan = yield* matchEffect(file.asEffect(), {
155832
+ onFailure: () => editor.editTemp({ suffix: ".md" }),
155833
+ onSuccess: (path) => fs.readFileString(path).pipe(asSome)
155834
+ });
155779
155835
  if (isNone(thePlan)) return;
155780
155836
  yield* gen(function* () {
155781
155837
  const project = withNewProject ? yield* addOrUpdateProject() : yield* selectProject;
@@ -155916,7 +155972,7 @@ const commandSource = make$36("source").pipe(withDescription("Select the issue s
155916
155972
 
155917
155973
  //#endregion
155918
155974
  //#region package.json
155919
- var version = "0.3.24";
155975
+ var version = "0.3.25";
155920
155976
 
155921
155977
  //#endregion
155922
155978
  //#region src/commands/projects/ls.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.3.24",
4
+ "version": "0.3.25",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -29,20 +29,32 @@ const withNewProject = Flag.boolean("new").pipe(
29
29
  ),
30
30
  )
31
31
 
32
+ const file = Flag.file("file", { mustExist: true }).pipe(
33
+ Flag.withAlias("f"),
34
+ Flag.withDescription(
35
+ "Read the plan from a markdown file instead of opening an editor",
36
+ ),
37
+ Flag.optional,
38
+ )
39
+
32
40
  export const commandPlan = Command.make("plan", {
33
41
  dangerous,
34
42
  withNewProject,
43
+ file,
35
44
  }).pipe(
36
45
  Command.withDescription(
37
- "Open an editor to draft a plan; on save, generate a specification under --specs and then create PRD tasks from it. Use --new to create a project first; use --dangerous to skip permission prompts during spec generation.",
46
+ "Draft a plan in your editor (or use --file); then generate a specification under --specs and create PRD tasks from it. Use --new to create a project first, and --dangerous to skip permission prompts during spec generation.",
38
47
  ),
39
48
  Command.withHandler(
40
- Effect.fnUntraced(function* ({ dangerous, withNewProject }) {
49
+ Effect.fnUntraced(function* ({ dangerous, withNewProject, file }) {
41
50
  const editor = yield* Editor
51
+ const fs = yield* FileSystem.FileSystem
42
52
 
43
- const thePlan = yield* editor.editTemp({
44
- suffix: ".md",
53
+ const thePlan = yield* Effect.matchEffect(file.asEffect(), {
54
+ onFailure: () => editor.editTemp({ suffix: ".md" }),
55
+ onSuccess: (path) => fs.readFileString(path).pipe(Effect.asSome),
45
56
  })
57
+
46
58
  if (Option.isNone(thePlan)) return
47
59
 
48
60
  // We nest this effect, so we can launch the editor first as fast as