@hallaxius/forge 0.1.2 → 0.1.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.
Files changed (50) hide show
  1. package/README.md +160 -158
  2. package/bin/forge.js +2 -2
  3. package/dist/cli.js +31602 -9895
  4. package/package.json +75 -72
  5. package/src/cli.ts +80 -78
  6. package/src/commands/account.ts +80 -0
  7. package/src/commands/alias.ts +66 -66
  8. package/src/commands/branch.ts +46 -46
  9. package/src/commands/ci.ts +28 -0
  10. package/src/commands/clone.ts +100 -100
  11. package/src/commands/commit.ts +88 -93
  12. package/src/commands/config.ts +47 -48
  13. package/src/commands/diff.ts +26 -26
  14. package/src/commands/fetch.ts +20 -20
  15. package/src/commands/help.ts +58 -58
  16. package/src/commands/init.ts +32 -37
  17. package/src/commands/issue.ts +63 -0
  18. package/src/commands/log.ts +29 -29
  19. package/src/commands/merge.ts +37 -37
  20. package/src/commands/pr.ts +65 -0
  21. package/src/commands/push.ts +35 -35
  22. package/src/commands/release.ts +26 -0
  23. package/src/commands/remote.ts +107 -107
  24. package/src/commands/reset.ts +30 -30
  25. package/src/commands/setup.ts +93 -95
  26. package/src/commands/stash.ts +44 -44
  27. package/src/commands/status.ts +74 -74
  28. package/src/commands/sync.ts +20 -20
  29. package/src/commands/tag.ts +41 -41
  30. package/src/commands/undo.ts +27 -27
  31. package/src/commands/version.ts +12 -12
  32. package/src/constants/colors.ts +7 -7
  33. package/src/constants/commit-types.ts +24 -24
  34. package/src/constants/messages.ts +13 -23
  35. package/src/lib/auth.ts +172 -95
  36. package/src/lib/config.ts +108 -99
  37. package/src/lib/git.ts +543 -382
  38. package/src/lib/github.ts +202 -0
  39. package/src/lib/logger.ts +18 -31
  40. package/src/lib/ui.ts +122 -156
  41. package/src/lib/validators.ts +16 -27
  42. package/src/templates/commit-types.json +9 -9
  43. package/src/utils/files.ts +21 -21
  44. package/src/utils/strings.ts +19 -19
  45. package/src/version.const.ts +1 -1
  46. package/src/commands/archive.ts +0 -35
  47. package/src/commands/bisect.ts +0 -102
  48. package/src/commands/cherry-pick.ts +0 -57
  49. package/src/commands/clean.ts +0 -76
  50. package/src/commands/worktree.ts +0 -92
@@ -1,35 +0,0 @@
1
- import type { Command } from "commander";
2
- import * as git from "../lib/git.js";
3
- import { error, success } from "../lib/logger.js";
4
-
5
- export default function register(program: Command): void {
6
- program
7
- .command("archive")
8
- .description("Create an archive of the repository")
9
- .argument("<format>", "Archive format (tar, tar.gz, zip)")
10
- .option("--prefix <dir>", "Prepend prefix to archive paths")
11
- .option("--output <file>", "Output file path")
12
- .option("--tree-ish <ref>", "Tree or commit to archive")
13
- .action(
14
- async (
15
- format: string,
16
- options: { prefix?: string; output?: string; treeIsh?: string },
17
- ) => {
18
- try {
19
- const opts: { prefix?: string; output?: string; treeIsh?: string } =
20
- {};
21
- if (options.prefix) opts.prefix = options.prefix;
22
- if (options.output) opts.output = options.output;
23
- if (options.treeIsh) opts.treeIsh = options.treeIsh;
24
-
25
- const _result = await git.archive(format, opts);
26
- const outputPath = options.output || `archive.${format}`;
27
- success(`Archive created: ${outputPath}`);
28
- } catch (err) {
29
- error(
30
- `Archive failed: ${err instanceof Error ? err.message : String(err)}`,
31
- );
32
- }
33
- },
34
- );
35
- }
@@ -1,102 +0,0 @@
1
- import type { Command } from "commander";
2
- import * as git from "../lib/git.js";
3
- import { error, info, success, text } from "../lib/logger.js";
4
-
5
- export default function register(program: Command): void {
6
- const cmd = program
7
- .command("bisect")
8
- .description("Bisect to find the commit that introduced a bug");
9
-
10
- cmd
11
- .command("start")
12
- .description("Start a bisect session")
13
- .argument("[bad]", "Bad commit (default: HEAD)")
14
- .argument("[good...]", "Good commits")
15
- .action(async (bad: string | undefined, good: string[]) => {
16
- try {
17
- await git.bisectStart(bad, good);
18
- success("Bisect started.");
19
- } catch (err) {
20
- error(
21
- `Bisect start failed: ${err instanceof Error ? err.message : String(err)}`,
22
- );
23
- }
24
- });
25
-
26
- cmd
27
- .command("bad")
28
- .description("Mark a commit as bad")
29
- .argument("[commit]", "Commit hash (default: HEAD)")
30
- .action(async (commit: string | undefined) => {
31
- try {
32
- await git.bisectBad(commit);
33
- success(`Commit ${commit || "HEAD"} marked as bad.`);
34
- } catch (err) {
35
- error(
36
- `Bisect bad failed: ${err instanceof Error ? err.message : String(err)}`,
37
- );
38
- }
39
- });
40
-
41
- cmd
42
- .command("good")
43
- .description("Mark commits as good")
44
- .argument("[commits...]", "Commits to mark as good")
45
- .action(async (commits: string[]) => {
46
- try {
47
- if (commits.length === 0) {
48
- info("Provide at least one commit to mark as good.");
49
- return;
50
- }
51
- await git.bisectGood(commits);
52
- success(`Marked ${commits.join(", ")} as good.`);
53
- } catch (err) {
54
- error(
55
- `Bisect good failed: ${err instanceof Error ? err.message : String(err)}`,
56
- );
57
- }
58
- });
59
-
60
- cmd
61
- .command("reset")
62
- .description("Reset bisect state")
63
- .action(async () => {
64
- try {
65
- await git.bisectReset();
66
- success("Bisect reset.");
67
- } catch (err) {
68
- error(
69
- `Bisect reset failed: ${err instanceof Error ? err.message : String(err)}`,
70
- );
71
- }
72
- });
73
-
74
- cmd
75
- .command("log")
76
- .description("Show bisect log")
77
- .action(async () => {
78
- try {
79
- const log = await git.bisectLog();
80
- text(log);
81
- } catch (err) {
82
- error(
83
- `Bisect log failed: ${err instanceof Error ? err.message : String(err)}`,
84
- );
85
- }
86
- });
87
-
88
- cmd
89
- .command("run")
90
- .description("Run a script for bisect")
91
- .argument("<cmd>", "Command to run")
92
- .action(async (cmd: string) => {
93
- try {
94
- await git.bisectRun(cmd);
95
- success("Bisect run completed.");
96
- } catch (err) {
97
- error(
98
- `Bisect run failed: ${err instanceof Error ? err.message : String(err)}`,
99
- );
100
- }
101
- });
102
- }
@@ -1,57 +0,0 @@
1
- import type { Command } from "commander";
2
- import * as git from "../lib/git.js";
3
- import { error, info, success } from "../lib/logger.js";
4
-
5
- export default function register(program: Command): void {
6
- program
7
- .command("cherry-pick")
8
- .description("Cherry-pick commits")
9
- .argument("[commits...]", "Commits to cherry-pick")
10
- .option("--no-commit", "Apply changes without committing")
11
- .option(
12
- "--mainline <number>",
13
- "Mainline parent for cherry-pick merge commits",
14
- )
15
- .option("--continue", "Continue after resolving conflicts")
16
- .option("--abort", "Abort cherry-pick in progress")
17
- .action(
18
- async (
19
- commits: string[],
20
- options: {
21
- noCommit?: boolean;
22
- mainline?: number;
23
- continue?: boolean;
24
- abort?: boolean;
25
- },
26
- ) => {
27
- try {
28
- if (options.continue) {
29
- await git.cherryPickContinue();
30
- success("Cherry-pick continued.");
31
- return;
32
- }
33
-
34
- if (options.abort) {
35
- await git.cherryPickAbort();
36
- success("Cherry-pick aborted.");
37
- return;
38
- }
39
-
40
- if (commits.length === 0) {
41
- info("Provide at least one commit to cherry-pick.");
42
- return;
43
- }
44
-
45
- await git.cherryPick(commits, {
46
- noCommit: options.noCommit ?? undefined,
47
- mainline: options.mainline ?? undefined,
48
- });
49
- success(`Cherry-pick applied: ${commits.join(", ")}`);
50
- } catch (err) {
51
- error(
52
- `Cherry-pick failed: ${err instanceof Error ? err.message : String(err)}`,
53
- );
54
- }
55
- },
56
- );
57
- }
@@ -1,76 +0,0 @@
1
- import type { Command } from "commander";
2
- import * as git from "../lib/git.js";
3
- import { error, info, success, warning } from "../lib/logger.js";
4
- import { confirm } from "../lib/ui.js";
5
-
6
- export default function register(program: Command): void {
7
- program
8
- .command("clean")
9
- .description("Clean untracked files")
10
- .argument("[paths...]", "Paths to clean")
11
- .option("--dry-run", "Show what would be removed")
12
- .option("--force", "Skip confirmation prompt")
13
- .option("--exclude <pattern>", "Exclude files matching pattern")
14
- .action(
15
- async (
16
- _paths: string[],
17
- options: { dryRun?: boolean; force?: boolean; exclude?: string },
18
- ) => {
19
- try {
20
- const opts: { dryRun?: boolean; force?: boolean; exclude?: string } =
21
- {};
22
- if (options.dryRun) opts.dryRun = true;
23
- if (options.force) opts.force = true;
24
- if (options.exclude) opts.exclude = options.exclude;
25
-
26
- const wouldRemove = await git.clean(opts);
27
-
28
- if (options.dryRun) {
29
- if (wouldRemove.length === 0) {
30
- info("Nothing would be removed.");
31
- return;
32
- }
33
- info("Would remove:");
34
- for (const line of wouldRemove) {
35
- warning(line);
36
- }
37
- return;
38
- }
39
-
40
- if (wouldRemove.length === 0) {
41
- info("Nothing to clean.");
42
- return;
43
- }
44
-
45
- if (!options.force) {
46
- const ok = await confirm(
47
- `Remove ${wouldRemove.length} untracked file(s)?`,
48
- );
49
- if (!ok) {
50
- info("Clean cancelled.");
51
- return;
52
- }
53
- }
54
-
55
- const result = await git.clean({
56
- force: true,
57
- ...(options.exclude ? { exclude: options.exclude } : {}),
58
- });
59
-
60
- if (result.length === 0) {
61
- info("Nothing cleaned.");
62
- return;
63
- }
64
-
65
- for (const line of result) {
66
- warning(line);
67
- }
68
- success(`Cleaned ${result.length} file(s).`);
69
- } catch (err) {
70
- error(
71
- `Clean failed: ${err instanceof Error ? err.message : String(err)}`,
72
- );
73
- }
74
- },
75
- );
76
- }
@@ -1,92 +0,0 @@
1
- import type { Command } from "commander";
2
- import * as git from "../lib/git.js";
3
- import { error, info, success } from "../lib/logger.js";
4
- import { createTable } from "../lib/ui.js";
5
-
6
- export default function register(program: Command): void {
7
- const cmd = program.command("worktree").description("Manage worktrees");
8
-
9
- cmd
10
- .command("add")
11
- .description("Add a new worktree")
12
- .argument("<path>", "Path for the new worktree")
13
- .argument("[branch]", "Branch to checkout")
14
- .option("--new", "Create and checkout a new branch")
15
- .option("--detach", "Checkout detached HEAD")
16
- .action(
17
- async (
18
- path: string,
19
- branch: string | undefined,
20
- options: { new?: boolean; detach?: boolean },
21
- ) => {
22
- try {
23
- await git.worktreeAdd(path, branch, {
24
- new: options.new,
25
- detach: options.detach,
26
- });
27
- success(`Worktree added at '${path}'.`);
28
- } catch (err) {
29
- error(
30
- `Worktree add failed: ${err instanceof Error ? err.message : String(err)}`,
31
- );
32
- }
33
- },
34
- );
35
-
36
- cmd
37
- .command("list")
38
- .description("List all worktrees")
39
- .action(async () => {
40
- try {
41
- const entries = await git.worktreeList();
42
- if (entries.length === 0) {
43
- info("No worktrees found.");
44
- return;
45
- }
46
- const rows = entries.map((e) => [e.path, e.branch, e.hash]);
47
- console.log(createTable(["Path", "Branch", "Hash"], rows));
48
- } catch (err) {
49
- error(
50
- `Worktree list failed: ${err instanceof Error ? err.message : String(err)}`,
51
- );
52
- }
53
- });
54
-
55
- cmd
56
- .command("remove")
57
- .description("Remove a worktree")
58
- .argument("<path>", "Path of the worktree to remove")
59
- .option("--force", "Force removal")
60
- .action(async (path: string, options: { force?: boolean }) => {
61
- try {
62
- await git.worktreeRemove(path, options.force);
63
- success(`Worktree '${path}' removed.`);
64
- } catch (err) {
65
- error(
66
- `Worktree remove failed: ${err instanceof Error ? err.message : String(err)}`,
67
- );
68
- }
69
- });
70
-
71
- cmd
72
- .command("prune")
73
- .description("Prune stale worktree references")
74
- .option("--dry-run", "Only show what would be pruned")
75
- .action(async (options: { dryRun?: boolean }) => {
76
- try {
77
- const result = await git.worktreePrune(options.dryRun);
78
- if (result.length === 0) {
79
- info("Nothing to prune.");
80
- return;
81
- }
82
- for (const line of result) {
83
- info(line);
84
- }
85
- success(`Pruned ${result.length} reference(s).`);
86
- } catch (err) {
87
- error(
88
- `Worktree prune failed: ${err instanceof Error ? err.message : String(err)}`,
89
- );
90
- }
91
- });
92
- }