opengstack 0.13.7 → 0.13.9

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 (135) hide show
  1. package/bin/opengstack.js +35 -90
  2. package/package.json +2 -3
  3. package/scripts/install-skills.js +47 -58
  4. package/skills/browse/bin/find-browse +21 -0
  5. package/skills/browse/bin/remote-slug +14 -0
  6. package/skills/browse/scripts/build-node-server.sh +48 -0
  7. package/skills/browse/src/activity.ts +208 -0
  8. package/skills/browse/src/browser-manager.ts +959 -0
  9. package/skills/browse/src/buffers.ts +137 -0
  10. package/skills/browse/src/bun-polyfill.cjs +109 -0
  11. package/skills/browse/src/cli.ts +678 -0
  12. package/skills/browse/src/commands.ts +128 -0
  13. package/skills/browse/src/config.ts +150 -0
  14. package/skills/browse/src/cookie-import-browser.ts +625 -0
  15. package/skills/browse/src/cookie-picker-routes.ts +230 -0
  16. package/skills/browse/src/cookie-picker-ui.ts +688 -0
  17. package/skills/browse/src/find-browse.ts +61 -0
  18. package/skills/browse/src/meta-commands.ts +550 -0
  19. package/skills/browse/src/platform.ts +17 -0
  20. package/skills/browse/src/read-commands.ts +358 -0
  21. package/skills/browse/src/server.ts +1192 -0
  22. package/skills/browse/src/sidebar-agent.ts +280 -0
  23. package/skills/browse/src/sidebar-utils.ts +21 -0
  24. package/skills/browse/src/snapshot.ts +407 -0
  25. package/skills/browse/src/url-validation.ts +95 -0
  26. package/skills/browse/src/write-commands.ts +364 -0
  27. package/skills/browse/test/activity.test.ts +120 -0
  28. package/skills/browse/test/adversarial-security.test.ts +32 -0
  29. package/skills/browse/test/browser-manager-unit.test.ts +17 -0
  30. package/skills/browse/test/bun-polyfill.test.ts +72 -0
  31. package/skills/browse/test/commands.test.ts +2075 -0
  32. package/skills/browse/test/compare-board.test.ts +342 -0
  33. package/skills/browse/test/config.test.ts +316 -0
  34. package/skills/browse/test/cookie-import-browser.test.ts +519 -0
  35. package/skills/browse/test/cookie-picker-routes.test.ts +260 -0
  36. package/skills/browse/test/file-drop.test.ts +271 -0
  37. package/skills/browse/test/find-browse.test.ts +50 -0
  38. package/skills/browse/test/findport.test.ts +191 -0
  39. package/skills/browse/test/fixtures/basic.html +33 -0
  40. package/skills/browse/test/fixtures/cursor-interactive.html +22 -0
  41. package/skills/browse/test/fixtures/dialog.html +15 -0
  42. package/skills/browse/test/fixtures/empty.html +2 -0
  43. package/skills/browse/test/fixtures/forms.html +55 -0
  44. package/skills/browse/test/fixtures/iframe.html +30 -0
  45. package/skills/browse/test/fixtures/network-idle.html +30 -0
  46. package/skills/browse/test/fixtures/qa-eval-checkout.html +108 -0
  47. package/skills/browse/test/fixtures/qa-eval-spa.html +98 -0
  48. package/skills/browse/test/fixtures/qa-eval.html +51 -0
  49. package/skills/browse/test/fixtures/responsive.html +49 -0
  50. package/skills/browse/test/fixtures/snapshot.html +55 -0
  51. package/skills/browse/test/fixtures/spa.html +24 -0
  52. package/skills/browse/test/fixtures/states.html +17 -0
  53. package/skills/browse/test/fixtures/upload.html +25 -0
  54. package/skills/browse/test/gstack-config.test.ts +138 -0
  55. package/skills/browse/test/gstack-update-check.test.ts +514 -0
  56. package/skills/browse/test/handoff.test.ts +235 -0
  57. package/skills/browse/test/path-validation.test.ts +91 -0
  58. package/skills/browse/test/platform.test.ts +37 -0
  59. package/skills/browse/test/server-auth.test.ts +65 -0
  60. package/skills/browse/test/sidebar-agent-roundtrip.test.ts +226 -0
  61. package/skills/browse/test/sidebar-agent.test.ts +199 -0
  62. package/skills/browse/test/sidebar-integration.test.ts +320 -0
  63. package/skills/browse/test/sidebar-unit.test.ts +96 -0
  64. package/skills/browse/test/snapshot.test.ts +467 -0
  65. package/skills/browse/test/state-ttl.test.ts +35 -0
  66. package/skills/browse/test/test-server.ts +57 -0
  67. package/skills/browse/test/url-validation.test.ts +72 -0
  68. package/skills/browse/test/watch.test.ts +129 -0
  69. package/skills/careful/bin/check-careful.sh +112 -0
  70. package/skills/cso/ACKNOWLEDGEMENTS.md +14 -0
  71. package/skills/freeze/bin/check-freeze.sh +79 -0
  72. package/skills/qa/references/issue-taxonomy.md +85 -0
  73. package/skills/qa/templates/qa-report-template.md +126 -0
  74. package/skills/review/TODOS-format.md +62 -0
  75. package/skills/review/checklist.md +220 -0
  76. package/skills/review/design-checklist.md +132 -0
  77. package/skills/review/greptile-triage.md +220 -0
  78. /package/{autoplan → skills/autoplan}/SKILL.md +0 -0
  79. /package/{autoplan → skills/autoplan}/SKILL.md.tmpl +0 -0
  80. /package/{benchmark → skills/benchmark}/SKILL.md +0 -0
  81. /package/{benchmark → skills/benchmark}/SKILL.md.tmpl +0 -0
  82. /package/{browse → skills/browse}/SKILL.md +0 -0
  83. /package/{browse → skills/browse}/SKILL.md.tmpl +0 -0
  84. /package/{canary → skills/canary}/SKILL.md +0 -0
  85. /package/{canary → skills/canary}/SKILL.md.tmpl +0 -0
  86. /package/{careful → skills/careful}/SKILL.md +0 -0
  87. /package/{careful → skills/careful}/SKILL.md.tmpl +0 -0
  88. /package/{codex → skills/codex}/SKILL.md +0 -0
  89. /package/{codex → skills/codex}/SKILL.md.tmpl +0 -0
  90. /package/{connect-chrome → skills/connect-chrome}/SKILL.md +0 -0
  91. /package/{connect-chrome → skills/connect-chrome}/SKILL.md.tmpl +0 -0
  92. /package/{cso → skills/cso}/SKILL.md +0 -0
  93. /package/{cso → skills/cso}/SKILL.md.tmpl +0 -0
  94. /package/{design-consultation → skills/design-consultation}/SKILL.md +0 -0
  95. /package/{design-consultation → skills/design-consultation}/SKILL.md.tmpl +0 -0
  96. /package/{design-review → skills/design-review}/SKILL.md +0 -0
  97. /package/{design-review → skills/design-review}/SKILL.md.tmpl +0 -0
  98. /package/{design-shotgun → skills/design-shotgun}/SKILL.md +0 -0
  99. /package/{design-shotgun → skills/design-shotgun}/SKILL.md.tmpl +0 -0
  100. /package/{document-release → skills/document-release}/SKILL.md +0 -0
  101. /package/{document-release → skills/document-release}/SKILL.md.tmpl +0 -0
  102. /package/{freeze → skills/freeze}/SKILL.md +0 -0
  103. /package/{freeze → skills/freeze}/SKILL.md.tmpl +0 -0
  104. /package/{gstack-upgrade → skills/gstack-upgrade}/SKILL.md +0 -0
  105. /package/{gstack-upgrade → skills/gstack-upgrade}/SKILL.md.tmpl +0 -0
  106. /package/{guard → skills/guard}/SKILL.md +0 -0
  107. /package/{guard → skills/guard}/SKILL.md.tmpl +0 -0
  108. /package/{investigate → skills/investigate}/SKILL.md +0 -0
  109. /package/{investigate → skills/investigate}/SKILL.md.tmpl +0 -0
  110. /package/{land-and-deploy → skills/land-and-deploy}/SKILL.md +0 -0
  111. /package/{land-and-deploy → skills/land-and-deploy}/SKILL.md.tmpl +0 -0
  112. /package/{office-hours → skills/office-hours}/SKILL.md +0 -0
  113. /package/{office-hours → skills/office-hours}/SKILL.md.tmpl +0 -0
  114. /package/{plan-ceo-review → skills/plan-ceo-review}/SKILL.md +0 -0
  115. /package/{plan-ceo-review → skills/plan-ceo-review}/SKILL.md.tmpl +0 -0
  116. /package/{plan-design-review → skills/plan-design-review}/SKILL.md +0 -0
  117. /package/{plan-design-review → skills/plan-design-review}/SKILL.md.tmpl +0 -0
  118. /package/{plan-eng-review → skills/plan-eng-review}/SKILL.md +0 -0
  119. /package/{plan-eng-review → skills/plan-eng-review}/SKILL.md.tmpl +0 -0
  120. /package/{qa → skills/qa}/SKILL.md +0 -0
  121. /package/{qa → skills/qa}/SKILL.md.tmpl +0 -0
  122. /package/{qa-only → skills/qa-only}/SKILL.md +0 -0
  123. /package/{qa-only → skills/qa-only}/SKILL.md.tmpl +0 -0
  124. /package/{retro → skills/retro}/SKILL.md +0 -0
  125. /package/{retro → skills/retro}/SKILL.md.tmpl +0 -0
  126. /package/{review → skills/review}/SKILL.md +0 -0
  127. /package/{review → skills/review}/SKILL.md.tmpl +0 -0
  128. /package/{setup-browser-cookies → skills/setup-browser-cookies}/SKILL.md +0 -0
  129. /package/{setup-browser-cookies → skills/setup-browser-cookies}/SKILL.md.tmpl +0 -0
  130. /package/{setup-deploy → skills/setup-deploy}/SKILL.md +0 -0
  131. /package/{setup-deploy → skills/setup-deploy}/SKILL.md.tmpl +0 -0
  132. /package/{ship → skills/ship}/SKILL.md +0 -0
  133. /package/{ship → skills/ship}/SKILL.md.tmpl +0 -0
  134. /package/{unfreeze → skills/unfreeze}/SKILL.md +0 -0
  135. /package/{unfreeze → skills/unfreeze}/SKILL.md.tmpl +0 -0
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Shared buffers and types — extracted to break circular dependency
3
+ * between server.ts and browser-manager.ts
4
+ *
5
+ * CircularBuffer<T>: O(1) insert ring buffer with fixed capacity.
6
+ *
7
+ * ┌───┬───┬───┬───┬───┬───┐
8
+ * │ 3 │ 4 │ 5 │ │ 1 │ 2 │ capacity=6, head=4, size=5
9
+ * └───┴───┴───┴───┴─▲─┴───┘
10
+ * │
11
+ * head (oldest entry)
12
+ *
13
+ * push() writes at (head+size) % capacity, O(1)
14
+ * toArray() returns entries in insertion order, O(n)
15
+ * totalAdded keeps incrementing past capacity (flush cursor)
16
+ */
17
+
18
+ // ─── CircularBuffer ─────────────────────────────────────────
19
+
20
+ export class CircularBuffer<T> {
21
+ private buffer: (T | undefined)[];
22
+ private head: number = 0;
23
+ private _size: number = 0;
24
+ private _totalAdded: number = 0;
25
+ readonly capacity: number;
26
+
27
+ constructor(capacity: number) {
28
+ this.capacity = capacity;
29
+ this.buffer = new Array(capacity);
30
+ }
31
+
32
+ push(entry: T): void {
33
+ const index = (this.head + this._size) % this.capacity;
34
+ this.buffer[index] = entry;
35
+ if (this._size < this.capacity) {
36
+ this._size++;
37
+ } else {
38
+ // Buffer full — advance head (overwrites oldest)
39
+ this.head = (this.head + 1) % this.capacity;
40
+ }
41
+ this._totalAdded++;
42
+ }
43
+
44
+ /** Return entries in insertion order (oldest first) */
45
+ toArray(): T[] {
46
+ const result: T[] = [];
47
+ for (let i = 0; i < this._size; i++) {
48
+ result.push(this.buffer[(this.head + i) % this.capacity] as T);
49
+ }
50
+ return result;
51
+ }
52
+
53
+ /** Return the last N entries (most recent first → reversed to oldest first) */
54
+ last(n: number): T[] {
55
+ const count = Math.min(n, this._size);
56
+ const result: T[] = [];
57
+ const start = (this.head + this._size - count) % this.capacity;
58
+ for (let i = 0; i < count; i++) {
59
+ result.push(this.buffer[(start + i) % this.capacity] as T);
60
+ }
61
+ return result;
62
+ }
63
+
64
+ get length(): number {
65
+ return this._size;
66
+ }
67
+
68
+ get totalAdded(): number {
69
+ return this._totalAdded;
70
+ }
71
+
72
+ clear(): void {
73
+ this.head = 0;
74
+ this._size = 0;
75
+ // Don't reset totalAdded — flush cursor depends on it
76
+ }
77
+
78
+ /** Get entry by index (0 = oldest) — used by network response matching */
79
+ get(index: number): T | undefined {
80
+ if (index < 0 || index >= this._size) return undefined;
81
+ return this.buffer[(this.head + index) % this.capacity];
82
+ }
83
+
84
+ /** Set entry by index (0 = oldest) — used by network response matching */
85
+ set(index: number, entry: T): void {
86
+ if (index < 0 || index >= this._size) return;
87
+ this.buffer[(this.head + index) % this.capacity] = entry;
88
+ }
89
+ }
90
+
91
+ // ─── Entry Types ────────────────────────────────────────────
92
+
93
+ export interface LogEntry {
94
+ timestamp: number;
95
+ level: string;
96
+ text: string;
97
+ }
98
+
99
+ export interface NetworkEntry {
100
+ timestamp: number;
101
+ method: string;
102
+ url: string;
103
+ status?: number;
104
+ duration?: number;
105
+ size?: number;
106
+ }
107
+
108
+ export interface DialogEntry {
109
+ timestamp: number;
110
+ type: string; // 'alert' | 'confirm' | 'prompt' | 'beforeunload'
111
+ message: string;
112
+ defaultValue?: string;
113
+ action: string; // 'accepted' | 'dismissed'
114
+ response?: string; // text provided for prompt
115
+ }
116
+
117
+ // ─── Buffer Instances ───────────────────────────────────────
118
+
119
+ const HIGH_WATER_MARK = 50_000;
120
+
121
+ export const consoleBuffer = new CircularBuffer<LogEntry>(HIGH_WATER_MARK);
122
+ export const networkBuffer = new CircularBuffer<NetworkEntry>(HIGH_WATER_MARK);
123
+ export const dialogBuffer = new CircularBuffer<DialogEntry>(HIGH_WATER_MARK);
124
+
125
+ // ─── Convenience add functions ──────────────────────────────
126
+
127
+ export function addConsoleEntry(entry: LogEntry) {
128
+ consoleBuffer.push(entry);
129
+ }
130
+
131
+ export function addNetworkEntry(entry: NetworkEntry) {
132
+ networkBuffer.push(entry);
133
+ }
134
+
135
+ export function addDialogEntry(entry: DialogEntry) {
136
+ dialogBuffer.push(entry);
137
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Bun API polyfill for Node.js — Windows compatibility layer.
3
+ *
4
+ * On Windows, Bun can't launch or connect to Playwright's Chromium
5
+ * (oven-sh/bun#4253, #9911). The browse server falls back to running
6
+ * under Node.js with this polyfill providing Bun API equivalents.
7
+ *
8
+ * Loaded via --require before the transpiled server bundle.
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const http = require('http');
14
+ const { spawnSync, spawn } = require('child_process');
15
+
16
+ globalThis.Bun = {
17
+ serve(options) {
18
+ const { port, hostname = '127.0.0.1', fetch } = options;
19
+
20
+ const server = http.createServer(async (nodeReq, nodeRes) => {
21
+ try {
22
+ const url = `http://${hostname}:${port}${nodeReq.url}`;
23
+ const headers = new Headers();
24
+ for (const [key, val] of Object.entries(nodeReq.headers)) {
25
+ if (val) headers.set(key, Array.isArray(val) ? val[0] : val);
26
+ }
27
+
28
+ let body = null;
29
+ if (nodeReq.method !== 'GET' && nodeReq.method !== 'HEAD') {
30
+ body = await new Promise((resolve) => {
31
+ const chunks = [];
32
+ nodeReq.on('data', (chunk) => chunks.push(chunk));
33
+ nodeReq.on('end', () => resolve(Buffer.concat(chunks)));
34
+ });
35
+ }
36
+
37
+ const webReq = new Request(url, {
38
+ method: nodeReq.method,
39
+ headers,
40
+ body,
41
+ });
42
+
43
+ const webRes = await fetch(webReq);
44
+
45
+ nodeRes.statusCode = webRes.status;
46
+ webRes.headers.forEach((val, key) => {
47
+ nodeRes.setHeader(key, val);
48
+ });
49
+
50
+ const resBody = await webRes.arrayBuffer();
51
+ nodeRes.end(Buffer.from(resBody));
52
+ } catch (err) {
53
+ nodeRes.statusCode = 500;
54
+ nodeRes.end(JSON.stringify({ error: err.message }));
55
+ }
56
+ });
57
+
58
+ server.listen(port, hostname);
59
+
60
+ return {
61
+ stop() { server.close(); },
62
+ port,
63
+ hostname,
64
+ };
65
+ },
66
+
67
+ spawnSync(cmd, options = {}) {
68
+ const [command, ...args] = cmd;
69
+ const result = spawnSync(command, args, {
70
+ stdio: [
71
+ options.stdin || 'pipe',
72
+ options.stdout === 'pipe' ? 'pipe' : 'ignore',
73
+ options.stderr === 'pipe' ? 'pipe' : 'ignore',
74
+ ],
75
+ timeout: options.timeout,
76
+ env: options.env,
77
+ cwd: options.cwd,
78
+ });
79
+
80
+ return {
81
+ exitCode: result.status,
82
+ stdout: result.stdout || Buffer.from(''),
83
+ stderr: result.stderr || Buffer.from(''),
84
+ };
85
+ },
86
+
87
+ spawn(cmd, options = {}) {
88
+ const [command, ...args] = cmd;
89
+ const stdio = options.stdio || ['pipe', 'pipe', 'pipe'];
90
+ const proc = spawn(command, args, {
91
+ stdio,
92
+ env: options.env,
93
+ cwd: options.cwd,
94
+ });
95
+
96
+ return {
97
+ pid: proc.pid,
98
+ stdout: proc.stdout,
99
+ stderr: proc.stderr,
100
+ stdin: proc.stdin,
101
+ unref() { proc.unref(); },
102
+ kill(signal) { proc.kill(signal); },
103
+ };
104
+ },
105
+
106
+ sleep(ms) {
107
+ return new Promise((resolve) => setTimeout(resolve, ms));
108
+ },
109
+ };