@saifymatteo/pi-extensions 0.0.0-stage → 0.1.1

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 (183) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE.md +20 -0
  3. package/README.md +151 -2
  4. package/inventory.json +73 -0
  5. package/package.json +74 -4
  6. package/packages/pi-bg-bash/LICENSE +661 -0
  7. package/packages/pi-bg-bash/NOTICE.md +3 -0
  8. package/packages/pi-bg-bash/README.md +41 -0
  9. package/packages/pi-bg-bash/examples/settings.example.json +6 -0
  10. package/packages/pi-bg-bash/package.json +38 -0
  11. package/packages/pi-bg-bash/src/index.ts +969 -0
  12. package/packages/pi-bg-bash/src/lib/async-work.ts +27 -0
  13. package/packages/pi-bg-bash/test/bg-bash.test.mjs +34 -0
  14. package/packages/pi-claude-usage/LICENSE +661 -0
  15. package/packages/pi-claude-usage/NOTICE.md +3 -0
  16. package/packages/pi-claude-usage/README.md +27 -0
  17. package/packages/pi-claude-usage/package.json +35 -0
  18. package/packages/pi-claude-usage/src/index.ts +130 -0
  19. package/packages/pi-clipboard-image/LICENSE +661 -0
  20. package/packages/pi-clipboard-image/NOTICE.md +3 -0
  21. package/packages/pi-clipboard-image/README.md +27 -0
  22. package/packages/pi-clipboard-image/package.json +36 -0
  23. package/packages/pi-clipboard-image/src/index.ts +527 -0
  24. package/packages/pi-codeblock-borders/LICENSE +661 -0
  25. package/packages/pi-codeblock-borders/NOTICE.md +3 -0
  26. package/packages/pi-codeblock-borders/README.md +30 -0
  27. package/packages/pi-codeblock-borders/package.json +35 -0
  28. package/packages/pi-codeblock-borders/src/index.ts +302 -0
  29. package/packages/pi-codegraph/LICENSE +661 -0
  30. package/packages/pi-codegraph/NOTICE.md +5 -0
  31. package/packages/pi-codegraph/README.md +35 -0
  32. package/packages/pi-codegraph/examples/codegraph.example.json +4 -0
  33. package/packages/pi-codegraph/package.json +37 -0
  34. package/packages/pi-codegraph/src/index.ts +573 -0
  35. package/packages/pi-codegraph/test/codegraph.test.mjs +21 -0
  36. package/packages/pi-compact-tools/LICENSE +661 -0
  37. package/packages/pi-compact-tools/NOTICE.md +3 -0
  38. package/packages/pi-compact-tools/README.md +27 -0
  39. package/packages/pi-compact-tools/package.json +36 -0
  40. package/packages/pi-compact-tools/src/index.ts +1161 -0
  41. package/packages/pi-decisions/LICENSE +661 -0
  42. package/packages/pi-decisions/NOTICE.md +3 -0
  43. package/packages/pi-decisions/README.md +37 -0
  44. package/packages/pi-decisions/examples/service-models.example.json +27 -0
  45. package/packages/pi-decisions/package.json +37 -0
  46. package/packages/pi-decisions/src/index.ts +364 -0
  47. package/packages/pi-decisions/src/lib/service-models.ts +95 -0
  48. package/packages/pi-decisions/test/service-models.test.mjs +71 -0
  49. package/packages/pi-load-pi-dotenv/LICENSE +661 -0
  50. package/packages/pi-load-pi-dotenv/NOTICE.md +3 -0
  51. package/packages/pi-load-pi-dotenv/README.md +27 -0
  52. package/packages/pi-load-pi-dotenv/package.json +32 -0
  53. package/packages/pi-load-pi-dotenv/src/index.ts +66 -0
  54. package/packages/pi-model-go/LICENSE +661 -0
  55. package/packages/pi-model-go/NOTICE.md +5 -0
  56. package/packages/pi-model-go/README.md +33 -0
  57. package/packages/pi-model-go/package.json +36 -0
  58. package/packages/pi-model-go/src/index.ts +171 -0
  59. package/packages/pi-model-go/src/lib/dialog.ts +31 -0
  60. package/packages/pi-model-go/src/lib/model-go.ts +239 -0
  61. package/packages/pi-model-go/test/behavior.test.mjs +17 -0
  62. package/packages/pi-prestart-working/LICENSE +661 -0
  63. package/packages/pi-prestart-working/NOTICE.md +3 -0
  64. package/packages/pi-prestart-working/README.md +25 -0
  65. package/packages/pi-prestart-working/package.json +35 -0
  66. package/packages/pi-prestart-working/src/index.ts +86 -0
  67. package/packages/pi-prestart-working/test/behavior.test.mjs +56 -0
  68. package/packages/pi-root-guard/LICENSE +661 -0
  69. package/packages/pi-root-guard/NOTICE.md +3 -0
  70. package/packages/pi-root-guard/README.md +27 -0
  71. package/packages/pi-root-guard/package.json +32 -0
  72. package/packages/pi-root-guard/src/index.ts +202 -0
  73. package/packages/pi-session-finder/LICENSE +661 -0
  74. package/packages/pi-session-finder/NOTICE.md +3 -0
  75. package/packages/pi-session-finder/README.md +33 -0
  76. package/packages/pi-session-finder/package.json +36 -0
  77. package/packages/pi-session-finder/src/index.ts +306 -0
  78. package/packages/pi-session-finder/src/lib/dialog.ts +31 -0
  79. package/packages/pi-session-finder/test/behavior.test.mjs +18 -0
  80. package/packages/pi-session-id/LICENSE +661 -0
  81. package/packages/pi-session-id/NOTICE.md +3 -0
  82. package/packages/pi-session-id/README.md +31 -0
  83. package/packages/pi-session-id/package.json +35 -0
  84. package/packages/pi-session-id/src/index.ts +20 -0
  85. package/packages/pi-session-id/test/behavior.test.mjs +25 -0
  86. package/packages/pi-session-nav/LICENSE +661 -0
  87. package/packages/pi-session-nav/NOTICE.md +3 -0
  88. package/packages/pi-session-nav/README.md +32 -0
  89. package/packages/pi-session-nav/package.json +36 -0
  90. package/packages/pi-session-nav/src/index.ts +203 -0
  91. package/packages/pi-session-nav/src/lib/dialog.ts +31 -0
  92. package/packages/pi-session-nav/test/behavior.test.mjs +36 -0
  93. package/packages/pi-session-rename/LICENSE +661 -0
  94. package/packages/pi-session-rename/NOTICE.md +3 -0
  95. package/packages/pi-session-rename/README.md +31 -0
  96. package/packages/pi-session-rename/package.json +35 -0
  97. package/packages/pi-session-rename/src/index.ts +456 -0
  98. package/packages/pi-session-rename/test/behavior.test.mjs +10 -0
  99. package/packages/pi-session-retention/LICENSE +661 -0
  100. package/packages/pi-session-retention/NOTICE.md +3 -0
  101. package/packages/pi-session-retention/README.md +62 -0
  102. package/packages/pi-session-retention/package.json +36 -0
  103. package/packages/pi-session-retention/src/README.md +42 -0
  104. package/packages/pi-session-retention/src/core.ts +333 -0
  105. package/packages/pi-session-retention/src/dialog.ts +118 -0
  106. package/packages/pi-session-retention/src/index.ts +311 -0
  107. package/packages/pi-session-retention/src/lib/dialog.ts +31 -0
  108. package/packages/pi-session-retention/src/safety.ts +50 -0
  109. package/packages/pi-session-retention/test/behavior.test.mjs +42 -0
  110. package/packages/pi-skill-usage-log/LICENSE +661 -0
  111. package/packages/pi-skill-usage-log/NOTICE.md +3 -0
  112. package/packages/pi-skill-usage-log/README.md +32 -0
  113. package/packages/pi-skill-usage-log/package.json +36 -0
  114. package/packages/pi-skill-usage-log/src/index.ts +316 -0
  115. package/packages/pi-skill-usage-log/src/lib/dialog.ts +31 -0
  116. package/packages/pi-skill-usage-log/src/lib/usage-log.ts +62 -0
  117. package/packages/pi-skill-usage-log/test/behavior.test.mjs +34 -0
  118. package/packages/pi-tool-usage-log/LICENSE +661 -0
  119. package/packages/pi-tool-usage-log/NOTICE.md +5 -0
  120. package/packages/pi-tool-usage-log/README.md +32 -0
  121. package/packages/pi-tool-usage-log/package.json +36 -0
  122. package/packages/pi-tool-usage-log/src/index.ts +233 -0
  123. package/packages/pi-tool-usage-log/src/lib/dialog.ts +31 -0
  124. package/packages/pi-tool-usage-log/src/lib/usage-log.ts +62 -0
  125. package/packages/pi-tool-usage-log/src/skill-usage-log.ts +316 -0
  126. package/packages/pi-tool-usage-log/test/behavior.test.mjs +23 -0
  127. package/packages/pi-tts/LICENSE +661 -0
  128. package/packages/pi-tts/NOTICE.md +3 -0
  129. package/packages/pi-tts/README.md +37 -0
  130. package/packages/pi-tts/examples/service-models.example.json +27 -0
  131. package/packages/pi-tts/package.json +37 -0
  132. package/packages/pi-tts/src/index.ts +135 -0
  133. package/packages/pi-tts/src/lib/service-models.ts +95 -0
  134. package/packages/pi-tts/test/tts-output.test.mjs +47 -0
  135. package/packages/pi-tts/test/tts.test.mjs +57 -0
  136. package/packages/pi-user-image-previews/LICENSE +661 -0
  137. package/packages/pi-user-image-previews/NOTICE.md +3 -0
  138. package/packages/pi-user-image-previews/README.md +27 -0
  139. package/packages/pi-user-image-previews/package.json +36 -0
  140. package/packages/pi-user-image-previews/src/index.ts +168 -0
  141. package/packages/pi-vision/LICENSE +661 -0
  142. package/packages/pi-vision/NOTICE.md +5 -0
  143. package/packages/pi-vision/README.md +43 -0
  144. package/packages/pi-vision/examples/vision-toolkit.example.json +12 -0
  145. package/packages/pi-vision/package.json +38 -0
  146. package/packages/pi-vision/skills/vision-tools/LICENSE +21 -0
  147. package/packages/pi-vision/skills/vision-tools/SKILL.md +134 -0
  148. package/packages/pi-vision/skills/vision-tools/agents/openai.yaml +4 -0
  149. package/packages/pi-vision/skills/vision-tools/bin/crop +94 -0
  150. package/packages/pi-vision/skills/vision-tools/bin/detect +18 -0
  151. package/packages/pi-vision/skills/vision-tools/bin/glance +98 -0
  152. package/packages/pi-vision/skills/vision-tools/bin/ground +18 -0
  153. package/packages/pi-vision/skills/vision-tools/bin/trace +134 -0
  154. package/packages/pi-vision/skills/vision-tools/bin/vision-doctor +168 -0
  155. package/packages/pi-vision/skills/vision-tools/detect.py +56 -0
  156. package/packages/pi-vision/skills/vision-tools/ground.py +216 -0
  157. package/packages/pi-vision/skills/vision-tools/references/gui.md +93 -0
  158. package/packages/pi-vision/skills/vision-tools/references/long-screenshot-ocr.md +103 -0
  159. package/packages/pi-vision/skills/vision-tools/references/restore-graphic.md +92 -0
  160. package/packages/pi-vision/skills/vision-tools/references/restore-structure.md +47 -0
  161. package/packages/pi-vision/skills/vision-tools/references/restore-ui.md +200 -0
  162. package/packages/pi-vision/skills/vision-tools/scripts/dominant_colors.py +224 -0
  163. package/packages/pi-vision/skills/vision-tools/scripts/extract_fg.py +278 -0
  164. package/packages/pi-vision/skills/vision-tools/scripts/html_shot.py +111 -0
  165. package/packages/pi-vision/skills/vision-tools/scripts/long_screenshot_ocr.py +1245 -0
  166. package/packages/pi-vision/skills/vision-tools/scripts/pixel_diff.py +88 -0
  167. package/packages/pi-vision/skills/vision-tools/vision_client.py +581 -0
  168. package/packages/pi-vision/src/index.ts +728 -0
  169. package/packages/pi-vision/test/vision.test.mjs +30 -0
  170. package/packages/pi-wait/LICENSE +661 -0
  171. package/packages/pi-wait/NOTICE.md +3 -0
  172. package/packages/pi-wait/README.md +37 -0
  173. package/packages/pi-wait/package.json +37 -0
  174. package/packages/pi-wait/src/index.ts +88 -0
  175. package/packages/pi-wait/src/lib/async-work.ts +27 -0
  176. package/packages/pi-wait/test/wait.test.mjs +43 -0
  177. package/packages/pi-zvec/LICENSE +661 -0
  178. package/packages/pi-zvec/NOTICE.md +3 -0
  179. package/packages/pi-zvec/README.md +37 -0
  180. package/packages/pi-zvec/examples/zvec.example.json +5 -0
  181. package/packages/pi-zvec/package.json +37 -0
  182. package/packages/pi-zvec/src/index.ts +754 -0
  183. package/packages/pi-zvec/test/zvec.test.mjs +19 -0
@@ -0,0 +1,27 @@
1
+ # Claude subscription usage
2
+
3
+ Displays Claude subscription rate-limit windows from provider message diagnostics.
4
+
5
+ ## Try locally
6
+
7
+ From the repository root:
8
+
9
+ ```sh
10
+ pi -e ./packages/pi-claude-usage
11
+ ```
12
+
13
+ This uses your normal personal resources unless you isolate the agent home. Follow the [root README](../../README.md#isolated-sessions) to avoid loading an existing copy of the extension. Nothing is installed globally.
14
+
15
+ ## Configuration and requirements
16
+
17
+ Uses rate-limit diagnostics from the external pi-claude-code provider; it does not poll Anthropic. Caches the most recent windows in <agent-dir>/state/claude-usage.json. No additional configuration.
18
+
19
+ ## Compatibility and safety
20
+
21
+ Status/footer presentation depends on the host and other footer extensions.
22
+
23
+ Imported host APIs are declared as peer dependencies and supplied by the Pi host. A `*` peer range describes host resolution, not a guarantee of compatibility with every release. See root verification notes for what was actually exercised.
24
+
25
+ ## Status
26
+
27
+ Part of the [pi-extensions](../../README.md) collection. No personal settings or credentials are included; see [NOTICE.md](NOTICE.md) for licensing and provenance.
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@saifymatteo/pi-claude-usage",
3
+ "version": "0.1.1",
4
+ "description": "Displays Claude subscription rate-limit windows from provider message diagnostics.",
5
+ "type": "module",
6
+ "license": "AGPL-3.0-only",
7
+ "keywords": [
8
+ "pi-package"
9
+ ],
10
+ "files": [
11
+ "src",
12
+ "README.md",
13
+ "NOTICE.md",
14
+ "LICENSE"
15
+ ],
16
+ "pi": {
17
+ "extensions": [
18
+ "./src/index.ts"
19
+ ]
20
+ },
21
+ "engines": {
22
+ "node": ">=24"
23
+ },
24
+ "peerDependencies": {
25
+ "@earendil-works/pi-coding-agent": "*"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/saifymatteo/pi-extensions.git",
33
+ "directory": "packages/pi-claude-usage"
34
+ }
35
+ }
@@ -0,0 +1,130 @@
1
+ // Claude subscription usage (5h + 7d windows) in the footer.
2
+ //
3
+ // Data is free: pi-claude-code attaches Claude Code's rate_limit_event to
4
+ // every assistant message as a "claude-code.rate-limit" diagnostic, whose
5
+ // unifiedWindows carry utilization (0..1) and resetsAt (epoch seconds). The
6
+ // last value is cached on disk so a fresh session shows it before any turn.
7
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
8
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
9
+ import { homedir } from "node:os";
10
+ import { dirname, join } from "node:path";
11
+
12
+ const STATUS_KEY = "claude-usage";
13
+ const DIAGNOSTIC_TYPE = "claude-code.rate-limit";
14
+ const TICK_MS = 60_000; // countdown refresh only, no network
15
+
16
+ export interface Window {
17
+ pct: number; // 0..100
18
+ resetsAt: number; // epoch ms
19
+ }
20
+
21
+ export interface Usage {
22
+ fiveHour?: Window;
23
+ sevenDay?: Window;
24
+ rejected?: boolean;
25
+ overage?: boolean;
26
+ }
27
+
28
+ function cachePath(): string {
29
+ return join(process.env.PI_CODING_AGENT_DIR || join(homedir(), ".pi", "agent"), "state", "claude-usage.json");
30
+ }
31
+
32
+ // rate_limit_info from Claude Code stream-json.
33
+ export function fromRateLimit(info: any): Usage | undefined {
34
+ const w = info?.unifiedWindows;
35
+ if (!w || typeof w !== "object") return undefined;
36
+ const win = (x: any): Window | undefined =>
37
+ typeof x?.utilization === "number" && typeof x?.resetsAt === "number"
38
+ ? { pct: x.utilization * 100, resetsAt: x.resetsAt * 1000 }
39
+ : undefined;
40
+ return {
41
+ fiveHour: win(w.five_hour),
42
+ sevenDay: win(w.seven_day),
43
+ rejected: info.status === "rejected",
44
+ overage: info.isUsingOverage === true,
45
+ };
46
+ }
47
+
48
+ export function formatLeft(ms: number): string {
49
+ const mins = Math.max(0, Math.ceil(ms / 60_000));
50
+ const d = Math.floor(mins / 1440);
51
+ const h = Math.floor((mins % 1440) / 60);
52
+ const m = mins % 60;
53
+ if (d > 0) return `${d}d${h}h`;
54
+ if (h > 0) return `${h}h${String(m).padStart(2, "0")}m`;
55
+ return `${m}m`;
56
+ }
57
+
58
+ function part(label: string, w: Window | undefined, now: number): string {
59
+ if (!w) return `${label} ?`;
60
+ // A passed reset means the window rolled over since we last saw it.
61
+ if (w.resetsAt <= now) return `${label} 0%`;
62
+ return `${label} ${Math.round(w.pct)}% ↻${formatLeft(w.resetsAt - now)}`;
63
+ }
64
+
65
+ export function formatFooter(u: Usage, now = Date.now()): string {
66
+ return `Claude ${part("5h", u.fiveHour, now)} · ${part("7d", u.sevenDay, now)}${u.overage ? " · overage" : ""}`;
67
+ }
68
+
69
+ function peak(u: Usage, now: number): number {
70
+ const live = (w?: Window) => (w && w.resetsAt > now ? w.pct : 0);
71
+ return Math.max(live(u.fiveHour), live(u.sevenDay));
72
+ }
73
+
74
+ export default function (pi: ExtensionAPI) {
75
+ let usage: Usage | undefined;
76
+ let ctx: ExtensionContext | undefined;
77
+ let tick: ReturnType<typeof setInterval> | undefined;
78
+
79
+ function render() {
80
+ if (!ctx || !usage) return;
81
+ const now = Date.now();
82
+ const text = formatFooter(usage, now);
83
+ const p = peak(usage, now);
84
+ const color = usage.rejected || usage.overage || p >= 90 ? "error" : p >= 75 ? "warning" : "dim";
85
+ try {
86
+ ctx.ui.setStatus(STATUS_KEY, ctx.ui.theme.fg(color, text));
87
+ } catch {
88
+ /* replaced session */
89
+ }
90
+ }
91
+
92
+ function update(next: Usage | undefined) {
93
+ if (!next) return;
94
+ usage = next;
95
+ render();
96
+ try {
97
+ mkdirSync(dirname(cachePath()), { recursive: true });
98
+ writeFileSync(cachePath(), JSON.stringify(next));
99
+ } catch {
100
+ /* cache is best-effort */
101
+ }
102
+ }
103
+
104
+ pi.on("session_start", async (_event, sessionCtx) => {
105
+ ctx = sessionCtx;
106
+ try {
107
+ usage ??= JSON.parse(readFileSync(cachePath(), "utf8"));
108
+ } catch {
109
+ /* no cache yet */
110
+ }
111
+ render();
112
+ if (!tick) {
113
+ tick = setInterval(render, TICK_MS);
114
+ tick.unref?.();
115
+ }
116
+ });
117
+
118
+ pi.on("session_shutdown", async () => {
119
+ if (tick) clearInterval(tick);
120
+ tick = undefined;
121
+ ctx = undefined;
122
+ });
123
+
124
+ pi.on("message_end", async (event) => {
125
+ const msg: any = event.message;
126
+ if (msg?.role !== "assistant" || !Array.isArray(msg.diagnostics)) return;
127
+ const diag = msg.diagnostics.findLast((d: any) => d?.type === DIAGNOSTIC_TYPE);
128
+ if (diag) update(fromRateLimit(diag.details));
129
+ });
130
+ }