forked from ProverCoderAI/docker-git
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.ts
More file actions
86 lines (77 loc) · 3.68 KB
/
parser.ts
File metadata and controls
86 lines (77 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { Either, Match } from "effect"
import { type Command, type ParseError } from "@effect-template/lib/core/domain"
import { parseApply } from "./parser-apply.js"
import { parseAttach } from "./parser-attach.js"
import { parseAuth } from "./parser-auth.js"
import { parseClone } from "./parser-clone.js"
import { buildCreateCommand } from "./parser-create.js"
import { parseMcpPlaywright } from "./parser-mcp-playwright.js"
import { parseRawOptions } from "./parser-options.js"
import { parsePanes } from "./parser-panes.js"
import { parseScrap } from "./parser-scrap.js"
import { parseSessionGists } from "./parser-session-gists.js"
import { parseSessions } from "./parser-sessions.js"
import { parseState } from "./parser-state.js"
import { usageText } from "./usage.js"
const isHelpFlag = (token: string): boolean => token === "--help" || token === "-h"
const helpCommand: Command = { _tag: "Help", message: usageText }
const menuCommand: Command = { _tag: "Menu" }
const statusCommand: Command = { _tag: "Status" }
const downAllCommand: Command = { _tag: "DownAll" }
const parseCreate = (args: ReadonlyArray<string>): Either.Either<Command, ParseError> =>
Either.flatMap(parseRawOptions(args), (raw) => buildCreateCommand(raw))
// CHANGE: parse CLI arguments into a typed command
// WHY: enforce deterministic, pure parsing before any effects run
// QUOTE(ТЗ): "Надо написать CLI команду с помощью которой мы будем создавать докер образы"
// REF: user-request-2026-01-07
// SOURCE: n/a
// FORMAT THEOREM: forall argv: parse(argv) = cmd -> deterministic(cmd)
// PURITY: CORE
// EFFECT: Effect<Command, ParseError, never>
// INVARIANT: parse does not perform IO and returns the same result for same argv
// COMPLEXITY: O(n) where n = |argv|
export const parseArgs = (args: ReadonlyArray<string>): Either.Either<Command, ParseError> => {
if (args.length === 0) {
return Either.right(menuCommand)
}
if (args.some((arg) => isHelpFlag(arg))) {
return Either.right(helpCommand)
}
const command = args[0]
const rest = args.slice(1)
const unknownCommandError: ParseError = {
_tag: "UnknownCommand",
command: command ?? ""
}
return Match.value(command)
.pipe(
Match.when("create", () => parseCreate(rest)),
Match.when("init", () => parseCreate(rest)),
Match.when("clone", () => parseClone(rest)),
Match.when("attach", () => parseAttach(rest)),
Match.when("tmux", () => parseAttach(rest)),
Match.when("panes", () => parsePanes(rest)),
Match.when("terms", () => parsePanes(rest)),
Match.when("terminals", () => parsePanes(rest)),
Match.when("sessions", () => parseSessions(rest)),
Match.when("scrap", () => parseScrap(rest)),
Match.when("mcp-playwright", () => parseMcpPlaywright(rest)),
Match.when("help", () => Either.right(helpCommand)),
Match.when("ps", () => Either.right(statusCommand)),
Match.when("status", () => Either.right(statusCommand)),
Match.when("down-all", () => Either.right(downAllCommand)),
Match.when("stop-all", () => Either.right(downAllCommand)),
Match.when("kill-all", () => Either.right(downAllCommand)),
Match.when("menu", () => Either.right(menuCommand)),
Match.when("ui", () => Either.right(menuCommand))
)
.pipe(
Match.when("auth", () => parseAuth(rest)),
Match.when("open", () => parseAttach(rest)),
Match.when("apply", () => parseApply(rest)),
Match.when("state", () => parseState(rest)),
Match.when("session-gists", () => parseSessionGists(rest)),
Match.when("gists", () => parseSessionGists(rest)),
Match.orElse(() => Either.left(unknownCommandError))
)
}