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,266 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { connect } from "./cdp.js";
7
+
8
+ const LOG_ROOT = join(homedir(), ".cache/agent-web/logs");
9
+ const PID_FILE = join(LOG_ROOT, ".pid");
10
+
11
+ function ensureDir(dir) {
12
+ if (!existsSync(dir)) {
13
+ mkdirSync(dir, { recursive: true });
14
+ }
15
+ }
16
+
17
+ function isProcessAlive(pid) {
18
+ try {
19
+ process.kill(pid, 0);
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ function getDateDir() {
27
+ const now = new Date();
28
+ const yyyy = String(now.getFullYear());
29
+ const mm = String(now.getMonth() + 1).padStart(2, "0");
30
+ const dd = String(now.getDate()).padStart(2, "0");
31
+ return join(LOG_ROOT, `${yyyy}-${mm}-${dd}`);
32
+ }
33
+
34
+ function safeFileName(value) {
35
+ return value.replace(/[^a-zA-Z0-9._-]/g, "_");
36
+ }
37
+
38
+ function compactStack(stackTrace) {
39
+ if (!stackTrace || !Array.isArray(stackTrace.callFrames)) return null;
40
+ return stackTrace.callFrames.slice(0, 8).map((frame) => ({
41
+ functionName: frame.functionName || null,
42
+ url: frame.url || null,
43
+ lineNumber: frame.lineNumber,
44
+ columnNumber: frame.columnNumber,
45
+ }));
46
+ }
47
+
48
+ function serializeRemoteObject(obj) {
49
+ if (!obj || typeof obj !== "object") return obj;
50
+ const value =
51
+ Object.prototype.hasOwnProperty.call(obj, "value")
52
+ ? obj.value
53
+ : obj.unserializableValue || obj.description || null;
54
+ return {
55
+ type: obj.type || null,
56
+ subtype: obj.subtype || null,
57
+ value,
58
+ description: obj.description || null,
59
+ };
60
+ }
61
+
62
+ ensureDir(LOG_ROOT);
63
+
64
+ if (existsSync(PID_FILE)) {
65
+ try {
66
+ const existing = Number(readFileSync(PID_FILE, "utf8").trim());
67
+ if (existing && isProcessAlive(existing)) {
68
+ console.log("✓ watch already running");
69
+ process.exit(0);
70
+ }
71
+ } catch {
72
+ // Ignore and overwrite stale pid.
73
+ }
74
+ }
75
+
76
+ writeFileSync(PID_FILE, String(process.pid));
77
+
78
+ const dateDir = getDateDir();
79
+ ensureDir(dateDir);
80
+
81
+ const targetState = new Map();
82
+ const sessionToTarget = new Map();
83
+
84
+ function getStreamForTarget(targetId) {
85
+ const state = targetState.get(targetId);
86
+ if (state?.stream) return state.stream;
87
+ const filename = `${safeFileName(targetId)}.jsonl`;
88
+ const filepath = join(dateDir, filename);
89
+ const stream = createWriteStream(filepath, { flags: "a" });
90
+ if (state) state.stream = stream;
91
+ return stream;
92
+ }
93
+
94
+ function writeLog(targetId, payload) {
95
+ const stream = getStreamForTarget(targetId);
96
+ const record = {
97
+ ts: new Date().toISOString(),
98
+ targetId,
99
+ ...payload,
100
+ };
101
+ stream.write(`${JSON.stringify(record)}\n`);
102
+ }
103
+
104
+ async function enableSession(cdp, sessionId) {
105
+ await cdp.send("Runtime.enable", {}, sessionId);
106
+ await cdp.send("Log.enable", {}, sessionId);
107
+ await cdp.send("Network.enable", {}, sessionId);
108
+ await cdp.send("Page.enable", {}, sessionId);
109
+ }
110
+
111
+ async function attachToTarget(cdp, targetInfo) {
112
+ if (targetInfo.type !== "page") return;
113
+ if (targetState.has(targetInfo.targetId)) return;
114
+
115
+ const { sessionId } = await cdp.send("Target.attachToTarget", {
116
+ targetId: targetInfo.targetId,
117
+ flatten: true,
118
+ });
119
+
120
+ targetState.set(targetInfo.targetId, {
121
+ sessionId,
122
+ url: targetInfo.url || null,
123
+ title: targetInfo.title || null,
124
+ stream: null,
125
+ });
126
+ sessionToTarget.set(sessionId, targetInfo.targetId);
127
+
128
+ await enableSession(cdp, sessionId);
129
+ writeLog(targetInfo.targetId, {
130
+ type: "target.attached",
131
+ url: targetInfo.url || null,
132
+ title: targetInfo.title || null,
133
+ });
134
+ }
135
+
136
+ async function main() {
137
+ const cdp = await connect(5000);
138
+
139
+ cdp.on("Target.targetCreated", async (params) => {
140
+ try {
141
+ await attachToTarget(cdp, params.targetInfo);
142
+ } catch (e) {
143
+ console.error("watch: attach error:", e.message);
144
+ }
145
+ });
146
+
147
+ cdp.on("Target.targetDestroyed", (params) => {
148
+ const targetId = params.targetId;
149
+ const state = targetState.get(targetId);
150
+ if (state?.stream) state.stream.end();
151
+ targetState.delete(targetId);
152
+ if (state?.sessionId) sessionToTarget.delete(state.sessionId);
153
+ });
154
+
155
+ cdp.on("Target.targetInfoChanged", (params) => {
156
+ const info = params.targetInfo;
157
+ const state = targetState.get(info.targetId);
158
+ if (state) {
159
+ state.url = info.url || state.url;
160
+ state.title = info.title || state.title;
161
+ writeLog(info.targetId, {
162
+ type: "target.info",
163
+ url: info.url || null,
164
+ title: info.title || null,
165
+ });
166
+ }
167
+ });
168
+
169
+ cdp.on("Runtime.consoleAPICalled", (params, sessionId) => {
170
+ const targetId = sessionToTarget.get(sessionId);
171
+ if (!targetId) return;
172
+ writeLog(targetId, {
173
+ type: "console",
174
+ level: params.type || null,
175
+ args: (params.args || []).map(serializeRemoteObject),
176
+ stack: compactStack(params.stackTrace),
177
+ });
178
+ });
179
+
180
+ cdp.on("Runtime.exceptionThrown", (params, sessionId) => {
181
+ const targetId = sessionToTarget.get(sessionId);
182
+ if (!targetId) return;
183
+ const details = params.exceptionDetails || {};
184
+ writeLog(targetId, {
185
+ type: "exception",
186
+ text: details.text || null,
187
+ description: details.exception?.description || null,
188
+ lineNumber: details.lineNumber,
189
+ columnNumber: details.columnNumber,
190
+ url: details.url || null,
191
+ stack: compactStack(details.stackTrace),
192
+ });
193
+ });
194
+
195
+ cdp.on("Log.entryAdded", (params, sessionId) => {
196
+ const targetId = sessionToTarget.get(sessionId);
197
+ if (!targetId) return;
198
+ const entry = params.entry || {};
199
+ writeLog(targetId, {
200
+ type: "log",
201
+ level: entry.level || null,
202
+ source: entry.source || null,
203
+ text: entry.text || null,
204
+ url: entry.url || null,
205
+ lineNumber: entry.lineNumber ?? null,
206
+ });
207
+ });
208
+
209
+ cdp.on("Network.requestWillBeSent", (params, sessionId) => {
210
+ const targetId = sessionToTarget.get(sessionId);
211
+ if (!targetId) return;
212
+ const request = params.request || {};
213
+ writeLog(targetId, {
214
+ type: "network.request",
215
+ requestId: params.requestId,
216
+ method: request.method || null,
217
+ url: request.url || null,
218
+ documentURL: params.documentURL || null,
219
+ initiator: params.initiator?.type || null,
220
+ hasPostData: !!request.hasPostData,
221
+ });
222
+ });
223
+
224
+ cdp.on("Network.responseReceived", (params, sessionId) => {
225
+ const targetId = sessionToTarget.get(sessionId);
226
+ if (!targetId) return;
227
+ const response = params.response || {};
228
+ writeLog(targetId, {
229
+ type: "network.response",
230
+ requestId: params.requestId,
231
+ url: response.url || null,
232
+ status: response.status,
233
+ statusText: response.statusText || null,
234
+ mimeType: response.mimeType || null,
235
+ fromDiskCache: !!response.fromDiskCache,
236
+ fromServiceWorker: !!response.fromServiceWorker,
237
+ });
238
+ });
239
+
240
+ cdp.on("Network.loadingFailed", (params, sessionId) => {
241
+ const targetId = sessionToTarget.get(sessionId);
242
+ if (!targetId) return;
243
+ writeLog(targetId, {
244
+ type: "network.failure",
245
+ requestId: params.requestId,
246
+ errorText: params.errorText || null,
247
+ canceled: !!params.canceled,
248
+ });
249
+ });
250
+
251
+ await cdp.send("Target.setDiscoverTargets", { discover: true });
252
+
253
+ const pages = await cdp.getPages();
254
+ for (const page of pages) {
255
+ await attachToTarget(cdp, page);
256
+ }
257
+
258
+ console.log("✓ watch started");
259
+ }
260
+
261
+ try {
262
+ await main();
263
+ } catch (e) {
264
+ console.error("✗ watch failed:", e.message);
265
+ process.exit(1);
266
+ }