@g-abhishek/gitx 0.1.0 → 0.1.2
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/bin.js +0 -0
- package/dist/cli/commands/implement.d.ts.map +1 -1
- package/dist/cli/commands/implement.js +3 -0
- package/dist/cli/commands/implement.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +37 -18
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/pr/create.d.ts.map +1 -1
- package/dist/cli/commands/pr/create.js +3 -0
- package/dist/cli/commands/pr/create.js.map +1 -1
- package/dist/cli/commands/pr/fixComments.d.ts.map +1 -1
- package/dist/cli/commands/pr/fixComments.js +3 -0
- package/dist/cli/commands/pr/fixComments.js.map +1 -1
- package/dist/cli/commands/pr/list.d.ts.map +1 -1
- package/dist/cli/commands/pr/list.js +3 -0
- package/dist/cli/commands/pr/list.js.map +1 -1
- package/dist/cli/commands/pr/review.d.ts.map +1 -1
- package/dist/cli/commands/pr/review.js +3 -0
- package/dist/cli/commands/pr/review.js.map +1 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +28 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +15 -8
- package/dist/config/schema.js.map +1 -1
- package/dist/core/context.d.ts +7 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +2 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/gitx.d.ts +6 -0
- package/dist/core/gitx.d.ts.map +1 -1
- package/dist/core/gitx.js +41 -1
- package/dist/core/gitx.js.map +1 -1
- package/dist/types/config.d.ts +12 -5
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/utils/git.d.ts +7 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +59 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/validators.d.ts +1 -0
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js +7 -0
- package/dist/utils/validators.js.map +1 -1
- package/package.json +2 -1
package/dist/bin.js
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkD/D"}
|
|
@@ -15,6 +15,9 @@ export function registerImplementCommand(program) {
|
|
|
15
15
|
assertValid(validateNonEmpty("Task")(task), "Task");
|
|
16
16
|
const mode = parseAutonomyMode(options.mode);
|
|
17
17
|
const gitx = await Gitx.fromCwd();
|
|
18
|
+
const ctx = await gitx.getRepoContext();
|
|
19
|
+
logger.info(`📦 Repo: ${ctx.repoSlug}`);
|
|
20
|
+
logger.info(`🔌 Provider: ${ctx.provider}`);
|
|
18
21
|
const spinner = ora("🧠 Analyzing task…").start();
|
|
19
22
|
const analysis = await gitx.ai.analyzeTask(task);
|
|
20
23
|
spinner.succeed("Task analyzed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement.js","sourceRoot":"","sources":["../../../src/cli/commands/implement.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,yCAAyC,CAAC;SACtD,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;SACtC,MAAM,CAAC,eAAe,EAAE,4BAA4B,EAAE,QAAQ,CAAC;SAC/D,MAAM,CAAC,WAAW,EAAE,iCAAiC,EAAE,KAAK,CAAC;SAC7D,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAgD,EAAE,EAAE;QAC/E,WAAW,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"implement.js","sourceRoot":"","sources":["../../../src/cli/commands/implement.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport inquirer from \"inquirer\";\nimport ora from \"ora\";\nimport { logger } from \"../../logger/logger.js\";\nimport type { AutonomyMode } from \"../../types/modes.js\";\nimport { Gitx } from \"../../core/gitx.js\";\nimport { assertValid, validateNonEmpty } from \"../../utils/validators.js\";\nimport { parseAutonomyMode } from \"../../utils/modes.js\";\n\nexport function registerImplementCommand(program: Command): void {\n program\n .command(\"implement\")\n .description(\"🛠️ Implement a task with AI assistance\")\n .argument(\"<task>\", \"Task description\")\n .option(\"--mode <mode>\", \"plan|guided|semi-auto|auto\", \"guided\")\n .option(\"--dry-run\", \"Simulate execution (no changes)\", false)\n .action(async (task: string, options: { mode: AutonomyMode; dryRun: boolean }) => {\n assertValid(validateNonEmpty(\"Task\")(task), \"Task\");\n const mode = parseAutonomyMode(options.mode);\n\n const gitx = await Gitx.fromCwd();\n const ctx = await gitx.getRepoContext();\n logger.info(`📦 Repo: ${ctx.repoSlug}`);\n logger.info(`🔌 Provider: ${ctx.provider}`);\n\n const spinner = ora(\"🧠 Analyzing task…\").start();\n const analysis = await gitx.ai.analyzeTask(task);\n spinner.succeed(\"Task analyzed\");\n\n logger.info(\"🧾 Summary\");\n logger.info(JSON.stringify(analysis, null, 2));\n\n const planSpinner = ora(\"🗺️ Generating plan…\").start();\n const plan = await gitx.ai.generatePlan({ task, analysis });\n planSpinner.succeed(\"Plan generated\");\n\n logger.info(\"🧩 Plan\");\n logger.info(JSON.stringify(plan, null, 2));\n\n if (mode !== \"auto\") {\n const { proceed } = await inquirer.prompt<{ proceed: boolean }>([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: options.dryRun\n ? \"Proceed with dry-run execution?\"\n : \"Proceed with execution (branch + commit + PR)?\",\n default: false\n }\n ]);\n if (!proceed) {\n logger.warn(\"⏹️ Cancelled\");\n return;\n }\n }\n\n logger.warn(\"⚠️ implement flow execution is not wired yet (providers + git ops in next step).\");\n logger.info(`Mode: ${mode}, dry-run: ${options.dryRun ? \"yes\" : \"no\"}`);\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgF1D"}
|
|
@@ -2,36 +2,48 @@ import inquirer from "inquirer";
|
|
|
2
2
|
import ora from "ora";
|
|
3
3
|
import { logger } from "../../logger/logger.js";
|
|
4
4
|
import { saveConfig } from "../../config/config.js";
|
|
5
|
-
import { validateNonEmpty
|
|
5
|
+
import { validateNonEmpty } from "../../utils/validators.js";
|
|
6
6
|
export function registerInitCommand(program) {
|
|
7
7
|
program
|
|
8
8
|
.command("init")
|
|
9
9
|
.description("🚀 Initialize gitx configuration")
|
|
10
10
|
.action(async () => {
|
|
11
11
|
logger.info("📄 gitx init");
|
|
12
|
-
const
|
|
12
|
+
const questions = [
|
|
13
13
|
{
|
|
14
|
-
type: "
|
|
15
|
-
name: "
|
|
16
|
-
message: "Choose
|
|
14
|
+
type: "checkbox",
|
|
15
|
+
name: "providers",
|
|
16
|
+
message: "Choose provider(s) to configure",
|
|
17
17
|
choices: [
|
|
18
18
|
{ name: "GitHub", value: "github" },
|
|
19
19
|
{ name: "GitLab", value: "gitlab" },
|
|
20
20
|
{ name: "Azure DevOps", value: "azure" }
|
|
21
|
-
]
|
|
21
|
+
],
|
|
22
|
+
validate: (value) => (Array.isArray(value) && value.length > 0 ? true : "Select at least one provider")
|
|
22
23
|
},
|
|
23
24
|
{
|
|
24
25
|
type: "password",
|
|
25
|
-
name: "
|
|
26
|
-
message: "
|
|
26
|
+
name: "githubToken",
|
|
27
|
+
message: "GitHub token",
|
|
27
28
|
mask: "*",
|
|
28
|
-
validate: validateNonEmpty("
|
|
29
|
+
validate: validateNonEmpty("GitHub token"),
|
|
30
|
+
when: (a) => a.providers.includes("github")
|
|
29
31
|
},
|
|
30
32
|
{
|
|
31
|
-
type: "
|
|
32
|
-
name: "
|
|
33
|
-
message: "
|
|
34
|
-
|
|
33
|
+
type: "password",
|
|
34
|
+
name: "gitlabToken",
|
|
35
|
+
message: "GitLab token",
|
|
36
|
+
mask: "*",
|
|
37
|
+
validate: validateNonEmpty("GitLab token"),
|
|
38
|
+
when: (a) => a.providers.includes("gitlab")
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: "password",
|
|
42
|
+
name: "azureToken",
|
|
43
|
+
message: "Azure DevOps token (PAT)",
|
|
44
|
+
mask: "*",
|
|
45
|
+
validate: validateNonEmpty("Azure DevOps token"),
|
|
46
|
+
when: (a) => a.providers.includes("azure")
|
|
35
47
|
},
|
|
36
48
|
{
|
|
37
49
|
type: "input",
|
|
@@ -40,18 +52,25 @@ export function registerInitCommand(program) {
|
|
|
40
52
|
default: "main",
|
|
41
53
|
validate: validateNonEmpty("Default branch")
|
|
42
54
|
}
|
|
43
|
-
]
|
|
55
|
+
];
|
|
56
|
+
// Inquirer question typings are strict across versions; keep runtime behavior, relax TS here.
|
|
57
|
+
const answers = await inquirer.prompt(questions);
|
|
58
|
+
const providers = {};
|
|
59
|
+
if (answers.githubToken)
|
|
60
|
+
providers.github = { token: answers.githubToken };
|
|
61
|
+
if (answers.gitlabToken)
|
|
62
|
+
providers.gitlab = { token: answers.gitlabToken };
|
|
63
|
+
if (answers.azureToken)
|
|
64
|
+
providers.azure = { token: answers.azureToken };
|
|
44
65
|
const config = {
|
|
45
|
-
|
|
46
|
-
token: answers.token,
|
|
47
|
-
repo: answers.repo,
|
|
66
|
+
providers,
|
|
48
67
|
defaultBranch: answers.defaultBranch
|
|
49
68
|
};
|
|
50
69
|
const spinner = ora("Saving config…").start();
|
|
51
70
|
await saveConfig(config);
|
|
52
71
|
spinner.succeed("Config saved");
|
|
53
72
|
logger.success("✅ gitx is ready");
|
|
54
|
-
logger.info("Next: run `gitx implement \"<task>\" --mode=plan`");
|
|
73
|
+
logger.info("Next: run `gitx implement \"<task>\" --mode=plan` inside a git repo");
|
|
55
74
|
});
|
|
56
75
|
}
|
|
57
76
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,OAAO,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport inquirer from \"inquirer\";\nimport ora from \"ora\";\nimport { logger } from \"../../logger/logger.js\";\nimport { saveConfig } from \"../../config/config.js\";\nimport type { GitxConfig } from \"../../types/config.js\";\nimport type { ProviderKind } from \"../../types/provider.js\";\nimport { validateNonEmpty } from \"../../utils/validators.js\";\n\nexport function registerInitCommand(program: Command): void {\n program\n .command(\"init\")\n .description(\"🚀 Initialize gitx configuration\")\n .action(async () => {\n logger.info(\"📄 gitx init\");\n\n type InitAnswers = {\n providers: ProviderKind[];\n githubToken?: string;\n gitlabToken?: string;\n azureToken?: string;\n defaultBranch: string;\n };\n\n const questions = [\n {\n type: \"checkbox\",\n name: \"providers\",\n message: \"Choose provider(s) to configure\",\n choices: [\n { name: \"GitHub\", value: \"github\" },\n { name: \"GitLab\", value: \"gitlab\" },\n { name: \"Azure DevOps\", value: \"azure\" }\n ],\n validate: (value: ProviderKind[]) => (Array.isArray(value) && value.length > 0 ? true : \"Select at least one provider\")\n },\n {\n type: \"password\",\n name: \"githubToken\",\n message: \"GitHub token\",\n mask: \"*\",\n validate: validateNonEmpty(\"GitHub token\"),\n when: (a: InitAnswers) => a.providers.includes(\"github\")\n },\n {\n type: \"password\",\n name: \"gitlabToken\",\n message: \"GitLab token\",\n mask: \"*\",\n validate: validateNonEmpty(\"GitLab token\"),\n when: (a: InitAnswers) => a.providers.includes(\"gitlab\")\n },\n {\n type: \"password\",\n name: \"azureToken\",\n message: \"Azure DevOps token (PAT)\",\n mask: \"*\",\n validate: validateNonEmpty(\"Azure DevOps token\"),\n when: (a: InitAnswers) => a.providers.includes(\"azure\")\n },\n {\n type: \"input\",\n name: \"defaultBranch\",\n message: \"Default branch\",\n default: \"main\",\n validate: validateNonEmpty(\"Default branch\")\n }\n ];\n\n // Inquirer question typings are strict across versions; keep runtime behavior, relax TS here.\n const answers = await inquirer.prompt<InitAnswers>(questions as any);\n\n const providers: GitxConfig[\"providers\"] = {};\n if (answers.githubToken) providers.github = { token: answers.githubToken };\n if (answers.gitlabToken) providers.gitlab = { token: answers.gitlabToken };\n if (answers.azureToken) providers.azure = { token: answers.azureToken };\n\n const config: GitxConfig = {\n providers,\n defaultBranch: answers.defaultBranch\n };\n\n const spinner = ora(\"Saving config…\").start();\n await saveConfig(config);\n spinner.succeed(\"Config saved\");\n\n logger.success(\"✅ gitx is ready\");\n logger.info(\"Next: run `gitx implement \\\"<task>\\\" --mode=plan` inside a git repo\");\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAUzD"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { logger } from "../../../logger/logger.js";
|
|
2
|
+
import { Gitx } from "../../../core/gitx.js";
|
|
2
3
|
export function registerPrCreateCommand(pr) {
|
|
3
4
|
pr.command("create")
|
|
4
5
|
.description("🆕 Create a pull request")
|
|
5
6
|
.option("--branches <branches>", "Comma-separated branches (e.g. dev,staging,prod)")
|
|
6
7
|
.action(async (options) => {
|
|
8
|
+
const gitx = await Gitx.fromCwd();
|
|
9
|
+
await gitx.getRepoContext();
|
|
7
10
|
logger.warn("Not implemented yet (provider system next).");
|
|
8
11
|
if (options.branches)
|
|
9
12
|
logger.info(`Branches: ${options.branches}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/create.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/create.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,MAAM,UAAU,uBAAuB,CAAC,EAAW;IACjD,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0BAA0B,CAAC;SACvC,MAAM,CAAC,uBAAuB,EAAE,kDAAkD,CAAC;SACnF,MAAM,CAAC,KAAK,EAAE,OAA8B,EAAE,EAAE;QAC/C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC3D,IAAI,OAAO,CAAC,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { Command } from \"commander\";\nimport { logger } from \"../../../logger/logger.js\";\nimport { Gitx } from \"../../../core/gitx.js\";\n\nexport function registerPrCreateCommand(pr: Command): void {\n pr.command(\"create\")\n .description(\"🆕 Create a pull request\")\n .option(\"--branches <branches>\", \"Comma-separated branches (e.g. dev,staging,prod)\")\n .action(async (options: { branches?: string }) => {\n const gitx = await Gitx.fromCwd();\n await gitx.getRepoContext();\n logger.warn(\"Not implemented yet (provider system next).\");\n if (options.branches) logger.info(`Branches: ${options.branches}`);\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixComments.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/fixComments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"fixComments.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/fixComments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAU9D"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { logger } from "../../../logger/logger.js";
|
|
2
|
+
import { Gitx } from "../../../core/gitx.js";
|
|
2
3
|
export function registerPrFixCommentsCommand(pr) {
|
|
3
4
|
pr.command("fix-comments")
|
|
4
5
|
.description("🩹 Attempt to fix PR review comments")
|
|
5
6
|
.argument("<id>", "Pull request id/number")
|
|
6
7
|
.action(async (id) => {
|
|
8
|
+
const gitx = await Gitx.fromCwd();
|
|
9
|
+
await gitx.getRepoContext();
|
|
7
10
|
logger.warn("Not implemented yet (AI + provider wiring next).");
|
|
8
11
|
logger.info(`PR: ${id}`);
|
|
9
12
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixComments.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/fixComments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"fixComments.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/fixComments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,MAAM,UAAU,4BAA4B,CAAC,EAAW;IACtD,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,sCAAsC,CAAC;SACnD,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { Command } from \"commander\";\nimport { logger } from \"../../../logger/logger.js\";\nimport { Gitx } from \"../../../core/gitx.js\";\n\nexport function registerPrFixCommentsCommand(pr: Command): void {\n pr.command(\"fix-comments\")\n .description(\"🩹 Attempt to fix PR review comments\")\n .argument(\"<id>\", \"Pull request id/number\")\n .action(async (id: string) => {\n const gitx = await Gitx.fromCwd();\n await gitx.getRepoContext();\n logger.warn(\"Not implemented yet (AI + provider wiring next).\");\n logger.info(`PR: ${id}`);\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAQvD"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { logger } from "../../../logger/logger.js";
|
|
2
|
+
import { Gitx } from "../../../core/gitx.js";
|
|
2
3
|
export function registerPrListCommand(pr) {
|
|
3
4
|
pr.command("list")
|
|
4
5
|
.description("📋 List pull requests")
|
|
5
6
|
.action(async () => {
|
|
7
|
+
const gitx = await Gitx.fromCwd();
|
|
8
|
+
await gitx.getRepoContext();
|
|
6
9
|
logger.warn("Not implemented yet (provider system next).");
|
|
7
10
|
});
|
|
8
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,MAAM,UAAU,qBAAqB,CAAC,EAAW;IAC/C,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { Command } from \"commander\";\nimport { logger } from \"../../../logger/logger.js\";\nimport { Gitx } from \"../../../core/gitx.js\";\n\nexport function registerPrListCommand(pr: Command): void {\n pr.command(\"list\")\n .description(\"📋 List pull requests\")\n .action(async () => {\n const gitx = await Gitx.fromCwd();\n await gitx.getRepoContext();\n logger.warn(\"Not implemented yet (provider system next).\");\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pr/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAUzD"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { logger } from "../../../logger/logger.js";
|
|
2
|
+
import { Gitx } from "../../../core/gitx.js";
|
|
2
3
|
export function registerPrReviewCommand(pr) {
|
|
3
4
|
pr.command("review")
|
|
4
5
|
.description("🧐 Review a pull request")
|
|
5
6
|
.argument("<id>", "Pull request id/number")
|
|
6
7
|
.action(async (id) => {
|
|
8
|
+
const gitx = await Gitx.fromCwd();
|
|
9
|
+
await gitx.getRepoContext();
|
|
7
10
|
logger.warn("Not implemented yet (provider system next).");
|
|
8
11
|
logger.info(`PR: ${id}`);
|
|
9
12
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/review.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr/review.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,MAAM,UAAU,uBAAuB,CAAC,EAAW;IACjD,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0BAA0B,CAAC;SACvC,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { Command } from \"commander\";\nimport { logger } from \"../../../logger/logger.js\";\nimport { Gitx } from \"../../../core/gitx.js\";\n\nexport function registerPrReviewCommand(pr: Command): void {\n pr.command(\"review\")\n .description(\"🧐 Review a pull request\")\n .argument(\"<id>\", \"Pull request id/number\")\n .action(async (id: string) => {\n const gitx = await Gitx.fromCwd();\n await gitx.getRepoContext();\n logger.warn(\"Not implemented yet (provider system next).\");\n logger.info(`PR: ${id}`);\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,eAAO,MAAM,YAAY,0CAA2C,CAAC;AAErE,wBAAsB,UAAU,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,eAAO,MAAM,YAAY,0CAA2C,CAAC;AAErE,wBAAsB,UAAU,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuBzE;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF"}
|
package/dist/config/config.js
CHANGED
|
@@ -10,10 +10,15 @@ export async function loadConfig(cwd = process.cwd()) {
|
|
|
10
10
|
continue;
|
|
11
11
|
const raw = await readFile(fullPath, "utf8");
|
|
12
12
|
const parsed = JSON.parse(raw);
|
|
13
|
-
|
|
13
|
+
// Back-compat for early v0.1 config shape: { provider, token, defaultBranch, repo? }
|
|
14
|
+
const migrated = migrateLegacyConfig(parsed);
|
|
15
|
+
if (!isGitxConfig(migrated)) {
|
|
14
16
|
throw new GitxError(`Invalid config in ${filename}.`, { exitCode: 2 });
|
|
15
17
|
}
|
|
16
|
-
|
|
18
|
+
if (Object.keys(migrated.providers).length === 0) {
|
|
19
|
+
throw new GitxError("No providers configured. Run `gitx init`.", { exitCode: 2 });
|
|
20
|
+
}
|
|
21
|
+
return migrated;
|
|
17
22
|
}
|
|
18
23
|
throw new GitxError("No gitx config found. Run `gitx init` first.", { exitCode: 2 });
|
|
19
24
|
}
|
|
@@ -31,4 +36,25 @@ async function exists(path) {
|
|
|
31
36
|
return false;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
39
|
+
function isRecord(value) {
|
|
40
|
+
return typeof value === "object" && value !== null;
|
|
41
|
+
}
|
|
42
|
+
function migrateLegacyConfig(value) {
|
|
43
|
+
if (!isRecord(value))
|
|
44
|
+
return value;
|
|
45
|
+
if (isRecord(value["providers"]))
|
|
46
|
+
return value;
|
|
47
|
+
const provider = value["provider"];
|
|
48
|
+
const token = value["token"];
|
|
49
|
+
const defaultBranch = value["defaultBranch"];
|
|
50
|
+
if ((provider === "github" || provider === "gitlab" || provider === "azure") &&
|
|
51
|
+
typeof token === "string" &&
|
|
52
|
+
token.trim().length > 0) {
|
|
53
|
+
return {
|
|
54
|
+
providers: { [provider]: { token } },
|
|
55
|
+
...(typeof defaultBranch === "string" ? { defaultBranch } : {})
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
34
60
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,kBAAkB,EAAE,SAAS,CAAU,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAClD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;YAAE,SAAS;QAExC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAExC,IAAI,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, readFile, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { GitxConfig } from \"../types/config.js\";\nimport { GitxError } from \"../utils/errors.js\";\nimport { isGitxConfig } from \"./schema.js\";\n\nexport const CONFIG_FILES = [\"gitx.config.json\", \".gitxrc\"] as const;\n\nexport async function loadConfig(cwd = process.cwd()): Promise<GitxConfig> {\n for (const filename of CONFIG_FILES) {\n const fullPath = resolve(cwd, filename);\n if (!(await exists(fullPath))) continue;\n\n const raw = await readFile(fullPath, \"utf8\");\n const parsed: unknown = JSON.parse(raw);\n\n // Back-compat for early v0.1 config shape: { provider, token, defaultBranch, repo? }\n const migrated = migrateLegacyConfig(parsed);\n\n if (!isGitxConfig(migrated)) {\n throw new GitxError(`Invalid config in ${filename}.`, { exitCode: 2 });\n }\n\n if (Object.keys(migrated.providers).length === 0) {\n throw new GitxError(\"No providers configured. Run `gitx init`.\", { exitCode: 2 });\n }\n\n return migrated;\n }\n\n throw new GitxError(\"No gitx config found. Run `gitx init` first.\", { exitCode: 2 });\n}\n\nexport async function saveConfig(config: GitxConfig, cwd = process.cwd()): Promise<void> {\n const fullPath = resolve(cwd, \"gitx.config.json\");\n const contents = JSON.stringify(config, null, 2) + \"\\n\";\n await writeFile(fullPath, contents, \"utf8\");\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction migrateLegacyConfig(value: unknown): unknown {\n if (!isRecord(value)) return value;\n if (isRecord(value[\"providers\"])) return value;\n\n const provider = value[\"provider\"];\n const token = value[\"token\"];\n const defaultBranch = value[\"defaultBranch\"];\n\n if (\n (provider === \"github\" || provider === \"gitlab\" || provider === \"azure\") &&\n typeof token === \"string\" &&\n token.trim().length > 0\n ) {\n return {\n providers: { [provider]: { token } },\n ...(typeof defaultBranch === \"string\" ? { defaultBranch } : {})\n };\n }\n\n return value;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMrD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMrD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAmBhE"}
|
package/dist/config/schema.js
CHANGED
|
@@ -4,14 +4,21 @@ function isRecord(value) {
|
|
|
4
4
|
export function isGitxConfig(value) {
|
|
5
5
|
if (!isRecord(value))
|
|
6
6
|
return false;
|
|
7
|
-
const
|
|
8
|
-
const token = value["token"];
|
|
9
|
-
const repo = value["repo"];
|
|
7
|
+
const providers = value["providers"];
|
|
10
8
|
const defaultBranch = value["defaultBranch"];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
9
|
+
if (!isRecord(providers))
|
|
10
|
+
return false;
|
|
11
|
+
const allowed = new Set(["github", "gitlab", "azure"]);
|
|
12
|
+
for (const [k, v] of Object.entries(providers)) {
|
|
13
|
+
if (!allowed.has(k))
|
|
14
|
+
return false;
|
|
15
|
+
if (!isRecord(v))
|
|
16
|
+
return false;
|
|
17
|
+
if (typeof v["token"] !== "string" || String(v["token"]).trim().length === 0)
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const branchOk = defaultBranch === undefined ||
|
|
21
|
+
(typeof defaultBranch === "string" && defaultBranch.trim().length > 0 && !defaultBranch.includes(" "));
|
|
22
|
+
return branchOk;
|
|
16
23
|
}
|
|
17
24
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,MAAM,aAAa,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;IAE7C,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/B,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAC7F,CAAC;IAED,MAAM,QAAQ,GACZ,aAAa,KAAK,SAAS;QAC3B,CAAC,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzG,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type { GitxConfig } from \"../types/config.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isGitxConfig(value: unknown): value is GitxConfig {\n if (!isRecord(value)) return false;\n const providers = value[\"providers\"];\n const defaultBranch = value[\"defaultBranch\"];\n\n if (!isRecord(providers)) return false;\n\n const allowed = new Set([\"github\", \"gitlab\", \"azure\"]);\n for (const [k, v] of Object.entries(providers)) {\n if (!allowed.has(k)) return false;\n if (!isRecord(v)) return false;\n if (typeof v[\"token\"] !== \"string\" || String(v[\"token\"]).trim().length === 0) return false;\n }\n\n const branchOk =\n defaultBranch === undefined ||\n (typeof defaultBranch === \"string\" && defaultBranch.trim().length > 0 && !defaultBranch.includes(\" \"));\n\n return branchOk;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"","sourcesContent":["import type { ProviderKind } from \"../types/provider.js\";\n\nexport interface RepoContext {\n provider: ProviderKind;\n repoSlug: string; // provider-facing slug (GitHub/GitLab: owner/name)\n token: string;\n}\n\n"]}
|
package/dist/core/gitx.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { GitxConfig } from "../types/config.js";
|
|
2
2
|
import type { AiClient } from "../ai/types.js";
|
|
3
3
|
import type { GitxPlugin } from "./plugin.js";
|
|
4
|
+
import type { RepoContext } from "./context.js";
|
|
4
5
|
export declare class Gitx {
|
|
5
6
|
readonly config: GitxConfig;
|
|
6
7
|
readonly ai: AiClient;
|
|
8
|
+
readonly cwd: string;
|
|
7
9
|
private readonly plugins;
|
|
8
10
|
private constructor();
|
|
9
11
|
static fromCwd(cwd?: string): Promise<Gitx>;
|
|
10
12
|
use(plugin: GitxPlugin): Promise<void>;
|
|
13
|
+
getRepoContext(): Promise<RepoContext>;
|
|
14
|
+
getRepoSlug(): Promise<string>;
|
|
15
|
+
getProvider(): Promise<RepoContext["provider"]>;
|
|
16
|
+
getToken(): Promise<string>;
|
|
11
17
|
}
|
|
12
18
|
//# sourceMappingURL=gitx.d.ts.map
|
package/dist/core/gitx.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitx.d.ts","sourceRoot":"","sources":["../../src/core/gitx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"gitx.d.ts","sourceRoot":"","sources":["../../src/core/gitx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,qBAAa,IAAI;IACf,SAAgB,MAAM,EAAE,UAAU,CAAC;IACnC,SAAgB,EAAE,EAAE,QAAQ,CAAC;IAC7B,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAE5C,OAAO;WAMM,OAAO,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlD,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtC,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IA0CtC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAK9B,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAK/C,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAIlC"}
|
package/dist/core/gitx.js
CHANGED
|
@@ -1,21 +1,61 @@
|
|
|
1
1
|
import { loadConfig } from "../config/config.js";
|
|
2
2
|
import { MockAi } from "../ai/mockAi.js";
|
|
3
|
+
import { detectProviderFromRemote, getGitRemoteOriginUrl, inferRepoSlugFromRemote, isInsideGitRepo } from "../utils/git.js";
|
|
4
|
+
import { GitxError } from "../utils/errors.js";
|
|
3
5
|
export class Gitx {
|
|
4
6
|
config;
|
|
5
7
|
ai;
|
|
8
|
+
cwd;
|
|
6
9
|
plugins = [];
|
|
7
10
|
constructor(args) {
|
|
8
11
|
this.config = args.config;
|
|
9
12
|
this.ai = args.ai;
|
|
13
|
+
this.cwd = args.cwd;
|
|
10
14
|
}
|
|
11
15
|
static async fromCwd(cwd = process.cwd()) {
|
|
12
16
|
const config = await loadConfig(cwd);
|
|
13
17
|
const ai = new MockAi();
|
|
14
|
-
return new Gitx({ config, ai });
|
|
18
|
+
return new Gitx({ config, ai, cwd });
|
|
15
19
|
}
|
|
16
20
|
async use(plugin) {
|
|
17
21
|
this.plugins.push(plugin);
|
|
18
22
|
await plugin.setup(this);
|
|
19
23
|
}
|
|
24
|
+
async getRepoContext() {
|
|
25
|
+
if (!(await isInsideGitRepo(this.cwd))) {
|
|
26
|
+
throw new GitxError("No git repo detected in the current directory. Run gitx inside a git repository.", { exitCode: 2 });
|
|
27
|
+
}
|
|
28
|
+
const originUrl = await getGitRemoteOriginUrl(this.cwd);
|
|
29
|
+
if (!originUrl) {
|
|
30
|
+
throw new GitxError("No `remote.origin.url` detected. Add an origin remote and retry.", {
|
|
31
|
+
exitCode: 2
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const provider = detectProviderFromRemote(originUrl);
|
|
35
|
+
if (!provider) {
|
|
36
|
+
throw new GitxError(`Unsupported git remote host for auto-detection: ${originUrl}.`, { exitCode: 2 });
|
|
37
|
+
}
|
|
38
|
+
const token = this.config.providers[provider]?.token;
|
|
39
|
+
if (!token) {
|
|
40
|
+
throw new GitxError(`No token configured for provider "${provider}". Re-run \`gitx init\` and add credentials for ${provider}.`, { exitCode: 2 });
|
|
41
|
+
}
|
|
42
|
+
const repoSlug = inferRepoSlugFromRemote(originUrl);
|
|
43
|
+
if (!repoSlug) {
|
|
44
|
+
throw new GitxError(`Could not infer repo slug from origin remote: ${originUrl}.`, { exitCode: 2 });
|
|
45
|
+
}
|
|
46
|
+
return { provider, repoSlug, token };
|
|
47
|
+
}
|
|
48
|
+
async getRepoSlug() {
|
|
49
|
+
const ctx = await this.getRepoContext();
|
|
50
|
+
return ctx.repoSlug;
|
|
51
|
+
}
|
|
52
|
+
async getProvider() {
|
|
53
|
+
const ctx = await this.getRepoContext();
|
|
54
|
+
return ctx.provider;
|
|
55
|
+
}
|
|
56
|
+
async getToken() {
|
|
57
|
+
const ctx = await this.getRepoContext();
|
|
58
|
+
return ctx.token;
|
|
59
|
+
}
|
|
20
60
|
}
|
|
21
61
|
//# sourceMappingURL=gitx.js.map
|
package/dist/core/gitx.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitx.js","sourceRoot":"","sources":["../../src/core/gitx.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"gitx.js","sourceRoot":"","sources":["../../src/core/gitx.ts"],"names":[],"mappings":"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","sourcesContent":["import type { GitxConfig } from \"../types/config.js\";\nimport { loadConfig } from \"../config/config.js\";\nimport { MockAi } from \"../ai/mockAi.js\";\nimport type { AiClient } from \"../ai/types.js\";\nimport type { GitxPlugin } from \"./plugin.js\";\nimport {\n detectProviderFromRemote,\n getGitRemoteOriginUrl,\n inferRepoSlugFromRemote,\n isInsideGitRepo\n} from \"../utils/git.js\";\nimport { GitxError } from \"../utils/errors.js\";\nimport type { RepoContext } from \"./context.js\";\n\nexport class Gitx {\n public readonly config: GitxConfig;\n public readonly ai: AiClient;\n public readonly cwd: string;\n private readonly plugins: GitxPlugin[] = [];\n\n private constructor(args: { config: GitxConfig; ai: AiClient; cwd: string }) {\n this.config = args.config;\n this.ai = args.ai;\n this.cwd = args.cwd;\n }\n\n static async fromCwd(cwd = process.cwd()): Promise<Gitx> {\n const config = await loadConfig(cwd);\n const ai = new MockAi();\n return new Gitx({ config, ai, cwd });\n }\n\n async use(plugin: GitxPlugin): Promise<void> {\n this.plugins.push(plugin);\n await plugin.setup(this);\n }\n\n async getRepoContext(): Promise<RepoContext> {\n if (!(await isInsideGitRepo(this.cwd))) {\n throw new GitxError(\n \"No git repo detected in the current directory. Run gitx inside a git repository.\",\n { exitCode: 2 }\n );\n }\n\n const originUrl = await getGitRemoteOriginUrl(this.cwd);\n if (!originUrl) {\n throw new GitxError(\"No `remote.origin.url` detected. Add an origin remote and retry.\", {\n exitCode: 2\n });\n }\n\n const provider = detectProviderFromRemote(originUrl);\n if (!provider) {\n throw new GitxError(\n `Unsupported git remote host for auto-detection: ${originUrl}.`,\n { exitCode: 2 }\n );\n }\n\n const token = this.config.providers[provider]?.token;\n if (!token) {\n throw new GitxError(\n `No token configured for provider \"${provider}\". Re-run \\`gitx init\\` and add credentials for ${provider}.`,\n { exitCode: 2 }\n );\n }\n\n const repoSlug = inferRepoSlugFromRemote(originUrl);\n if (!repoSlug) {\n throw new GitxError(\n `Could not infer repo slug from origin remote: ${originUrl}.`,\n { exitCode: 2 }\n );\n }\n\n return { provider, repoSlug, token };\n }\n\n async getRepoSlug(): Promise<string> {\n const ctx = await this.getRepoContext();\n return ctx.repoSlug;\n }\n\n async getProvider(): Promise<RepoContext[\"provider\"]> {\n const ctx = await this.getRepoContext();\n return ctx.provider;\n }\n\n async getToken(): Promise<string> {\n const ctx = await this.getRepoContext();\n return ctx.token;\n }\n}\n"]}
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import type { ProviderKind } from "./provider.js";
|
|
2
1
|
export interface GitxConfig {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Provider credentials. Configure one or more providers up-front using `gitx init`.
|
|
4
|
+
* At runtime, gitx detects which provider to use based on the current repo's `remote.origin.url`.
|
|
5
|
+
*/
|
|
6
|
+
providers: Partial<Record<"github" | "gitlab" | "azure", {
|
|
7
|
+
token: string;
|
|
8
|
+
}>>;
|
|
9
|
+
/**
|
|
10
|
+
* Optional default branch to assume when it can't be inferred from the repo.
|
|
11
|
+
* If omitted, gitx will attempt to infer it from git remotes.
|
|
12
|
+
*/
|
|
13
|
+
defaultBranch?: string;
|
|
7
14
|
}
|
|
8
15
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,GAAG,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAE7E;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
package/dist/types/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"","sourcesContent":["export interface GitxConfig {\n /**\n * Provider credentials. Configure one or more providers up-front using `gitx init`.\n * At runtime, gitx detects which provider to use based on the current repo's `remote.origin.url`.\n */\n providers: Partial<Record<\"github\" | \"gitlab\" | \"azure\", { token: string }>>;\n\n /**\n * Optional default branch to assume when it can't be inferred from the repo.\n * If omitted, gitx will attempt to infer it from git remotes.\n */\n defaultBranch?: string;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProviderKind } from "../types/provider.js";
|
|
2
|
+
export declare function getGitRemoteOriginUrl(cwd?: string): Promise<string | undefined>;
|
|
3
|
+
export declare function isInsideGitRepo(cwd?: string): Promise<boolean>;
|
|
4
|
+
export declare function inferRepoSlugFromRemote(url: string): string | undefined;
|
|
5
|
+
export declare function resolveRepoSlugFromCwd(cwd?: string): Promise<string | undefined>;
|
|
6
|
+
export declare function detectProviderFromRemote(url: string): ProviderKind | undefined;
|
|
7
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,wBAAsB,qBAAqB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ5F;AAED,wBAAsB,eAAe,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3E;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqBvE;AAED,wBAAsB,sBAAsB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAI7F;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAM9E"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
export async function getGitRemoteOriginUrl(cwd = process.cwd()) {
|
|
5
|
+
try {
|
|
6
|
+
const { stdout } = await execFileAsync("git", ["config", "--get", "remote.origin.url"], { cwd });
|
|
7
|
+
const url = String(stdout ?? "").trim();
|
|
8
|
+
return url.length > 0 ? url : undefined;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function isInsideGitRepo(cwd = process.cwd()) {
|
|
15
|
+
try {
|
|
16
|
+
const { stdout } = await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], { cwd });
|
|
17
|
+
return String(stdout ?? "").trim() === "true";
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function inferRepoSlugFromRemote(url) {
|
|
24
|
+
// Supports common GitHub/GitLab URL formats:
|
|
25
|
+
// - git@github.com:owner/repo.git
|
|
26
|
+
// - https://github.com/owner/repo(.git)
|
|
27
|
+
// - ssh://git@github.com/owner/repo(.git)
|
|
28
|
+
const cleaned = url.trim();
|
|
29
|
+
const patterns = [
|
|
30
|
+
/^(?:git@)(?:github\.com|gitlab\.com):(?<owner>[^/]+)\/(?<repo>[^/]+?)(?:\.git)?$/i,
|
|
31
|
+
/^(?:https?:\/\/)(?:github\.com|gitlab\.com)\/(?<owner>[^/]+)\/(?<repo>[^/]+?)(?:\.git)?(?:\/)?$/i,
|
|
32
|
+
/^(?:ssh:\/\/)(?:git@)(?:github\.com|gitlab\.com)\/(?<owner>[^/]+)\/(?<repo>[^/]+?)(?:\.git)?$/i
|
|
33
|
+
];
|
|
34
|
+
for (const re of patterns) {
|
|
35
|
+
const match = re.exec(cleaned);
|
|
36
|
+
const owner = match?.groups?.["owner"];
|
|
37
|
+
const repo = match?.groups?.["repo"];
|
|
38
|
+
if (owner && repo)
|
|
39
|
+
return `${owner}/${repo}`;
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
export async function resolveRepoSlugFromCwd(cwd = process.cwd()) {
|
|
44
|
+
const originUrl = await getGitRemoteOriginUrl(cwd);
|
|
45
|
+
if (!originUrl)
|
|
46
|
+
return undefined;
|
|
47
|
+
return inferRepoSlugFromRemote(originUrl);
|
|
48
|
+
}
|
|
49
|
+
export function detectProviderFromRemote(url) {
|
|
50
|
+
const cleaned = url.trim();
|
|
51
|
+
if (cleaned.includes("github.com"))
|
|
52
|
+
return "github";
|
|
53
|
+
if (cleaned.includes("gitlab.com"))
|
|
54
|
+
return "gitlab";
|
|
55
|
+
if (cleaned.includes("dev.azure.com") || cleaned.includes("visualstudio.com"))
|
|
56
|
+
return "azure";
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC7D,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACjG,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACvD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/F,OAAO,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,GAAW;IACjD,6CAA6C;IAC7C,kCAAkC;IAClC,wCAAwC;IACxC,0CAA0C;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAa;QACzB,mFAAmF;QACnF,kGAAkG;QAClG,gGAAgG;KACjG,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC9D,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAAE,OAAO,OAAO,CAAC;IAC9F,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { ProviderKind } from \"../types/provider.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function getGitRemoteOriginUrl(cwd = process.cwd()): Promise<string | undefined> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"config\", \"--get\", \"remote.origin.url\"], { cwd });\n const url = String(stdout ?? \"\").trim();\n return url.length > 0 ? url : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport async function isInsideGitRepo(cwd = process.cwd()): Promise<boolean> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], { cwd });\n return String(stdout ?? \"\").trim() === \"true\";\n } catch {\n return false;\n }\n}\n\nexport function inferRepoSlugFromRemote(url: string): string | undefined {\n // Supports common GitHub/GitLab URL formats:\n // - git@github.com:owner/repo.git\n // - https://github.com/owner/repo(.git)\n // - ssh://git@github.com/owner/repo(.git)\n const cleaned = url.trim();\n\n const patterns: RegExp[] = [\n /^(?:git@)(?:github\\.com|gitlab\\.com):(?<owner>[^/]+)\\/(?<repo>[^/]+?)(?:\\.git)?$/i,\n /^(?:https?:\\/\\/)(?:github\\.com|gitlab\\.com)\\/(?<owner>[^/]+)\\/(?<repo>[^/]+?)(?:\\.git)?(?:\\/)?$/i,\n /^(?:ssh:\\/\\/)(?:git@)(?:github\\.com|gitlab\\.com)\\/(?<owner>[^/]+)\\/(?<repo>[^/]+?)(?:\\.git)?$/i\n ];\n\n for (const re of patterns) {\n const match = re.exec(cleaned);\n const owner = match?.groups?.[\"owner\"];\n const repo = match?.groups?.[\"repo\"];\n if (owner && repo) return `${owner}/${repo}`;\n }\n\n return undefined;\n}\n\nexport async function resolveRepoSlugFromCwd(cwd = process.cwd()): Promise<string | undefined> {\n const originUrl = await getGitRemoteOriginUrl(cwd);\n if (!originUrl) return undefined;\n return inferRepoSlugFromRemote(originUrl);\n}\n\nexport function detectProviderFromRemote(url: string): ProviderKind | undefined {\n const cleaned = url.trim();\n if (cleaned.includes(\"github.com\")) return \"github\";\n if (cleaned.includes(\"gitlab.com\")) return \"gitlab\";\n if (cleaned.includes(\"dev.azure.com\") || cleaned.includes(\"visualstudio.com\")) return \"azure\";\n return undefined;\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function validateNonEmpty(label: string): (value: unknown) => true | string;
|
|
2
2
|
export declare function assertValid(result: true | string, label?: string): void;
|
|
3
3
|
export declare function validateRepoSlug(value: unknown): true | string;
|
|
4
|
+
export declare function validateOptionalRepoSlug(value: unknown): true | string;
|
|
4
5
|
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,CAMjF;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,SAAkB,GAAG,IAAI,CAIhF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAY9D"}
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,CAMjF;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,SAAkB,GAAG,IAAI,CAIhF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAY9D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAItE"}
|
package/dist/utils/validators.js
CHANGED
|
@@ -28,4 +28,11 @@ export function validateRepoSlug(value) {
|
|
|
28
28
|
}
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
|
+
export function validateOptionalRepoSlug(value) {
|
|
32
|
+
if (typeof value !== "string")
|
|
33
|
+
return "Repo must be a string";
|
|
34
|
+
if (value.trim().length === 0)
|
|
35
|
+
return true;
|
|
36
|
+
return validateRepoSlug(value);
|
|
37
|
+
}
|
|
31
38
|
//# sourceMappingURL=validators.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,CAAC,KAAc,EAAE,EAAE;QACxB,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,GAAG,KAAK,mBAAmB,CAAC;QAClE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,KAAK,cAAc,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAqB,EAAE,KAAK,GAAG,eAAe;IACxE,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,MAAM,EAAE,CAAC;IAC1E,MAAM,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,uBAAuB,CAAC;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC;IACpD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,8BAA8B,CAAC;IAEjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,gCAAgC,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { GitxError } from \"./errors.js\";\n\nexport function validateNonEmpty(label: string): (value: unknown) => true | string {\n return (value: unknown) => {\n if (typeof value !== \"string\") return `${label} must be a string`;\n if (value.trim().length === 0) return `${label} is required`;\n return true;\n };\n}\n\nexport function assertValid(result: true | string, label = \"Invalid input\"): void {\n if (result === true) return;\n const message = result.startsWith(label) ? result : `${label}: ${result}`;\n throw new GitxError(message, { exitCode: 2 });\n}\n\nexport function validateRepoSlug(value: unknown): true | string {\n if (typeof value !== \"string\") return \"Repo must be a string\";\n const trimmed = value.trim();\n if (trimmed.length === 0) return \"Repo is required\";\n if (trimmed.includes(\" \")) return \"Repo must not contain spaces\";\n\n const parts = trimmed.split(\"/\");\n if (parts.length !== 2 || parts[0].length === 0 || parts[1].length === 0) {\n return \"Repo must look like owner/name\";\n }\n\n return true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,CAAC,KAAc,EAAE,EAAE;QACxB,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,GAAG,KAAK,mBAAmB,CAAC;QAClE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,KAAK,cAAc,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAqB,EAAE,KAAK,GAAG,eAAe;IACxE,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,MAAM,EAAE,CAAC;IAC1E,MAAM,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,uBAAuB,CAAC;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC;IACpD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,8BAA8B,CAAC;IAEjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,gCAAgC,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,uBAAuB,CAAC;IAC9D,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC","sourcesContent":["import { GitxError } from \"./errors.js\";\n\nexport function validateNonEmpty(label: string): (value: unknown) => true | string {\n return (value: unknown) => {\n if (typeof value !== \"string\") return `${label} must be a string`;\n if (value.trim().length === 0) return `${label} is required`;\n return true;\n };\n}\n\nexport function assertValid(result: true | string, label = \"Invalid input\"): void {\n if (result === true) return;\n const message = result.startsWith(label) ? result : `${label}: ${result}`;\n throw new GitxError(message, { exitCode: 2 });\n}\n\nexport function validateRepoSlug(value: unknown): true | string {\n if (typeof value !== \"string\") return \"Repo must be a string\";\n const trimmed = value.trim();\n if (trimmed.length === 0) return \"Repo is required\";\n if (trimmed.includes(\" \")) return \"Repo must not contain spaces\";\n\n const parts = trimmed.split(\"/\");\n if (parts.length !== 2 || parts[0].length === 0 || parts[1].length === 0) {\n return \"Repo must look like owner/name\";\n }\n\n return true;\n}\n\nexport function validateOptionalRepoSlug(value: unknown): true | string {\n if (typeof value !== \"string\") return \"Repo must be a string\";\n if (value.trim().length === 0) return true;\n return validateRepoSlug(value);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g-abhishek/gitx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "AI-powered Git workflow automation CLI and SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"dev": "node --enable-source-maps dist/bin.js",
|
|
43
43
|
"lint": "eslint .",
|
|
44
44
|
"format": "prettier -w .",
|
|
45
|
+
"prepack": "npm run build",
|
|
45
46
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|