gh-axi 0.1.20 → 0.1.22

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
@@ -14,6 +14,24 @@ GitHub CLI for agents — designed with [AXI](https://github.com/kunchenguid/axi
14
14
  Wraps the official `gh` cli with token-efficient TOON output, contextual next-step suggestions, and structured error handling.
15
15
  Built for autonomous agents that interact with GitHub via shell execution.
16
16
 
17
+ ## Benchmarks
18
+
19
+ Agent ergonomics is measurable.
20
+ The [axi benchmark](https://axi.md) runs the same 17 real-world GitHub tasks (issue triage, PR review prep, CI failure investigation, and more) through 5 GitHub interface setups - 5 repeats each, with `claude-sonnet-4-6` as the agent and an LLM judge scoring task success.
21
+
22
+ gh-axi posts the lowest input tokens, cost, and duration of all 5 conditions, and is the only one to pass every run:
23
+
24
+ | Condition | Avg Input Tokens | Avg Cost/Task | Avg Duration | Avg Turns | Success |
25
+ | -------------------------- | ---------------- | ------------- | ------------ | --------- | -------- |
26
+ | **gh-axi** | **46,462** | **$0.050** | **15.7s** | **3** | **100%** |
27
+ | gh CLI (raw) | 47,076 | $0.054 | 17.4s | 3 | 86% |
28
+ | GitHub MCP code execution | 137,409 | $0.101 | 43.4s | 7 | 84% |
29
+ | GitHub MCP + ToolSearch | 153,621 | $0.147 | 41.1s | 8 | 82% |
30
+ | GitHub MCP (eager schemas) | 175,757 | $0.148 | 34.2s | 6 | 87% |
31
+
32
+ Against raw `gh` - the very CLI this tool wraps - that is 100% vs 86% task success at 7% lower cost.
33
+ Against the GitHub MCP server it is 66% cheaper, with 74% fewer input tokens and half the turns.
34
+
17
35
  ## Quick Start
18
36
 
19
37
  Install the gh-axi skill in the [Agent Skills](https://agentskills.io) format with [`npx skills`](https://github.com/vercel-labs/skills):
@@ -27,6 +45,7 @@ The skill teaches your agent to run gh-axi through `npx -y gh-axi`, so the CLI c
27
45
  You still need [`gh`](https://cli.github.com/) installed and authenticated via `gh auth login` (Node 20+ required).
28
46
 
29
47
  The skill is not a user-facing slash command (`user-invocable: false`).
48
+ Its frontmatter also includes Hermes Agent metadata (`metadata.hermes`) so Hermes can categorize it as a `devops` skill for GitHub, git, CI, pull requests, and releases.
30
49
  Just ask for anything that touches GitHub - filing issues, reviewing PRs, checking CI runs, cutting releases - and the agent loads the skill on its own when it recognizes the task.
31
50
 
32
51
  `-g` installs the skill for all projects (`~/.claude/skills/`, for example); drop it to install for the current project only (`.claude/skills/`).
@@ -70,6 +89,9 @@ gh-axi run view --job 789012 --log-failed # show failed log lines for one job
70
89
  gh-axi setup hooks # install optional agent session hooks
71
90
  ```
72
91
 
92
+ For multi-line issue, PR, review, or comment text, write Markdown to a UTF-8 file and pass `--body-file <path>` anywhere `--body` is accepted.
93
+ For releases, `--body` and `--body-file` are aliases for release notes, alongside `--notes` and `--notes-file`.
94
+
73
95
  Long `run view --log` and `run view --log-failed` output shows the last 20,000 characters so CI failures stay visible.
74
96
  When truncation happens, gh-axi best-effort saves the complete log to a temp file, includes it as `full_log`, and prints a `help:` hint telling agents to grep that file for earlier context.
75
97
 
@@ -97,6 +119,7 @@ Repository targeting is command-first too:
97
119
 
98
120
  - `gh-axi issue list -R owner/name`
99
121
  - `gh-axi issue list --repo owner/name`
122
+ - `gh-axi issue list --repo=owner/name`
100
123
  - `gh-axi run list -R owner/name`
101
124
  - `gh-axi search issues "login bug" --repo owner/name`
102
125
 
@@ -108,13 +131,13 @@ When a command also needs a destination repository, use a dedicated flag for it:
108
131
 
109
132
  ```sh
110
133
  pnpm run build # Compile TypeScript to dist/
111
- pnpm run build:skill # Regenerate skills/gh-axi/SKILL.md from shared CLI guidance
134
+ pnpm run build:skill # Regenerate skills/gh-axi/SKILL.md from shared skill source
112
135
  pnpm run dev # Run CLI directly with tsx
113
136
  pnpm test # Run tests with vitest
114
137
  pnpm run test:watch # Run tests in watch mode
115
138
  ```
116
139
 
117
- The committed `skills/gh-axi/SKILL.md` is generated by `pnpm run build:skill`; `pnpm test` fails if it drifts from the shared CLI guidance.
140
+ The committed `skills/gh-axi/SKILL.md` is generated by `pnpm run build:skill`; `pnpm test` fails if it drifts from the shared CLI guidance or generated skill frontmatter.
118
141
  The npm package includes `skills/gh-axi/`, so published releases ship the same installable Agent Skill documented in Quick Start.
119
142
 
120
143
  ## License
@@ -1,12 +1,12 @@
1
- /** Get a flag's value without modifying the args array. */
1
+ /** Get a flag's value from --flag value or --flag=value without modifying args. */
2
2
  export declare function getFlag(args: string[], name: string): string | undefined;
3
- /** Get a flag's value and remove both the flag and value from args. */
3
+ /** Get a flag's value from --flag value or --flag=value and remove it from args. */
4
4
  export declare function takeFlag(args: string[], flag: string): string | undefined;
5
5
  /** Check if a boolean flag is present. */
6
6
  export declare function hasFlag(args: string[], flag: string): boolean;
7
7
  /** Check if a boolean flag is present and remove it from args. */
8
8
  export declare function takeBoolFlag(args: string[], flag: string): boolean;
9
- /** Collect all values for a repeatable flag. */
9
+ /** Collect all values for a repeatable flag in --flag value or --flag=value form. */
10
10
  export declare function getAllFlags(args: string[], flag: string): string[];
11
11
  /** Get the first positional arg (non-flag) starting from startIndex. */
12
12
  export declare function getPositional(args: string[], startIndex: number): string | undefined;
package/dist/src/args.js CHANGED
@@ -1,19 +1,40 @@
1
- import { AxiError } from './errors.js';
2
- /** Get a flag's value without modifying the args array. */
1
+ import { AxiError } from "./errors.js";
2
+ function flagEqualsPrefix(flag) {
3
+ return `${flag}=`;
4
+ }
5
+ /** Get a flag's value from --flag value or --flag=value without modifying args. */
3
6
  export function getFlag(args, name) {
4
- const idx = args.indexOf(name);
5
- if (idx === -1 || idx + 1 >= args.length)
6
- return undefined;
7
- return args[idx + 1];
7
+ const equalsPrefix = flagEqualsPrefix(name);
8
+ for (let i = 0; i < args.length; i++) {
9
+ const arg = args[i];
10
+ if (arg === name) {
11
+ if (i + 1 >= args.length)
12
+ return undefined;
13
+ return args[i + 1];
14
+ }
15
+ if (arg.startsWith(equalsPrefix)) {
16
+ return arg.slice(equalsPrefix.length);
17
+ }
18
+ }
19
+ return undefined;
8
20
  }
9
- /** Get a flag's value and remove both the flag and value from args. */
21
+ /** Get a flag's value from --flag value or --flag=value and remove it from args. */
10
22
  export function takeFlag(args, flag) {
11
- const idx = args.indexOf(flag);
12
- if (idx === -1)
13
- return undefined;
14
- const val = args[idx + 1];
15
- args.splice(idx, 2);
16
- return val;
23
+ const equalsPrefix = flagEqualsPrefix(flag);
24
+ for (let i = 0; i < args.length; i++) {
25
+ const arg = args[i];
26
+ if (arg === flag) {
27
+ const val = args[i + 1];
28
+ args.splice(i, 2);
29
+ return val;
30
+ }
31
+ if (arg.startsWith(equalsPrefix)) {
32
+ const val = arg.slice(equalsPrefix.length);
33
+ args.splice(i, 1);
34
+ return val;
35
+ }
36
+ }
37
+ return undefined;
17
38
  }
18
39
  /** Check if a boolean flag is present. */
19
40
  export function hasFlag(args, flag) {
@@ -27,21 +48,26 @@ export function takeBoolFlag(args, flag) {
27
48
  args.splice(idx, 1);
28
49
  return true;
29
50
  }
30
- /** Collect all values for a repeatable flag. */
51
+ /** Collect all values for a repeatable flag in --flag value or --flag=value form. */
31
52
  export function getAllFlags(args, flag) {
32
53
  const result = [];
54
+ const equalsPrefix = flagEqualsPrefix(flag);
33
55
  for (let i = 0; i < args.length; i++) {
34
- if (args[i] === flag && i + 1 < args.length) {
56
+ const arg = args[i];
57
+ if (arg === flag && i + 1 < args.length) {
35
58
  result.push(args[i + 1]);
36
59
  i++;
37
60
  }
61
+ else if (arg.startsWith(equalsPrefix)) {
62
+ result.push(arg.slice(equalsPrefix.length));
63
+ }
38
64
  }
39
65
  return result;
40
66
  }
41
67
  /** Get the first positional arg (non-flag) starting from startIndex. */
42
68
  export function getPositional(args, startIndex) {
43
69
  for (let i = startIndex; i < args.length; i++) {
44
- if (!args[i].startsWith('--'))
70
+ if (!args[i].startsWith("--"))
45
71
  return args[i];
46
72
  }
47
73
  return undefined;
@@ -49,17 +75,17 @@ export function getPositional(args, startIndex) {
49
75
  /** Parse and validate a required numeric argument. */
50
76
  export function requireNumber(raw, label) {
51
77
  if (!raw)
52
- throw new AxiError(`Missing ${label} number`, 'VALIDATION_ERROR');
78
+ throw new AxiError(`Missing ${label} number`, "VALIDATION_ERROR");
53
79
  const n = parseInt(raw, 10);
54
80
  if (isNaN(n))
55
- throw new AxiError(`Invalid ${label} number: ${raw}`, 'VALIDATION_ERROR');
81
+ throw new AxiError(`Invalid ${label} number: ${raw}`, "VALIDATION_ERROR");
56
82
  return n;
57
83
  }
58
84
  /** Find the first numeric positional arg, remove it from args, and return it as a number. */
59
85
  export function takeNumber(args, label) {
60
86
  const raw = args.find((a) => /^\d+$/.test(a));
61
87
  if (!raw)
62
- throw new AxiError(`Missing ${label} number`, 'VALIDATION_ERROR');
88
+ throw new AxiError(`Missing ${label} number`, "VALIDATION_ERROR");
63
89
  args.splice(args.indexOf(raw), 1);
64
90
  return Number(raw);
65
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/args.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,22 @@
1
+ interface TakeBodyOptions {
2
+ required?: boolean;
3
+ inlineFlags?: string[];
4
+ fileFlags?: string[];
5
+ valueBoundaryFlags?: string[];
6
+ label?: string;
7
+ suggestions?: string[];
8
+ }
1
9
  /**
2
- * Shared body cleaning and truncation for all entity types.
10
+ * Resolve a command body from inline text or a UTF-8 file and remove the flags.
3
11
  *
4
- * Cleanups are only applied when content needs truncation.
5
- * When --full is used, the raw body is returned as-is.
12
+ * Optional bodies accept at most one source. Required bodies enforce exactly
13
+ * one source and raise validation errors for missing, conflicting, or
14
+ * unreadable input.
6
15
  */
16
+ export declare function takeBody(args: string[], options: TakeBodyOptions & {
17
+ required: true;
18
+ }): string;
19
+ export declare function takeBody(args: string[], options?: TakeBodyOptions): string | undefined;
7
20
  /** Clean up a body string to reduce token cost before truncation. */
8
21
  export declare function cleanBody(text: string): string;
9
22
  /**
@@ -12,3 +25,4 @@ export declare function cleanBody(text: string): string;
12
25
  * Returns the raw body when it fits within maxLen.
13
26
  */
14
27
  export declare function truncateBody(body: unknown, maxLen?: number): string;
28
+ export {};
package/dist/src/body.js CHANGED
@@ -1,24 +1,118 @@
1
- /**
2
- * Shared body cleaning and truncation for all entity types.
3
- *
4
- * Cleanups are only applied when content needs truncation.
5
- * When --full is used, the raw body is returned as-is.
6
- */
1
+ import { readFileSync } from "node:fs";
2
+ import { AxiError } from "./errors.js";
3
+ function defaultSuggestions(label) {
4
+ return [
5
+ `Use --body "..." for inline ${label}, or --body-file <path> for markdown from a file`,
6
+ ];
7
+ }
8
+ function isMissingValue(value) {
9
+ return value === undefined || value.trim() === "";
10
+ }
11
+ function isValueBoundary(arg, flags) {
12
+ if (arg === undefined)
13
+ return false;
14
+ return flags.some((flag) => arg === flag || arg.startsWith(`${flag}=`));
15
+ }
16
+ function takeFlagMatches(args, flags, valueBoundaryFlags) {
17
+ const matches = [];
18
+ for (let index = 0; index < args.length; index++) {
19
+ const arg = args[index];
20
+ let matched = false;
21
+ for (const flag of flags) {
22
+ const equalsPrefix = `${flag}=`;
23
+ if (arg === flag) {
24
+ const next = args[index + 1];
25
+ const value = next !== undefined && !isValueBoundary(next, valueBoundaryFlags)
26
+ ? next
27
+ : undefined;
28
+ const consumeCount = value === undefined ? 1 : 2;
29
+ args.splice(index, consumeCount);
30
+ index--;
31
+ matches.push({ flag, value });
32
+ matched = true;
33
+ break;
34
+ }
35
+ if (arg.startsWith(equalsPrefix)) {
36
+ args.splice(index, 1);
37
+ index--;
38
+ matches.push({ flag, value: arg.slice(equalsPrefix.length) });
39
+ matched = true;
40
+ break;
41
+ }
42
+ }
43
+ if (matched)
44
+ continue;
45
+ }
46
+ return matches;
47
+ }
48
+ function readBodyFile(flag, path, suggestions) {
49
+ try {
50
+ return readFileSync(path, "utf8");
51
+ }
52
+ catch (error) {
53
+ const code = error && typeof error === "object" && "code" in error
54
+ ? String(error.code)
55
+ : "UNKNOWN";
56
+ if (code === "ENOENT") {
57
+ throw new AxiError(`${flag} path not found: ${path}`, "VALIDATION_ERROR", suggestions);
58
+ }
59
+ if (code === "EISDIR") {
60
+ throw new AxiError(`${flag} must point to a readable UTF-8 file, not a directory: ${path}`, "VALIDATION_ERROR", suggestions);
61
+ }
62
+ throw new AxiError(`Could not read ${flag} path: ${path} (${code})`, "VALIDATION_ERROR", suggestions);
63
+ }
64
+ }
65
+ export function takeBody(args, options = {}) {
66
+ const inlineFlags = options.inlineFlags ?? ["--body"];
67
+ const fileFlags = options.fileFlags ?? ["--body-file"];
68
+ const valueBoundaryFlags = [
69
+ ...new Set([
70
+ ...inlineFlags,
71
+ ...fileFlags,
72
+ ...(options.valueBoundaryFlags ?? []),
73
+ ]),
74
+ ];
75
+ const label = options.label ?? "body";
76
+ const suggestions = options.suggestions ?? defaultSuggestions(label);
77
+ const inlineMatches = takeFlagMatches(args, inlineFlags, valueBoundaryFlags);
78
+ const fileMatches = takeFlagMatches(args, fileFlags, valueBoundaryFlags);
79
+ const matches = [...inlineMatches, ...fileMatches];
80
+ if (matches.length === 0) {
81
+ if (options.required) {
82
+ throw new AxiError(`${inlineFlags[0]} or ${fileFlags[0]} is required`, "VALIDATION_ERROR", suggestions);
83
+ }
84
+ return undefined;
85
+ }
86
+ if (matches.length > 1) {
87
+ throw new AxiError(`Use only one ${label} source: ${matches.map((m) => m.flag).join(", ")} were provided`, "VALIDATION_ERROR", suggestions);
88
+ }
89
+ const match = matches[0];
90
+ const value = match.value;
91
+ if (isMissingValue(value)) {
92
+ const noun = fileFlags.includes(match.flag) ? "path" : "text";
93
+ throw new AxiError(`${match.flag} requires ${noun}`, "VALIDATION_ERROR", suggestions);
94
+ }
95
+ const resolvedValue = value ?? "";
96
+ if (fileFlags.includes(match.flag)) {
97
+ return readBodyFile(match.flag, resolvedValue, suggestions);
98
+ }
99
+ return resolvedValue;
100
+ }
7
101
  /** Clean up a body string to reduce token cost before truncation. */
8
102
  export function cleanBody(text) {
9
103
  // Normalize GitHub PR/issue URLs to short references
10
- let s = text.replace(/\[([^\]]+)\]\(https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/(\d+)\)/g, '[$1](PR#$2)');
11
- s = s.replace(/\[([^\]]+)\]\(https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)\)/g, '[$1](Issue#$2)');
12
- s = s.replace(/(?<!\()https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/(\d+)/g, 'PR#$1');
13
- s = s.replace(/(?<!\()https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/g, 'Issue#$1');
104
+ let s = text.replace(/\[([^\]]+)\]\(https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/(\d+)\)/g, "[$1](PR#$2)");
105
+ s = s.replace(/\[([^\]]+)\]\(https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)\)/g, "[$1](Issue#$2)");
106
+ s = s.replace(/(?<!\()https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/(\d+)/g, "PR#$1");
107
+ s = s.replace(/(?<!\()https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/g, "Issue#$1");
14
108
  // Strip markdown image embeds: ![alt](url) → [image: alt]
15
- s = s.replace(/!\[([^\]]*)\]\([^)]+\)/g, (_m, alt) => alt ? `[image: ${alt}]` : '[image]');
109
+ s = s.replace(/!\[([^\]]*)\]\([^)]+\)/g, (_m, alt) => alt ? `[image: ${alt}]` : "[image]");
16
110
  // Strip long URLs (>80 chars) in markdown links: [text](longurl) → [text]
17
- s = s.replace(/\[([^\]]+)\]\(([^)]{80,})\)/g, '[$1]');
111
+ s = s.replace(/\[([^\]]+)\]\(([^)]{80,})\)/g, "[$1]");
18
112
  // Strip standalone long URLs (>100 chars) not in markdown
19
- s = s.replace(/(?<!\()https?:\/\/\S{100,}/g, '[long URL removed]');
113
+ s = s.replace(/(?<!\()https?:\/\/\S{100,}/g, "[long URL removed]");
20
114
  // Collapse email-style quoted blocks (lines starting with >) to a summary
21
- s = s.replace(/(^|\n)(>\s?[^\n]*\n?){3,}/gm, '$1[quoted text removed]\n');
115
+ s = s.replace(/(^|\n)(>\s?[^\n]*\n?){3,}/gm, "$1[quoted text removed]\n");
22
116
  return s;
23
117
  }
24
118
  /**
@@ -27,18 +121,24 @@ export function cleanBody(text) {
27
121
  * Returns the raw body when it fits within maxLen.
28
122
  */
29
123
  export function truncateBody(body, maxLen = 500) {
30
- if (typeof body !== 'string' || !body)
31
- return '';
124
+ if (typeof body !== "string" || !body)
125
+ return "";
32
126
  if (body.length <= maxLen)
33
127
  return body;
34
128
  const cleaned = cleanBody(body);
35
129
  if (cleaned.length <= maxLen) {
36
130
  // Cleanup made it fit, but content was modified — offer --full for the original
37
131
  if (cleaned !== body) {
38
- return cleaned + '\n(cleaned, ' + body.length + ' chars original — use --full to see original)';
132
+ return (cleaned +
133
+ "\n(cleaned, " +
134
+ body.length +
135
+ " chars original — use --full to see original)");
39
136
  }
40
137
  return cleaned;
41
138
  }
42
- return cleaned.slice(0, maxLen) + '\n... (truncated, ' + cleaned.length + ' chars total — use --full to see complete body)';
139
+ return (cleaned.slice(0, maxLen) +
140
+ "\n... (truncated, " +
141
+ cleaned.length +
142
+ " chars total — use --full to see complete body)");
43
143
  }
44
144
  //# sourceMappingURL=body.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"body.js","sourceRoot":"","sources":["../../src/body.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qEAAqE;AACrE,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,qDAAqD;IACrD,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,mEAAmE,EAAE,aAAa,CAAC,CAAC;IACzG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,qEAAqE,EAAE,gBAAgB,CAAC,CAAC;IACvG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,0DAA0D,EAAE,OAAO,CAAC,CAAC;IACnF,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,4DAA4D,EAAE,UAAU,CAAC,CAAC;IACxF,0DAA0D;IAC1D,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3F,0EAA0E;IAC1E,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;IACtD,0DAA0D;IAC1D,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,6BAA6B,EAAE,oBAAoB,CAAC,CAAC;IACnE,0EAA0E;IAC1E,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,6BAA6B,EAAE,2BAA2B,CAAC,CAAC;IAC1E,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,MAAM,GAAG,GAAG;IACtD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACjD,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,OAAO,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QAC7B,gFAAgF;QAChF,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,OAAO,GAAG,cAAc,GAAG,IAAI,CAAC,MAAM,GAAG,+CAA+C,CAAC;QAClG,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,oBAAoB,GAAG,OAAO,CAAC,MAAM,GAAG,iDAAiD,CAAC;AAC9H,CAAC"}
1
+ {"version":3,"file":"body.js","sourceRoot":"","sources":["../../src/body.ts"],"names":[],"mappings":"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"}
package/dist/src/cli.d.ts CHANGED
@@ -4,6 +4,6 @@ type MainOptions = {
4
4
  argv?: string[];
5
5
  stdout?: CliStdout;
6
6
  };
7
- export declare const TOP_HELP = "usage: gh-axi [command] [args] [flags]\ncommands[11]:\n (none)=dashboard, issue, pr, run, workflow, release, repo, label, search, api, setup\nflags[3]:\n -R/--repo <OWNER/NAME> (after command), --help, -v/-V/--version\nexamples:\n gh-axi\n gh-axi issue list --state open\n gh-axi issue list -R owner/name\n gh-axi issue list --repo owner/name\n gh-axi pr view 42\n gh-axi setup hooks\n";
7
+ export declare const TOP_HELP = "usage: gh-axi [command] [args] [flags]\ncommands[11]:\n (none)=dashboard, issue, pr, run, workflow, release, repo, label, search, api, setup\nflags[3]:\n -R/--repo <OWNER/NAME> (after command), accepts space or equals form, --help, -v/-V/--version\nexamples:\n gh-axi\n gh-axi issue list --state open\n gh-axi issue list -R owner/name\n gh-axi issue list --repo=owner/name\n gh-axi pr view 42\n gh-axi setup hooks\n";
8
8
  export declare function main(options?: MainOptions): Promise<void>;
9
9
  export {};
package/dist/src/cli.js CHANGED
@@ -20,12 +20,12 @@ export const TOP_HELP = `usage: gh-axi [command] [args] [flags]
20
20
  commands[11]:
21
21
  (none)=dashboard, issue, pr, run, workflow, release, repo, label, search, api, setup
22
22
  flags[3]:
23
- -R/--repo <OWNER/NAME> (after command), --help, -v/-V/--version
23
+ -R/--repo <OWNER/NAME> (after command), accepts space or equals form, --help, -v/-V/--version
24
24
  examples:
25
25
  gh-axi
26
26
  gh-axi issue list --state open
27
27
  gh-axi issue list -R owner/name
28
- gh-axi issue list --repo owner/name
28
+ gh-axi issue list --repo=owner/name
29
29
  gh-axi pr view 42
30
30
  gh-axi setup hooks
31
31
  `;
@@ -95,6 +95,10 @@ function parseRepoContextArgs(command, args) {
95
95
  index++;
96
96
  continue;
97
97
  }
98
+ if (arg.startsWith("-R=") && arg.length > 3) {
99
+ repoFlag = arg.slice(3);
100
+ continue;
101
+ }
98
102
  if (arg === "--repo" && index + 1 < args.length) {
99
103
  const value = args[index + 1];
100
104
  repoFlag = value;
@@ -104,6 +108,13 @@ function parseRepoContextArgs(command, args) {
104
108
  index++;
105
109
  continue;
106
110
  }
111
+ if (arg.startsWith("--repo=") && arg.length > "--repo=".length) {
112
+ repoFlag = arg.slice("--repo=".length);
113
+ if (command === "search") {
114
+ stripped.push(arg);
115
+ }
116
+ continue;
117
+ }
107
118
  stripped.push(arg);
108
119
  }
109
120
  return { repoFlag, strippedArgs: stripped };
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import type { RepoContext } from "../context.js";
2
- export declare const ISSUE_HELP = "usage: gh-axi issue <subcommand> [flags]\nsubcommands[14]:\n list, view <number>, create, edit <number>, close <number>, reopen <number>, comment <number>, delete <number>, lock <number>, unlock <number>, pin <number>, unpin <number>, transfer <number>, subissue <add|remove|list>\nflags{list}:\n --state <open|closed|all>, --label <name>, --assignee <login>, --author <login>, --milestone <name>, --sort <created|updated|comments>, --limit <n> (default 30), --fields <a,b,c>\nflags{view}:\n --comments, --full (show complete body without truncation)\nflags{create}:\n --title <text> (required), --body <text>, --assignee <login>, --label <name>, --milestone <name>, --type <name>\nflags{edit}:\n --title, --body, --add-label, --remove-label, --add-assignee, --remove-assignee, --milestone, --type <name>, --no-type\nflags{close}:\n --reason <completed|not_planned>, --comment <text>\nflags{comment}:\n --body <text> (required)\nflags{transfer}:\n --to-repo <owner/name> (required)\nsubissue:\n add <parent> <child> [<child> ...], remove <parent> <child>, list <parent>\nexamples:\n gh-axi issue list --state closed --label bug\n gh-axi issue view 42 --comments\n gh-axi issue create --title \"Fix login\" --body \"Steps to reproduce...\"\n gh-axi issue close 42 --reason completed\n gh-axi issue transfer 42 -R source/repo --to-repo dest/repo\n gh-axi issue subissue add 16 20 101 125\n gh-axi issue subissue list 16";
2
+ export declare const ISSUE_HELP = "usage: gh-axi issue <subcommand> [flags]\nsubcommands[14]:\n list, view <number>, create, edit <number>, close <number>, reopen <number>, comment <number>, delete <number>, lock <number>, unlock <number>, pin <number>, unpin <number>, transfer <number>, subissue <add|remove|list>\nflags{list}:\n --state <open|closed|all>, --label <name>, --assignee <login>, --author <login>, --milestone <name>, --sort <created|updated|comments>, --limit <n> (default 30), --fields <a,b,c>\nflags{view}:\n --comments, --full (show complete body without truncation)\nflags{create}:\n --title <text> (required), --body <text> or --body-file <path>, --assignee <login>, --label <name>, --milestone <name>, --type <name>\nflags{edit}:\n --title, --body <text> or --body-file <path>, --add-label, --remove-label, --add-assignee, --remove-assignee, --milestone, --type <name>, --no-type\nflags{close}:\n --reason <completed|not_planned>, --comment <text>\nflags{comment}:\n --body <text> or --body-file <path> (required)\nflags{transfer}:\n --to-repo <owner/name> (required)\nsubissue:\n add <parent> <child> [<child> ...], remove <parent> <child>, list <parent>\nexamples:\n gh-axi issue list --state closed --label bug\n gh-axi issue view 42 --comments\n gh-axi issue create --title \"Fix login\" --body \"Steps to reproduce...\"\n gh-axi issue comment 42 --body-file comment.md\n gh-axi issue close 42 --reason completed\n gh-axi issue transfer 42 -R source/repo --to-repo dest/repo\n gh-axi issue subissue add 16 20 101 125\n gh-axi issue subissue list 16";
3
3
  export declare const SUBISSUE_HELP = "usage: gh-axi issue subissue <add|remove|list> <parent> [child...]\nsubcommands[3]:\n add <parent> <child> [<child> ...], remove <parent> <child>, list <parent>\nexamples:\n gh-axi issue subissue add 16 20 101 125\n gh-axi issue subissue remove 16 101\n gh-axi issue subissue list 16";
4
4
  export declare function issueCommand(args: string[], ctx?: RepoContext): Promise<string>;
@@ -1,8 +1,8 @@
1
1
  import { ghJson, ghExec, ghRaw } from "../gh.js";
2
2
  import { AxiError, mapGhError } from "../errors.js";
3
3
  import { getSuggestions } from "../suggestions.js";
4
- import { getFlag, hasFlag, getPositional, requireNumber, takeFlag, takeBoolFlag, } from "../args.js";
5
- import { truncateBody } from "../body.js";
4
+ import { hasFlag, getFlag, getPositional, requireNumber, takeFlag, takeBoolFlag, } from "../args.js";
5
+ import { takeBody, truncateBody } from "../body.js";
6
6
  import { parseFields } from "../fields.js";
7
7
  import { formatCountLine } from "../format.js";
8
8
  import { field, pluck, joinArray, relativeTime, lower, custom, renderList, renderDetail, renderHelp, renderError, renderOutput, } from "../toon.js";
@@ -17,13 +17,13 @@ flags{list}:
17
17
  flags{view}:
18
18
  --comments, --full (show complete body without truncation)
19
19
  flags{create}:
20
- --title <text> (required), --body <text>, --assignee <login>, --label <name>, --milestone <name>, --type <name>
20
+ --title <text> (required), --body <text> or --body-file <path>, --assignee <login>, --label <name>, --milestone <name>, --type <name>
21
21
  flags{edit}:
22
- --title, --body, --add-label, --remove-label, --add-assignee, --remove-assignee, --milestone, --type <name>, --no-type
22
+ --title, --body <text> or --body-file <path>, --add-label, --remove-label, --add-assignee, --remove-assignee, --milestone, --type <name>, --no-type
23
23
  flags{close}:
24
24
  --reason <completed|not_planned>, --comment <text>
25
25
  flags{comment}:
26
- --body <text> (required)
26
+ --body <text> or --body-file <path> (required)
27
27
  flags{transfer}:
28
28
  --to-repo <owner/name> (required)
29
29
  subissue:
@@ -32,6 +32,7 @@ examples:
32
32
  gh-axi issue list --state closed --label bug
33
33
  gh-axi issue view 42 --comments
34
34
  gh-axi issue create --title "Fix login" --body "Steps to reproduce..."
35
+ gh-axi issue comment 42 --body-file comment.md
35
36
  gh-axi issue close 42 --reason completed
36
37
  gh-axi issue transfer 42 -R source/repo --to-repo dest/repo
37
38
  gh-axi issue subissue add 16 20 101 125
@@ -334,7 +335,7 @@ async function createIssue(args, ctx) {
334
335
  const title = getFlag(args, "--title");
335
336
  if (!title)
336
337
  throw new AxiError("--title is required", "VALIDATION_ERROR");
337
- const body = getFlag(args, "--body");
338
+ const body = takeBody(args);
338
339
  const assignee = getFlag(args, "--assignee");
339
340
  const label = getFlag(args, "--label");
340
341
  const milestone = getFlag(args, "--milestone");
@@ -346,7 +347,7 @@ async function createIssue(args, ctx) {
346
347
  resolvedType = await resolveIssueType(typeName, ctx);
347
348
  }
348
349
  const ghArgs = ["issue", "create", "--title", title];
349
- if (body)
350
+ if (body !== undefined)
350
351
  ghArgs.push("--body", body);
351
352
  if (assignee)
352
353
  ghArgs.push("--assignee", assignee);
@@ -388,7 +389,7 @@ async function createIssue(args, ctx) {
388
389
  async function editIssue(args, ctx) {
389
390
  const num = requireNumber(getPositional(args, 1), "issue");
390
391
  const title = getFlag(args, "--title");
391
- const body = getFlag(args, "--body");
392
+ const body = takeBody(args);
392
393
  const addLabel = getFlag(args, "--add-label");
393
394
  const removeLabel = getFlag(args, "--remove-label");
394
395
  const addAssignee = getFlag(args, "--add-assignee");
@@ -405,7 +406,7 @@ async function editIssue(args, ctx) {
405
406
  const ghArgs = ["issue", "edit", String(num)];
406
407
  if (title)
407
408
  ghArgs.push("--title", title);
408
- if (body)
409
+ if (body !== undefined)
409
410
  ghArgs.push("--body", body);
410
411
  if (addLabel)
411
412
  ghArgs.push("--add-label", addLabel);
@@ -525,9 +526,7 @@ async function reopenIssue(args, ctx) {
525
526
  }
526
527
  async function commentOnIssue(args, ctx) {
527
528
  const num = requireNumber(getPositional(args, 1), "issue");
528
- const body = getFlag(args, "--body");
529
- if (!body)
530
- throw new AxiError("--body is required", "VALIDATION_ERROR");
529
+ const body = takeBody(args, { required: true });
531
530
  await ghExec(["issue", "comment", String(num), "--body", body], ctx);
532
531
  // Fetch the latest comment
533
532
  const issue = await ghJson(["issue", "view", String(num), "--json", "comments"], ctx);