mitsupi 1.0.0

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 (77) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +95 -0
  3. package/TODO.md +11 -0
  4. package/commands/handoff.md +100 -0
  5. package/commands/make-release.md +75 -0
  6. package/commands/pickup.md +30 -0
  7. package/commands/update-changelog.md +78 -0
  8. package/package.json +22 -0
  9. package/pi-extensions/answer.ts +527 -0
  10. package/pi-extensions/codex-tuning.ts +632 -0
  11. package/pi-extensions/commit.ts +248 -0
  12. package/pi-extensions/cwd-history.ts +237 -0
  13. package/pi-extensions/issues.ts +548 -0
  14. package/pi-extensions/loop.ts +446 -0
  15. package/pi-extensions/qna.ts +167 -0
  16. package/pi-extensions/reveal.ts +689 -0
  17. package/pi-extensions/review.ts +807 -0
  18. package/pi-themes/armin.json +81 -0
  19. package/pi-themes/nightowl.json +82 -0
  20. package/skills/anachb/SKILL.md +183 -0
  21. package/skills/anachb/departures.sh +79 -0
  22. package/skills/anachb/disruptions.sh +53 -0
  23. package/skills/anachb/route.sh +87 -0
  24. package/skills/anachb/search.sh +43 -0
  25. package/skills/ghidra/SKILL.md +254 -0
  26. package/skills/ghidra/scripts/find-ghidra.sh +54 -0
  27. package/skills/ghidra/scripts/ghidra-analyze.sh +239 -0
  28. package/skills/ghidra/scripts/ghidra_scripts/ExportAll.java +278 -0
  29. package/skills/ghidra/scripts/ghidra_scripts/ExportCalls.java +148 -0
  30. package/skills/ghidra/scripts/ghidra_scripts/ExportDecompiled.java +84 -0
  31. package/skills/ghidra/scripts/ghidra_scripts/ExportFunctions.java +114 -0
  32. package/skills/ghidra/scripts/ghidra_scripts/ExportStrings.java +123 -0
  33. package/skills/ghidra/scripts/ghidra_scripts/ExportSymbols.java +135 -0
  34. package/skills/github/SKILL.md +47 -0
  35. package/skills/improve-skill/SKILL.md +155 -0
  36. package/skills/improve-skill/scripts/extract-session.js +349 -0
  37. package/skills/oebb-scotty/SKILL.md +429 -0
  38. package/skills/oebb-scotty/arrivals.sh +83 -0
  39. package/skills/oebb-scotty/departures.sh +83 -0
  40. package/skills/oebb-scotty/disruptions.sh +33 -0
  41. package/skills/oebb-scotty/search-station.sh +36 -0
  42. package/skills/oebb-scotty/trip.sh +119 -0
  43. package/skills/openscad/SKILL.md +232 -0
  44. package/skills/openscad/examples/parametric_box.scad +92 -0
  45. package/skills/openscad/examples/phone_stand.scad +95 -0
  46. package/skills/openscad/tools/common.sh +50 -0
  47. package/skills/openscad/tools/export-stl.sh +56 -0
  48. package/skills/openscad/tools/extract-params.sh +147 -0
  49. package/skills/openscad/tools/multi-preview.sh +68 -0
  50. package/skills/openscad/tools/preview.sh +74 -0
  51. package/skills/openscad/tools/render-with-params.sh +91 -0
  52. package/skills/openscad/tools/validate.sh +46 -0
  53. package/skills/pi-share/SKILL.md +105 -0
  54. package/skills/pi-share/fetch-session.mjs +322 -0
  55. package/skills/sentry/SKILL.md +239 -0
  56. package/skills/sentry/lib/auth.js +99 -0
  57. package/skills/sentry/scripts/fetch-event.js +329 -0
  58. package/skills/sentry/scripts/fetch-issue.js +356 -0
  59. package/skills/sentry/scripts/list-issues.js +239 -0
  60. package/skills/sentry/scripts/search-events.js +291 -0
  61. package/skills/sentry/scripts/search-logs.js +240 -0
  62. package/skills/tmux/SKILL.md +105 -0
  63. package/skills/tmux/scripts/find-sessions.sh +112 -0
  64. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  65. package/skills/web-browser/SKILL.md +91 -0
  66. package/skills/web-browser/scripts/cdp.js +210 -0
  67. package/skills/web-browser/scripts/dismiss-cookies.js +373 -0
  68. package/skills/web-browser/scripts/eval.js +68 -0
  69. package/skills/web-browser/scripts/logs-tail.js +69 -0
  70. package/skills/web-browser/scripts/nav.js +65 -0
  71. package/skills/web-browser/scripts/net-summary.js +94 -0
  72. package/skills/web-browser/scripts/package-lock.json +33 -0
  73. package/skills/web-browser/scripts/package.json +6 -0
  74. package/skills/web-browser/scripts/pick.js +165 -0
  75. package/skills/web-browser/scripts/screenshot.js +52 -0
  76. package/skills/web-browser/scripts/start.js +80 -0
  77. package/skills/web-browser/scripts/watch.js +266 -0
@@ -0,0 +1,123 @@
1
+ /* ###
2
+ * Export all strings found in the binary
3
+ * @category Export
4
+ */
5
+
6
+ import ghidra.app.script.GhidraScript;
7
+ import ghidra.program.model.data.DataType;
8
+ import ghidra.program.model.data.StringDataType;
9
+ import ghidra.program.model.listing.Data;
10
+ import ghidra.program.model.listing.DataIterator;
11
+ import ghidra.program.model.mem.Memory;
12
+ import ghidra.program.model.mem.MemoryBlock;
13
+ import ghidra.program.util.DefinedDataIterator;
14
+
15
+ import java.io.File;
16
+ import java.io.FileWriter;
17
+ import java.io.PrintWriter;
18
+
19
+ public class ExportStrings extends GhidraScript {
20
+
21
+ @Override
22
+ public void run() throws Exception {
23
+ String outputDir = System.getenv("GHIDRA_OUTPUT_DIR");
24
+ if (outputDir == null || outputDir.isEmpty()) {
25
+ outputDir = ".";
26
+ }
27
+
28
+ String programName = currentProgram.getName().replaceAll("[^a-zA-Z0-9._-]", "_");
29
+ File outputFile = new File(outputDir, programName + "_strings.json");
30
+
31
+ println("Exporting strings to: " + outputFile.getAbsolutePath());
32
+
33
+ try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
34
+ writer.println("{");
35
+ writer.println(" \"program\": \"" + escapeJson(currentProgram.getName()) + "\",");
36
+ writer.println(" \"strings\": [");
37
+
38
+ int count = 0;
39
+ boolean first = true;
40
+
41
+ // Iterate through all defined data looking for strings
42
+ DataIterator dataIterator = currentProgram.getListing().getDefinedData(true);
43
+
44
+ while (dataIterator.hasNext() && !monitor.isCancelled()) {
45
+ Data data = dataIterator.next();
46
+
47
+ if (isStringData(data)) {
48
+ String value = getStringValue(data);
49
+ if (value != null && !value.isEmpty() && value.length() >= 4) { // Skip very short strings
50
+ if (!first) {
51
+ writer.println(",");
52
+ }
53
+ first = false;
54
+
55
+ writer.println(" {");
56
+ writer.println(" \"address\": \"" + data.getAddress() + "\",");
57
+ writer.println(" \"type\": \"" + data.getDataType().getName() + "\",");
58
+ writer.println(" \"length\": " + value.length() + ",");
59
+ writer.println(" \"value\": \"" + escapeJson(truncate(value, 1000)) + "\"");
60
+ writer.print(" }");
61
+ count++;
62
+ }
63
+ }
64
+ }
65
+
66
+ writer.println();
67
+ writer.println(" ]");
68
+ writer.println("}");
69
+
70
+ println("Exported " + count + " strings");
71
+ }
72
+ }
73
+
74
+ private boolean isStringData(Data data) {
75
+ DataType dt = data.getBaseDataType();
76
+ String typeName = dt.getName().toLowerCase();
77
+ return typeName.contains("string") ||
78
+ typeName.equals("char") ||
79
+ typeName.contains("unicode");
80
+ }
81
+
82
+ private String getStringValue(Data data) {
83
+ Object value = data.getValue();
84
+ if (value instanceof String) {
85
+ return (String) value;
86
+ }
87
+ // Try to get the string representation
88
+ String repr = data.getDefaultValueRepresentation();
89
+ if (repr != null && repr.startsWith("\"") && repr.endsWith("\"")) {
90
+ return repr.substring(1, repr.length() - 1);
91
+ }
92
+ return repr;
93
+ }
94
+
95
+ private String truncate(String s, int maxLen) {
96
+ if (s == null) return "";
97
+ if (s.length() <= maxLen) return s;
98
+ return s.substring(0, maxLen) + "...";
99
+ }
100
+
101
+ private String escapeJson(String s) {
102
+ if (s == null) return "";
103
+ StringBuilder sb = new StringBuilder();
104
+ for (char c : s.toCharArray()) {
105
+ switch (c) {
106
+ case '\\': sb.append("\\\\"); break;
107
+ case '"': sb.append("\\\""); break;
108
+ case '\n': sb.append("\\n"); break;
109
+ case '\r': sb.append("\\r"); break;
110
+ case '\t': sb.append("\\t"); break;
111
+ case '\b': sb.append("\\b"); break;
112
+ case '\f': sb.append("\\f"); break;
113
+ default:
114
+ if (c < 32 || c > 126) {
115
+ sb.append(String.format("\\u%04x", (int) c));
116
+ } else {
117
+ sb.append(c);
118
+ }
119
+ }
120
+ }
121
+ return sb.toString();
122
+ }
123
+ }
@@ -0,0 +1,135 @@
1
+ /* ###
2
+ * Export all symbols and their addresses
3
+ * @category Export
4
+ */
5
+
6
+ import ghidra.app.script.GhidraScript;
7
+ import ghidra.program.model.symbol.*;
8
+ import ghidra.program.model.listing.*;
9
+
10
+ import java.io.File;
11
+ import java.io.FileWriter;
12
+ import java.io.PrintWriter;
13
+
14
+ public class ExportSymbols extends GhidraScript {
15
+
16
+ @Override
17
+ public void run() throws Exception {
18
+ String outputDir = System.getenv("GHIDRA_OUTPUT_DIR");
19
+ if (outputDir == null || outputDir.isEmpty()) {
20
+ outputDir = ".";
21
+ }
22
+
23
+ String programName = currentProgram.getName().replaceAll("[^a-zA-Z0-9._-]", "_");
24
+ File outputFile = new File(outputDir, programName + "_symbols.json");
25
+
26
+ println("Exporting symbols to: " + outputFile.getAbsolutePath());
27
+
28
+ SymbolTable symbolTable = currentProgram.getSymbolTable();
29
+
30
+ try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
31
+ writer.println("{");
32
+ writer.println(" \"program\": \"" + escapeJson(currentProgram.getName()) + "\",");
33
+
34
+ // Export imports (external functions)
35
+ writer.println(" \"imports\": [");
36
+ boolean first = true;
37
+ int importCount = 0;
38
+ SymbolIterator externalSymbols = symbolTable.getExternalSymbols();
39
+ while (externalSymbols.hasNext() && !monitor.isCancelled()) {
40
+ Symbol sym = externalSymbols.next();
41
+ if (!first) writer.println(",");
42
+ first = false;
43
+ writer.println(" {");
44
+ writer.println(" \"name\": \"" + escapeJson(sym.getName()) + "\",");
45
+ writer.println(" \"address\": \"" + sym.getAddress() + "\",");
46
+ writer.println(" \"namespace\": \"" + escapeJson(sym.getParentNamespace().getName()) + "\",");
47
+ writer.println(" \"type\": \"" + sym.getSymbolType() + "\"");
48
+ writer.print(" }");
49
+ importCount++;
50
+ }
51
+ writer.println();
52
+ writer.println(" ],");
53
+
54
+ // Export exports (if any)
55
+ writer.println(" \"exports\": [");
56
+ first = true;
57
+ int exportCount = 0;
58
+ // Functions that are potential exports (entry points or exported)
59
+ FunctionIterator functions = currentProgram.getFunctionManager().getExternalFunctions();
60
+ // Look for functions marked as entry points
61
+ FunctionIterator allFunctions = currentProgram.getFunctionManager().getFunctions(true);
62
+ while (allFunctions.hasNext() && !monitor.isCancelled()) {
63
+ Function func = allFunctions.next();
64
+ // Check if function is at an entry point or has export symbol
65
+ Symbol sym = func.getSymbol();
66
+ if (sym.isExternalEntryPoint() || sym.getSource() == SourceType.IMPORTED) {
67
+ if (!first) writer.println(",");
68
+ first = false;
69
+ writer.println(" {");
70
+ writer.println(" \"name\": \"" + escapeJson(func.getName()) + "\",");
71
+ writer.println(" \"address\": \"" + func.getEntryPoint() + "\",");
72
+ writer.println(" \"signature\": \"" + escapeJson(func.getPrototypeString(false, false)) + "\"");
73
+ writer.print(" }");
74
+ exportCount++;
75
+ }
76
+ }
77
+ writer.println();
78
+ writer.println(" ],");
79
+
80
+ // Export all labels/symbols
81
+ writer.println(" \"symbols\": [");
82
+ first = true;
83
+ int symbolCount = 0;
84
+ SymbolIterator allSymbols = symbolTable.getAllSymbols(true);
85
+ while (allSymbols.hasNext() && !monitor.isCancelled()) {
86
+ Symbol sym = allSymbols.next();
87
+ // Skip default/dynamic symbols to reduce noise
88
+ if (sym.getSource() == SourceType.DEFAULT) {
89
+ continue;
90
+ }
91
+
92
+ if (!first) writer.println(",");
93
+ first = false;
94
+ writer.println(" {");
95
+ writer.println(" \"name\": \"" + escapeJson(sym.getName()) + "\",");
96
+ writer.println(" \"address\": \"" + sym.getAddress() + "\",");
97
+ writer.println(" \"type\": \"" + sym.getSymbolType() + "\",");
98
+ writer.println(" \"source\": \"" + sym.getSource() + "\",");
99
+ writer.println(" \"namespace\": \"" + escapeJson(sym.getParentNamespace().getName()) + "\",");
100
+ writer.println(" \"primary\": " + sym.isPrimary());
101
+ writer.print(" }");
102
+ symbolCount++;
103
+
104
+ // Limit to prevent huge outputs
105
+ if (symbolCount >= 10000) {
106
+ writer.println(",");
107
+ writer.println(" {\"_truncated\": true, \"_message\": \"Output truncated at 10000 symbols\"}");
108
+ break;
109
+ }
110
+ }
111
+ writer.println();
112
+ writer.println(" ],");
113
+
114
+ // Summary
115
+ writer.println(" \"summary\": {");
116
+ writer.println(" \"imports\": " + importCount + ",");
117
+ writer.println(" \"exports\": " + exportCount + ",");
118
+ writer.println(" \"symbols\": " + symbolCount);
119
+ writer.println(" }");
120
+
121
+ writer.println("}");
122
+
123
+ println("Exported " + importCount + " imports, " + exportCount + " exports, " + symbolCount + " symbols");
124
+ }
125
+ }
126
+
127
+ private String escapeJson(String s) {
128
+ if (s == null) return "";
129
+ return s.replace("\\", "\\\\")
130
+ .replace("\"", "\\\"")
131
+ .replace("\n", "\\n")
132
+ .replace("\r", "\\r")
133
+ .replace("\t", "\\t");
134
+ }
135
+ }
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: github
3
+ description: "Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries."
4
+ ---
5
+
6
+ # GitHub Skill
7
+
8
+ Use the `gh` CLI to interact with GitHub. Always specify `--repo owner/repo` when not in a git directory, or use URLs directly.
9
+
10
+ ## Pull Requests
11
+
12
+ Check CI status on a PR:
13
+ ```bash
14
+ gh pr checks 55 --repo owner/repo
15
+ ```
16
+
17
+ List recent workflow runs:
18
+ ```bash
19
+ gh run list --repo owner/repo --limit 10
20
+ ```
21
+
22
+ View a run and see which steps failed:
23
+ ```bash
24
+ gh run view <run-id> --repo owner/repo
25
+ ```
26
+
27
+ View logs for failed steps only:
28
+ ```bash
29
+ gh run view <run-id> --repo owner/repo --log-failed
30
+ ```
31
+
32
+ ## API for Advanced Queries
33
+
34
+ The `gh api` command is useful for accessing data not available through other subcommands.
35
+
36
+ Get PR with specific fields:
37
+ ```bash
38
+ gh api repos/owner/repo/pulls/55 --jq '.title, .state, .user.login'
39
+ ```
40
+
41
+ ## JSON Output
42
+
43
+ Most commands support `--json` for structured output. You can use `--jq` to filter:
44
+
45
+ ```bash
46
+ gh issue list --repo owner/repo --json number,title --jq '.[] | "\(.number): \(.title)"'
47
+ ```
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: improve-skill
3
+ description: "Analyze coding agent session transcripts to improve existing skills or create new ones. Use when asked to improve a skill based on a session, or extract a new skill from session history."
4
+ ---
5
+
6
+ # Improve Skill
7
+
8
+ This skill helps analyze coding agent sessions to improve or create skills. It works with Claude Code, Pi, and Codex session files.
9
+
10
+ ## Quick Start
11
+
12
+ Extract the current session and generate an improvement prompt:
13
+
14
+ ```bash
15
+ # Auto-detect agent and extract current session
16
+ ./scripts/extract-session.js
17
+ ```
18
+
19
+ ## Session Extraction
20
+
21
+ The `extract-session.js` script finds and parses session files from any of the three agents:
22
+
23
+ ```bash
24
+ # Auto-detect (uses most recent session for current working directory)
25
+ ./scripts/extract-session.js
26
+
27
+ # Specify agent type
28
+ ./scripts/extract-session.js --agent claude
29
+ ./scripts/extract-session.js --agent pi
30
+ ./scripts/extract-session.js --agent codex
31
+
32
+ # Specify a different working directory
33
+ ./scripts/extract-session.js --cwd /path/to/project
34
+
35
+ # Use a specific session file
36
+ ./scripts/extract-session.js /path/to/session.jsonl
37
+ ```
38
+
39
+ **Session file locations:**
40
+ - **Claude Code**: `~/.claude/projects/<encoded-cwd>/*.jsonl`
41
+ - **Pi**: `~/.pi/agent/sessions/<encoded-cwd>/*.jsonl`
42
+ - **Codex**: `~/.codex/sessions/YYYY/MM/DD/*.jsonl`
43
+
44
+ ## Workflow: Improve an Existing Skill
45
+
46
+ When asked to improve a skill based on a session:
47
+
48
+ 1. **Extract the session transcript:**
49
+ ```bash
50
+ ./scripts/extract-session.js > /tmp/session-transcript.txt
51
+ ```
52
+
53
+ 2. **Find the existing skill** in one of these locations:
54
+ - `~/.codex/skills/<skill-name>/SKILL.md`
55
+ - `~/.claude/skills/<skill-name>/SKILL.md`
56
+ - `~/.pi/agent/skills/<skill-name>/SKILL.md`
57
+
58
+ 3. **Generate an improvement prompt** for a new session:
59
+
60
+ ```
61
+ ═══════════════════════════════════════════════════════════════════════════════
62
+ COPY THE FOLLOWING PROMPT INTO A NEW AGENT SESSION:
63
+ ═══════════════════════════════════════════════════════════════════════════════
64
+
65
+ I need to improve the "<skill-name>" skill based on a session where I used it.
66
+
67
+ First, read the current skill at: <path-to-skill>
68
+
69
+ Then analyze this session transcript to understand:
70
+ - Where I struggled to use the skill correctly
71
+ - What information was missing from the skill
72
+ - What examples would have helped
73
+ - What I had to figure out on my own
74
+
75
+ <session_transcript>
76
+ <paste transcript here>
77
+ </session_transcript>
78
+
79
+ Based on this analysis, improve the skill by:
80
+ 1. Adding missing instructions or clarifications
81
+ 2. Adding examples for common use cases discovered
82
+ 3. Fixing any incorrect guidance
83
+ 4. Making the skill more concise where possible
84
+
85
+ Write the improved skill back to the same location.
86
+
87
+ ═══════════════════════════════════════════════════════════════════════════════
88
+ ```
89
+
90
+ ## Workflow: Create a New Skill
91
+
92
+ When asked to create a new skill from a session:
93
+
94
+ 1. **Extract the session transcript:**
95
+ ```bash
96
+ ./scripts/extract-session.js > /tmp/session-transcript.txt
97
+ ```
98
+
99
+ 2. **Generate a creation prompt** for a new session:
100
+
101
+ ```
102
+ ═══════════════════════════════════════════════════════════════════════════════
103
+ COPY THE FOLLOWING PROMPT INTO A NEW AGENT SESSION:
104
+ ═══════════════════════════════════════════════════════════════════════════════
105
+
106
+ Analyze this session transcript to extract a reusable skill called "<skill-name>":
107
+
108
+ <session_transcript>
109
+ <paste transcript here>
110
+ </session_transcript>
111
+
112
+ Create a new skill that captures:
113
+ 1. The core capability or workflow demonstrated
114
+ 2. Key commands, APIs, or patterns used
115
+ 3. Common pitfalls and how to avoid them
116
+ 4. Example usage for typical scenarios
117
+
118
+ Write the skill to: ~/.codex/skills/<skill-name>/SKILL.md
119
+
120
+ Use this format:
121
+ ---
122
+ name: <skill-name>
123
+ description: "<one-line description>"
124
+ ---
125
+
126
+ # <Skill Name> Skill
127
+
128
+ <overview and quick reference>
129
+
130
+ ## <Section for each major capability>
131
+
132
+ <instructions and examples>
133
+
134
+ ═══════════════════════════════════════════════════════════════════════════════
135
+ ```
136
+
137
+ ## Why a Separate Session?
138
+
139
+ The improvement prompt is meant to be copied into a **fresh agent session** because:
140
+
141
+ 1. **Token efficiency** - The current session already has a lot of context; starting fresh means only the transcript and skill are loaded
142
+ 2. **Clean analysis** - The new session can focus purely on improvement without being influenced by the current task
143
+ 3. **Reproducibility** - The prompt is self-contained and can be shared or reused
144
+
145
+ ## Tips for Good Skill Improvements
146
+
147
+ When analyzing a transcript, look for:
148
+
149
+ - **Confusion patterns** - Where did the agent retry or change approach?
150
+ - **Missing examples** - What specific commands or code patterns were discovered?
151
+ - **Workarounds** - What did the agent have to figure out that wasn't documented?
152
+ - **Errors** - What failed and how was it resolved?
153
+ - **Successful patterns** - What worked well and should be highlighted?
154
+
155
+ Keep skills concise - focus on the most important information and examples.