@laitszkin/apollo-toolkit 2.11.2 → 2.11.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 (34) hide show
  1. package/AGENTS.md +4 -2
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +3 -2
  4. package/analyse-app-logs/README.md +12 -0
  5. package/analyse-app-logs/SKILL.md +6 -1
  6. package/analyse-app-logs/agents/openai.yaml +1 -1
  7. package/analyse-app-logs/scripts/filter_logs_by_time.py +64 -0
  8. package/analyse-app-logs/scripts/log_cli_utils.py +112 -0
  9. package/analyse-app-logs/scripts/search_logs.py +137 -0
  10. package/analyse-app-logs/tests/test_filter_logs_by_time.py +95 -0
  11. package/analyse-app-logs/tests/test_search_logs.py +100 -0
  12. package/commit-and-push/SKILL.md +20 -10
  13. package/maintain-skill-catalog/SKILL.md +3 -1
  14. package/open-github-issue/README.md +48 -6
  15. package/open-github-issue/SKILL.md +80 -5
  16. package/open-github-issue/agents/openai.yaml +2 -2
  17. package/open-github-issue/scripts/open_github_issue.py +174 -1
  18. package/open-github-issue/tests/test_open_github_issue.py +79 -0
  19. package/package.json +1 -1
  20. package/production-sim-debug/LICENSE +21 -0
  21. package/production-sim-debug/README.md +91 -0
  22. package/production-sim-debug/SKILL.md +131 -0
  23. package/production-sim-debug/agents/openai.yaml +4 -0
  24. package/read-github-issue/SKILL.md +99 -0
  25. package/read-github-issue/agents/openai.yaml +4 -0
  26. package/{fix-github-issues/scripts/list_issues.py → read-github-issue/scripts/find_issues.py} +1 -1
  27. package/read-github-issue/scripts/read_issue.py +108 -0
  28. package/{fix-github-issues/tests/test_list_issues.py → read-github-issue/tests/test_find_issues.py} +3 -3
  29. package/read-github-issue/tests/test_read_issue.py +109 -0
  30. package/ship-github-issue-fix/SKILL.md +65 -0
  31. package/ship-github-issue-fix/agents/openai.yaml +4 -0
  32. package/version-release/SKILL.md +4 -1
  33. package/fix-github-issues/SKILL.md +0 -105
  34. package/fix-github-issues/agents/openai.yaml +0 -4
@@ -81,6 +81,11 @@ class OpenGitHubIssueTests(unittest.TestCase):
81
81
  proposal="Allow exporting incident timelines",
82
82
  reason="Support postmortem handoff",
83
83
  suggested_architecture="Add shared exporters and UI action",
84
+ impact=None,
85
+ evidence=None,
86
+ suggested_action=None,
87
+ severity=None,
88
+ affected_scope=None,
84
89
  )
85
90
 
86
91
  self.assertIn("### 功能提案", zh_body)
@@ -88,6 +93,28 @@ class OpenGitHubIssueTests(unittest.TestCase):
88
93
  self.assertIn("### Feature Proposal", en_body)
89
94
  self.assertIn("### Suggested Architecture", en_body)
90
95
 
96
+ def test_build_issue_body_supports_security_issue_sections(self) -> None:
97
+ en_body = MODULE.build_issue_body(
98
+ issue_type=MODULE.ISSUE_TYPE_SECURITY,
99
+ language="en",
100
+ title="[Security] Missing auth",
101
+ problem_description="Endpoint misses admin check",
102
+ suspected_cause=None,
103
+ reproduction=None,
104
+ proposal=None,
105
+ reason=None,
106
+ suggested_architecture=None,
107
+ impact="Sensitive export may leak",
108
+ evidence="Reproduced request and code path review",
109
+ suggested_action="Add authz and tests",
110
+ severity="high",
111
+ affected_scope="/admin/export",
112
+ )
113
+
114
+ self.assertIn("### Security Risk", en_body)
115
+ self.assertIn("### Severity", en_body)
116
+ self.assertIn("### Suggested Mitigation", en_body)
117
+
91
118
  def test_validate_issue_content_args_requires_feature_fields(self) -> None:
92
119
  with self.assertRaises(SystemExit):
93
120
  MODULE.validate_issue_content_args(
@@ -118,6 +145,43 @@ class OpenGitHubIssueTests(unittest.TestCase):
118
145
  suggested_architecture="shared module",
119
146
  problem_description=None,
120
147
  suspected_cause=None,
148
+ impact=None,
149
+ evidence=None,
150
+ suggested_action=None,
151
+ severity=None,
152
+ affected_scope=None,
153
+ )
154
+ )
155
+
156
+ def test_validate_issue_content_args_requires_security_fields(self) -> None:
157
+ with self.assertRaises(SystemExit):
158
+ MODULE.validate_issue_content_args(
159
+ Namespace(
160
+ issue_type=MODULE.ISSUE_TYPE_SECURITY,
161
+ problem_description="auth missing",
162
+ affected_scope="",
163
+ impact="sensitive export may leak",
164
+ evidence="reproduced",
165
+ suggested_action="add authz",
166
+ severity="high",
167
+ reason=None,
168
+ suggested_architecture=None,
169
+ suspected_cause=None,
170
+ )
171
+ )
172
+
173
+ MODULE.validate_issue_content_args(
174
+ Namespace(
175
+ issue_type=MODULE.ISSUE_TYPE_SECURITY,
176
+ problem_description="auth missing",
177
+ affected_scope="/admin/export",
178
+ impact="sensitive export may leak",
179
+ evidence="reproduced",
180
+ suggested_action="add authz",
181
+ severity="high",
182
+ reason=None,
183
+ suggested_architecture=None,
184
+ suspected_cause=None,
121
185
  )
122
186
  )
123
187
 
@@ -130,6 +194,11 @@ class OpenGitHubIssueTests(unittest.TestCase):
130
194
  suggested_architecture=None,
131
195
  problem_description="Repeated timeout warnings escalated into request failures.",
132
196
  suspected_cause="handler.py:12",
197
+ impact=None,
198
+ evidence=None,
199
+ suggested_action=None,
200
+ severity=None,
201
+ affected_scope=None,
133
202
  )
134
203
  )
135
204
 
@@ -153,6 +222,11 @@ class OpenGitHubIssueTests(unittest.TestCase):
153
222
  "- Difference/Impact: users still receive errors.\n"
154
223
  ),
155
224
  suspected_cause="handler.py:12",
225
+ impact=None,
226
+ evidence=None,
227
+ suggested_action=None,
228
+ severity=None,
229
+ affected_scope=None,
156
230
  )
157
231
  )
158
232
 
@@ -181,6 +255,11 @@ class OpenGitHubIssueTests(unittest.TestCase):
181
255
  suggested_architecture=None,
182
256
  repo="owner/repo",
183
257
  dry_run=True,
258
+ impact=None,
259
+ evidence=None,
260
+ suggested_action=None,
261
+ severity=None,
262
+ affected_scope=None,
184
263
  )
185
264
 
186
265
  with patch.object(MODULE, "parse_args", return_value=args), patch.object(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laitszkin/apollo-toolkit",
3
- "version": "2.11.2",
3
+ "version": "2.11.4",
4
4
  "description": "Apollo Toolkit npm installer for managed skill copying across Codex, OpenClaw, and Trae.",
5
5
  "license": "MIT",
6
6
  "author": "LaiTszKin",
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LaiTszKin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,91 @@
1
+ # Production Sim Debug
2
+
3
+ An agent skill for investigating production or local simulation runs when the observed behavior diverges from the intended market scenario or expected liquidation/remediation outcomes.
4
+
5
+ This skill helps agents reproduce a bounded simulation run, inspect the real preset and runtime artifacts, separate product bugs from local harness drift, and apply the smallest realistic fix before rerunning the same scenario.
6
+
7
+ ## What this skill provides
8
+
9
+ - A workflow for bounded production/local simulation diagnosis.
10
+ - A decision tree for separating runtime logic bugs from harness, stub, preset, and persistence issues.
11
+ - A repeatable way to audit the active run directory, logs, and event database before drawing conclusions.
12
+ - Guidance for turning recurring ad hoc scenarios into named presets and documented test cases.
13
+ - Emphasis on rerunning the same scenario after a fix instead of relying only on unit tests.
14
+
15
+ ## Repository structure
16
+
17
+ - `SKILL.md`: Main skill definition, workflow, and output contract.
18
+ - `agents/openai.yaml`: Agent interface metadata and default prompt.
19
+
20
+ ## Installation
21
+
22
+ 1. Clone this repository.
23
+ 2. Copy this folder to your Codex skills directory:
24
+
25
+ ```bash
26
+ mkdir -p "$CODEX_HOME/skills"
27
+ cp -R production-sim-debug "$CODEX_HOME/skills/production-sim-debug"
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ Invoke the skill in your prompt:
33
+
34
+ ```text
35
+ Use $production-sim-debug to run this repository's production local simulation with the named preset for 5 minutes, explain why remediations or liquidations did not land, and fix any harness or runtime-alignment issues you confirm.
36
+ ```
37
+
38
+ Best results come from including:
39
+
40
+ - workspace path
41
+ - canonical simulation entrypoint
42
+ - preset or scenario name
43
+ - run duration
44
+ - expected market shape or success criteria
45
+ - the run directory to inspect, if it already exists
46
+ - whether toolchain fixes are in scope or the task is read-only
47
+
48
+ If the repository already has a named preset system, prefer using it instead of describing the scenario only in prose.
49
+
50
+ ## Example
51
+
52
+ ### Input prompt
53
+
54
+ ```text
55
+ Use $production-sim-debug for this repository.
56
+
57
+ Workspace: /workspace/pangu
58
+ Entrypoint: ./scripts/run-production-local-sim.sh stress-test-1
59
+ Duration: 5 minutes
60
+ Expectations:
61
+ - Jupiter free tier
62
+ - mostly oracle-blocked positions that can be unlocked by remediation
63
+ - some directly executable opportunities
64
+ - evidence-backed explanation for why liquidations did or did not land
65
+ ```
66
+
67
+ ### Expected response shape
68
+
69
+ ```text
70
+ 1) Scenario contract
71
+ - Named preset, duration, and run directory used.
72
+
73
+ 2) Observed outcomes
74
+ - Event-table counts, dominant skip reasons, and runtime stage reached.
75
+
76
+ 3) Root cause
77
+ - Whether the main blocker was product logic, quote budget, preset design, or harness/stub drift.
78
+
79
+ 4) Fixes applied
80
+ - Toolchain or runtime fixes with file paths.
81
+
82
+ 5) Validation
83
+ - Rerun or targeted tests proving the intended stage now executes.
84
+
85
+ 6) Remaining gaps
86
+ - Any realism differences still left between local simulation and chain behavior.
87
+ ```
88
+
89
+ ## License
90
+
91
+ MIT. See `LICENSE`.
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: production-sim-debug
3
+ description: Investigate production or local simulation runs for runtime-toolchain drift, harness bugs, preset mistakes, unrealistic local stubs, or mismatches between expected and observed liquidation outcomes. Use when users ask to run bounded production simulations, explain why simulated liquidations or remediations did not happen, calibrate presets, or fix local simulation tooling so it better matches real on-chain behavior.
4
+ ---
5
+
6
+ # Production Sim Debug
7
+
8
+ ## Dependencies
9
+
10
+ - Required: `systematic-debug` for evidence-first root-cause analysis when a simulation shows failing or missing expected behavior.
11
+ - Conditional: `scheduled-runtime-health-check` when the user wants a bounded production/local simulation run executed and observed; `read-github-issue` when the requested simulation work is driven by a remote issue; `open-github-issue` when confirmed toolchain gaps should be published.
12
+ - Optional: none.
13
+ - Fallback: If the relevant simulation entrypoint, preset, logs, or run artifacts cannot be found, stop and report the missing evidence instead of inferring behavior from stale docs or memory.
14
+
15
+ ## Standards
16
+
17
+ - Evidence: Base conclusions on the actual preset, runtime command, logs, SQLite event store, local stub responses, and the code paths that generated them.
18
+ - Execution: Reproduce with the exact scenario first, separate product logic failures from simulation-toolchain failures, make the smallest realistic toolchain fix, and rerun the same bounded scenario to validate.
19
+ - Quality: Prefer harness or stub fixes that improve realism over one-off scenario hacks, avoid duplicating existing workflow skills, and record reusable presets when a scenario becomes part of the regular test suite.
20
+ - Output: Return the scenario contract, observed outcomes, root-cause chain, fixes applied, validation evidence, and any remaining realism gaps.
21
+
22
+ ## Goal
23
+
24
+ Use this skill to debug simulation workflows where the repository exposes a production-like local run path, but the observed outcomes are distorted by presets, harness logic, local stubs, event persistence, or runtime scheduling constraints.
25
+
26
+ ## Workflow
27
+
28
+ ### 1) Lock the simulation contract before touching code
29
+
30
+ - Identify the exact entrypoint, preset, duration, runtime mode, and rate-limit tier the user expects.
31
+ - Read the preset or scenario definition from the repository before assuming what the test means.
32
+ - Capture the intended success criteria explicitly, such as:
33
+ - successful liquidation count
34
+ - remediation count
35
+ - oracle-block registration
36
+ - profit ranking behavior
37
+ - quote budget behavior
38
+ - If the scenario is ad hoc but likely to recur, prefer turning it into a named preset instead of leaving it as an undocumented shell invocation.
39
+
40
+ ### 2) Reproduce with the real bounded run path
41
+
42
+ - Use the same production/local simulation script the repository already treats as canonical.
43
+ - Prefer a bounded run window with a stable run name and output directory.
44
+ - Save and inspect the exact artifacts produced by that run:
45
+ - main runtime log
46
+ - actor or stub logs
47
+ - generated env/config files
48
+ - SQLite or other persistence outputs
49
+ - scenario manifest or preset-resolved settings
50
+ - Do not trust older run directories when the user asks about a new execution.
51
+
52
+ ### 3) Audit the artifact chain before diagnosing product logic
53
+
54
+ - Confirm that you are reading the correct database and log files for the active run.
55
+ - Verify that the event tables you expect are actually the ones written by the runtime.
56
+ - Check whether missing results come from:
57
+ - no candidate selection
58
+ - no worker completion
59
+ - planner failure
60
+ - event persistence mismatch
61
+ - reading the wrong file
62
+ - Treat this artifact audit as mandatory; repeated failures in the recent chats came from toolchain alignment errors before they came from liquidation logic.
63
+
64
+ ### 4) Separate product failures from toolchain realism failures
65
+
66
+ - Classify each blocker into one of these buckets:
67
+ - preset design mismatch
68
+ - runtime scheduling or budget behavior
69
+ - stub or mock response unrealism
70
+ - local validator or cloned-state setup drift
71
+ - account ordering / remaining-account mismatch
72
+ - event-generation or persistence bug
73
+ - genuine product logic bug
74
+ - If the symptom is caused by the local harness, fix the harness instead of masking it in runtime logic.
75
+ - If a local stub inflates or distorts profitability, preserve the runtime behavior and calibrate the stub.
76
+ - If a scenario intentionally stresses one dimension, make sure the harness is not accidentally stressing unrelated dimensions.
77
+
78
+ ### 5) Trace the full decision tree for missed liquidations or remediations
79
+
80
+ - Follow the candidate from discovery through:
81
+ - local profitability estimate
82
+ - health precheck
83
+ - oracle-block classification
84
+ - remediation registration and rearm
85
+ - quote admission
86
+ - quote calibration
87
+ - pre-submit verification
88
+ - final execution or skip reason
89
+ - When the runtime reports a generic or overloaded failure label, reopen the logs and derive a finer-grained breakdown before proposing fixes.
90
+ - Distinguish fail-closed behavior from broken behavior; not all skipped liquidations are bugs.
91
+
92
+ ### 6) Fix the narrowest realistic cause
93
+
94
+ - Prefer minimal fixes that improve realism or observability at the root cause:
95
+ - add preset support to shell tooling instead of hardcoding another branch
96
+ - make oracle-blocked paths avoid external quote I/O when a local estimate is sufficient
97
+ - make stubs preserve run-specific metadata instead of falling back to unrealistic defaults
98
+ - keep continuous oracle updates realistic without breaking the runtime's own core feeds
99
+ - Add or update regression tests when the bug is in the harness, runtime decision tree, or event persistence path.
100
+ - If the scenario becomes a durable benchmark, add or update the named preset and the developer docs in the same change.
101
+
102
+ ### 7) Re-run the same scenario and compare outcomes
103
+
104
+ - After the fix, rerun the same scenario or the shortest bounded version that still exercises the bug.
105
+ - Compare:
106
+ - event-table counts before and after
107
+ - dominant skip reasons before and after
108
+ - whether the runtime reaches the intended decision stage
109
+ - whether the harness still resembles the user’s requested market conditions
110
+ - Do not claim success based only on unit tests when the original issue was a simulation-toolchain integration problem.
111
+
112
+ ## Common failure patterns
113
+
114
+ - **Wrong artifact source**: the analyst inspects an older SQLite file or the wrong event database and concludes that runtime behavior is missing.
115
+ - **Preset says one thing, harness does another**: scenario names sound right, but the actual matrix or oracle mode does not match the user’s intent.
116
+ - **Stub realism drift**: local quote, swap, or oracle stubs distort pricing, accounts, or program IDs enough to create false failures or false profits.
117
+ - **Overloaded “unknown” failures**: logs contain structured reasons, but the first-pass analysis never decomposes them.
118
+ - **Continuous-mode self-sabotage**: a stress regime intended to stale pull oracles instead makes the runtime’s own primary feeds unusable.
119
+ - **Quote budget starvation**: local filtering improves behavior but still lets low-value cross-mint candidates consume scarce quote capacity before higher-value paths can finish.
120
+
121
+ ## Output checklist
122
+
123
+ - Name the exact scenario, preset, duration, and run directory.
124
+ - State whether the root cause was product logic, toolchain realism, or both.
125
+ - Cite the artifact types used: preset, logs, SQLite tables, and code paths.
126
+ - Summarize the narrow fix and the regression test or rerun evidence.
127
+ - If the final scenario should be reused, state where the preset or docs were added.
128
+
129
+ ## Example invocation
130
+
131
+ `Use $production-sim-debug to run the repository's production local simulation for 5 minutes with the named preset, explain why liquidations did not land, and fix any local harness or runtime-alignment issues that make the simulation unrealistic.`
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Production Sim Debug"
3
+ short_description: "診斷 production/local simulation 工具鏈與結果失真"
4
+ default_prompt: "Use $production-sim-debug to investigate a production/local simulation run, explain why outcomes diverged, and fix the harness or runtime alignment if needed."
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: read-github-issue
3
+ description: Read and search remote GitHub issues via GitHub CLI (`gh`). Use when users ask to list issues, filter issue candidates, inspect a specific issue with comments, or gather issue context before planning follow-up work. Prefer the bundled scripts when they are present and working, but fall back to direct `gh issue list` / `gh issue view` commands when the scripts are missing or fail for repository-specific reasons.
4
+ ---
5
+
6
+ # Read GitHub Issue
7
+
8
+ ## Dependencies
9
+
10
+ - Required: none.
11
+ - Conditional: none.
12
+ - Optional: none.
13
+ - Fallback: If the bundled scripts are missing or fail but `gh` is available, continue with raw `gh issue list` / `gh issue view`; only stop when `gh` itself is unavailable or unauthenticated.
14
+
15
+ ## Standards
16
+
17
+ - Evidence: Verify repository context first, then read remote issue data directly from `gh issue list` / `gh issue view` instead of paraphrasing from memory.
18
+ - Execution: Confirm the target repo, prefer the bundled scripts for deterministic output, then fall back to raw `gh` commands whenever the scripts are unavailable or broken in the target repository.
19
+ - Quality: Keep the skill focused on issue discovery and retrieval only; do not embed any hardcoded fixing, branching, PR, or push workflow.
20
+ - Output: Return candidate issues, selected issue details, comments summary, and any missing information needed before follow-up work.
21
+
22
+ ## Overview
23
+
24
+ Use this skill to gather trustworthy GitHub issue context with `gh`: discover open or closed issues, narrow them with labels or search text, then inspect a chosen issue in detail before any separate planning or implementation workflow begins.
25
+
26
+ ## Prerequisites
27
+
28
+ - `gh` is installed and authenticated (`gh auth status`).
29
+ - The current directory is a git repository with the correct `origin`, or the user provides `--repo owner/name`.
30
+
31
+ ## Workflow
32
+
33
+ ### 1) Verify repository and remote context
34
+
35
+ - Run `gh repo view --json nameWithOwner,isPrivate,defaultBranchRef` to confirm target repo.
36
+ - If the user specifies another repository, always use `--repo <owner>/<repo>` in issue commands.
37
+
38
+ ### 2) Find candidate issues with the bundled script
39
+
40
+ - Preferred command:
41
+
42
+ ```bash
43
+ python3 scripts/find_issues.py --limit 50 --state open
44
+ ```
45
+
46
+ - Optional filters:
47
+ - `--repo owner/name`
48
+ - `--label bug`
49
+ - `--search "panic in parser"`
50
+ - Raw `gh` fallback when the script is missing or broken:
51
+
52
+ ```bash
53
+ gh issue list --limit 50 --state open
54
+ ```
55
+
56
+ - Add `--repo <owner>/<repo>`, `--label <label>`, or `--search "<text>"` as needed.
57
+ - If the issue target is still unclear, present top candidates and ask which issue number or URL should be inspected next.
58
+
59
+ ### 3) Read a specific issue in detail
60
+
61
+ - Preferred command:
62
+
63
+ ```bash
64
+ python3 scripts/read_issue.py 123 --comments
65
+ ```
66
+
67
+ - Optional flags:
68
+ - `--repo owner/name`
69
+ - `--json`
70
+ - `--comments`
71
+ - Raw `gh` fallback when the script is missing or broken:
72
+
73
+ ```bash
74
+ gh issue view 123 --comments
75
+ ```
76
+
77
+ - Use `--repo <owner>/<repo>` when targeting a different repository.
78
+ - Use the returned title, body, labels, assignees, state, timestamps, and comments to summarize the issue precisely.
79
+
80
+ ### 4) Summarize gaps before any follow-up action
81
+
82
+ - Identify missing acceptance criteria, repro details, affected components, or environment context.
83
+ - If issue text and comments are insufficient, state exactly what is missing instead of inventing a fix plan.
84
+
85
+ ## Included Script
86
+
87
+ ### `scripts/find_issues.py`
88
+
89
+ - Purpose: consistent remote issue listing via `gh issue list`.
90
+ - Outputs a readable table by default, or JSON with `--output json`.
91
+ - Uses only GitHub CLI so it reflects remote GitHub state.
92
+ - Treat it as a convenience wrapper, not a hard dependency.
93
+
94
+ ### `scripts/read_issue.py`
95
+
96
+ - Purpose: deterministic issue detail retrieval via `gh issue view`.
97
+ - Outputs either a human-readable summary or full JSON for downstream automation.
98
+ - Can include issue comments so the agent can read the latest discussion before taking any other step.
99
+ - Treat it as a convenience wrapper, not a hard dependency.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Read GitHub Issue"
3
+ short_description: "Read and search remote GitHub issues"
4
+ default_prompt: "Use $read-github-issue to verify the target GitHub repository with gh, prefer the bundled issue scripts when they work, fall back to raw gh issue commands when they do not, inspect the selected issue with comments and structured fields, summarize the trustworthy issue context, and call out any missing details before any separate planning or implementation work."
@@ -17,7 +17,7 @@ def positive_int(raw: str) -> int:
17
17
 
18
18
  def parse_args() -> argparse.Namespace:
19
19
  parser = argparse.ArgumentParser(
20
- description="List remote GitHub issues with gh CLI and display table or JSON output."
20
+ description="Find remote GitHub issues with gh CLI and display table or JSON output."
21
21
  )
22
22
  parser.add_argument("--repo", help="Target repository in owner/name format.")
23
23
  parser.add_argument("--state", default="open", choices=["open", "closed", "all"])
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import subprocess
7
+ import sys
8
+
9
+
10
+ ISSUE_FIELDS = "number,title,body,state,author,labels,assignees,comments,createdAt,updatedAt,closedAt,url"
11
+
12
+
13
+ def parse_args() -> argparse.Namespace:
14
+ parser = argparse.ArgumentParser(
15
+ description="Read a remote GitHub issue with gh CLI and display summary or JSON output."
16
+ )
17
+ parser.add_argument("issue", help="Issue number or URL.")
18
+ parser.add_argument("--repo", help="Target repository in owner/name format.")
19
+ parser.add_argument(
20
+ "--comments",
21
+ action="store_true",
22
+ help="Keep issue comments in formatted output.",
23
+ )
24
+ parser.add_argument(
25
+ "--json",
26
+ action="store_true",
27
+ help="Print raw JSON output.",
28
+ )
29
+ return parser.parse_args()
30
+
31
+
32
+ def build_command(args: argparse.Namespace) -> list[str]:
33
+ cmd = [
34
+ "gh",
35
+ "issue",
36
+ "view",
37
+ args.issue,
38
+ "--json",
39
+ ISSUE_FIELDS,
40
+ ]
41
+ if args.repo:
42
+ cmd.extend(["--repo", args.repo])
43
+ return cmd
44
+
45
+
46
+ def join_names(items: list[dict], key: str) -> str:
47
+ values = [item.get(key, "") for item in items if item.get(key)]
48
+ return ", ".join(values) if values else "-"
49
+
50
+
51
+ def print_summary(issue: dict, include_comments: bool) -> None:
52
+ print(f"Number: #{issue.get('number', '')}")
53
+ print(f"Title: {issue.get('title', '')}")
54
+ print(f"State: {issue.get('state', '')}")
55
+ print(f"URL: {issue.get('url', '')}")
56
+ print(f"Author: {(issue.get('author') or {}).get('login', '-')}")
57
+ print(f"Labels: {join_names(issue.get('labels', []), 'name')}")
58
+ print(f"Assignees: {join_names(issue.get('assignees', []), 'login')}")
59
+ print(f"Created: {issue.get('createdAt', '')}")
60
+ print(f"Updated: {issue.get('updatedAt', '')}")
61
+ print(f"Closed: {issue.get('closedAt', '') or '-'}")
62
+ print("")
63
+ print("Body:")
64
+ print(issue.get("body", "") or "-")
65
+
66
+ if include_comments:
67
+ comments = issue.get("comments", [])
68
+ print("")
69
+ print(f"Comments ({len(comments)}):")
70
+ if not comments:
71
+ print("-")
72
+ return
73
+ for comment in comments:
74
+ author = (comment.get("author") or {}).get("login", "-")
75
+ created = comment.get("createdAt", "")
76
+ body = comment.get("body", "") or "-"
77
+ print(f"- [{created}] {author}: {body}")
78
+
79
+
80
+ def main() -> int:
81
+ args = parse_args()
82
+ cmd = build_command(args)
83
+
84
+ try:
85
+ result = subprocess.run(cmd, check=True, capture_output=True, text=True)
86
+ except FileNotFoundError:
87
+ print("Error: gh CLI is not installed or not in PATH.", file=sys.stderr)
88
+ return 1
89
+ except subprocess.CalledProcessError as exc:
90
+ print(exc.stderr.strip() or "gh issue view failed.", file=sys.stderr)
91
+ return exc.returncode
92
+
93
+ try:
94
+ issue = json.loads(result.stdout)
95
+ except json.JSONDecodeError:
96
+ print("Error: unable to parse gh output as JSON.", file=sys.stderr)
97
+ return 1
98
+
99
+ if args.json:
100
+ print(json.dumps(issue, indent=2))
101
+ return 0
102
+
103
+ print_summary(issue, include_comments=args.comments)
104
+ return 0
105
+
106
+
107
+ if __name__ == "__main__":
108
+ sys.exit(main())
@@ -12,13 +12,13 @@ from pathlib import Path
12
12
  from unittest.mock import patch
13
13
 
14
14
 
15
- SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "list_issues.py"
16
- SPEC = importlib.util.spec_from_file_location("list_issues", SCRIPT_PATH)
15
+ SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "find_issues.py"
16
+ SPEC = importlib.util.spec_from_file_location("find_issues", SCRIPT_PATH)
17
17
  MODULE = importlib.util.module_from_spec(SPEC)
18
18
  SPEC.loader.exec_module(MODULE)
19
19
 
20
20
 
21
- class ListIssuesTests(unittest.TestCase):
21
+ class FindIssuesTests(unittest.TestCase):
22
22
  def test_build_command_with_filters(self) -> None:
23
23
  args = Namespace(
24
24
  repo="owner/repo",