@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.
- package/AGENTS.md +4 -2
- package/CHANGELOG.md +22 -0
- package/README.md +3 -2
- package/analyse-app-logs/README.md +12 -0
- package/analyse-app-logs/SKILL.md +6 -1
- package/analyse-app-logs/agents/openai.yaml +1 -1
- package/analyse-app-logs/scripts/filter_logs_by_time.py +64 -0
- package/analyse-app-logs/scripts/log_cli_utils.py +112 -0
- package/analyse-app-logs/scripts/search_logs.py +137 -0
- package/analyse-app-logs/tests/test_filter_logs_by_time.py +95 -0
- package/analyse-app-logs/tests/test_search_logs.py +100 -0
- package/commit-and-push/SKILL.md +20 -10
- package/maintain-skill-catalog/SKILL.md +3 -1
- package/open-github-issue/README.md +48 -6
- package/open-github-issue/SKILL.md +80 -5
- package/open-github-issue/agents/openai.yaml +2 -2
- package/open-github-issue/scripts/open_github_issue.py +174 -1
- package/open-github-issue/tests/test_open_github_issue.py +79 -0
- package/package.json +1 -1
- package/production-sim-debug/LICENSE +21 -0
- package/production-sim-debug/README.md +91 -0
- package/production-sim-debug/SKILL.md +131 -0
- package/production-sim-debug/agents/openai.yaml +4 -0
- package/read-github-issue/SKILL.md +99 -0
- package/read-github-issue/agents/openai.yaml +4 -0
- package/{fix-github-issues/scripts/list_issues.py → read-github-issue/scripts/find_issues.py} +1 -1
- package/read-github-issue/scripts/read_issue.py +108 -0
- package/{fix-github-issues/tests/test_list_issues.py → read-github-issue/tests/test_find_issues.py} +3 -3
- package/read-github-issue/tests/test_read_issue.py +109 -0
- package/ship-github-issue-fix/SKILL.md +65 -0
- package/ship-github-issue-fix/agents/openai.yaml +4 -0
- package/version-release/SKILL.md +4 -1
- package/fix-github-issues/SKILL.md +0 -105
- 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
|
@@ -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."
|
package/{fix-github-issues/scripts/list_issues.py → read-github-issue/scripts/find_issues.py}
RENAMED
|
@@ -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="
|
|
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())
|
package/{fix-github-issues/tests/test_list_issues.py → read-github-issue/tests/test_find_issues.py}
RENAMED
|
@@ -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" / "
|
|
16
|
-
SPEC = importlib.util.spec_from_file_location("
|
|
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
|
|
21
|
+
class FindIssuesTests(unittest.TestCase):
|
|
22
22
|
def test_build_command_with_filters(self) -> None:
|
|
23
23
|
args = Namespace(
|
|
24
24
|
repo="owner/repo",
|