teamshare-bridge 0.26.24 → 0.26.25
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/README.md +383 -383
- package/dist/bridge/install-verify.js +8 -8
- package/dist/bridge/wake-handler.js +5 -4
- package/dist/bridge/wake-handler.js.map +1 -1
- package/dist/lib/agent-scope.js +10 -10
- package/dist/lib/browser/browse-llm.js +44 -44
- package/dist/lib/browser/human-input-guard.js +106 -106
- package/dist/lib/browser/login.js +141 -141
- package/dist/lib/browser/otp.js +72 -72
- package/dist/lib/browser/page-context.js +592 -592
- package/dist/lib/browser/page-events.js +91 -91
- package/dist/lib/browser/refs.js +264 -264
- package/dist/lib/browser/screen-change.js +79 -79
- package/dist/lib/harness/harness-adapter.js +8 -0
- package/dist/lib/harness/harness-adapter.js.map +1 -1
- package/dist/lib/human-style.js +32 -32
- package/dist/lib/scope-guard.js +15 -5
- package/dist/lib/scope-guard.js.map +1 -1
- package/package.json +1 -1
- package/skills/THIRD_PARTY_NOTICES.md +26 -26
- package/skills/architect/LICENSE +21 -21
- package/skills/codebase-design/LICENSE +21 -21
- package/skills/diagnosing-bugs/LICENSE +21 -21
- package/skills/domain-modeling/LICENSE +21 -21
- package/skills/improve-codebase-architecture/LICENSE +21 -21
- package/skills/recover/LICENSE +21 -21
- package/skills/review/LICENSE +21 -21
- package/skills/tdd/LICENSE +21 -21
- package/skills/teamshare-auth-rbac/SKILL.md +78 -78
- package/skills/teamshare-cdd/SKILL.md +215 -215
- package/skills/teamshare-modularity/SKILL.md +146 -146
- package/skills/teamshare-orchestrator-ask/SKILL.md +77 -77
- package/skills/teamshare-scaffold/SKILL.md +116 -116
- package/templates/backend/.env.example.tpl +13 -13
- package/templates/backend/nest-cli.json.tpl +8 -8
- package/templates/backend/package.json.tpl +41 -41
- package/templates/backend/prisma/schema.prisma.tpl +39 -39
- package/templates/backend/src/app.module.ts.tpl +24 -24
- package/templates/backend/src/common/filters/all-exceptions.filter.ts.tpl +59 -59
- package/templates/backend/src/common/guards/jwt-auth.guard.ts.tpl +27 -27
- package/templates/backend/src/common/guards/rbac.guard.ts.tpl +48 -48
- package/templates/backend/src/common/interceptors/transform.interceptor.ts.tpl +44 -44
- package/templates/backend/src/common/pipes/zod-validation.pipe.ts.tpl +29 -29
- package/templates/backend/src/common/swagger/envelope.schemas.ts.tpl +53 -53
- package/templates/backend/src/common/swagger/error.schemas.ts.tpl +62 -62
- package/templates/backend/src/main.ts.tpl +27 -27
- package/templates/backend/src/modules/example/example.controller.ts.tpl +102 -102
- package/templates/backend/src/modules/example/example.dto.ts.tpl +14 -14
- package/templates/backend/src/modules/example/example.module.ts.tpl +10 -10
- package/templates/backend/src/modules/example/example.service.ts.tpl +45 -45
- package/templates/backend/tsconfig.json.tpl +26 -26
- package/templates/common/.gitignore.tpl +42 -42
- package/templates/common/AGENTS.md.tpl +58 -58
- package/templates/common/docs/adr/README.md +25 -25
- package/templates/common/docs/api-contract.md.tpl +72 -72
- package/templates/web/next.config.ts.tpl +7 -7
- package/templates/web/package.json.tpl +37 -37
- package/templates/web/src/app/globals.css.tpl +48 -48
- package/templates/web/src/app/layout.tsx.tpl +25 -25
- package/templates/web/src/components/shared/app-button.tsx.tpl +59 -59
- package/templates/web/src/components/shared/app-empty-state.tsx.tpl +39 -39
- package/templates/web/src/components/shared/app-list-toolbar.tsx.tpl +63 -63
- package/templates/web/src/components/shared/app-skeleton.tsx.tpl +14 -14
- package/templates/web/src/components/shared/app-table.tsx.tpl +128 -128
- package/templates/web/src/components/shared/index.ts.tpl +5 -5
- package/templates/web/src/hooks/use-list-state.ts.tpl +72 -72
- package/templates/web/src/hooks/use-url-tab.ts.tpl +25 -25
- package/templates/web/src/lib/api/client.ts.tpl +123 -123
- package/templates/web/src/lib/providers.tsx.tpl +35 -35
- package/templates/web/src/lib/query-keys.ts.tpl +21 -21
- package/templates/web/src/lib/utils.ts.tpl +7 -7
- package/templates/web/src/lib/validation/schemas.ts.tpl +15 -15
- package/templates/web/src/modules/example/views/example-list-view.tsx.tpl +97 -97
- package/templates/web/tsconfig.json.tpl +23 -23
- package/tools/workspace-arbitration-check.mjs +359 -359
package/dist/lib/browser/otp.js
CHANGED
|
@@ -18,57 +18,57 @@ exports.fillOtpGroup = fillOtpGroup;
|
|
|
18
18
|
* and only submits when the widget did NOT auto-submit itself.
|
|
19
19
|
*/
|
|
20
20
|
const cdp_1 = require("./cdp");
|
|
21
|
-
const FILL_OTP_JS = `(() => {
|
|
22
|
-
const vis = (el) => {
|
|
23
|
-
if (!el) return false;
|
|
24
|
-
const r = el.getBoundingClientRect();
|
|
25
|
-
if (r.width === 0 || r.height === 0) return false;
|
|
26
|
-
const cs = getComputedStyle(el);
|
|
27
|
-
return cs.visibility !== 'hidden' && cs.display !== 'none' && cs.opacity !== '0';
|
|
28
|
-
};
|
|
29
|
-
const dialogSel = 'dialog[open],[role="dialog"],[aria-modal="true"],' +
|
|
30
|
-
'[class*="modal"],[class*="Modal"],[class*="dialog"],[class*="Dialog"]';
|
|
31
|
-
const dialogs = [...document.querySelectorAll(dialogSel)].filter(vis);
|
|
32
|
-
const scope = dialogs.length ? dialogs[dialogs.length - 1] : document;
|
|
33
|
-
const inputs = [...scope.querySelectorAll('input')]
|
|
34
|
-
.filter(vis)
|
|
35
|
-
.filter((el) => !el.disabled && !el.readOnly && (el.type || '').toLowerCase() !== 'hidden');
|
|
36
|
-
const single = inputs.filter((el) => {
|
|
37
|
-
const ml = el.getAttribute('maxlength') ?? el.getAttribute('maxLength');
|
|
38
|
-
const n = ml === null || ml === undefined ? NaN : Number(ml);
|
|
39
|
-
return n === 1;
|
|
40
|
-
});
|
|
41
|
-
// A segmented OTP widget: at least 4 single-char inputs, or an explicit
|
|
42
|
-
// one-time-code input with siblings of the same shape.
|
|
43
|
-
let group = [];
|
|
44
|
-
if (single.length >= 4) {
|
|
45
|
-
// Keep the largest run of adjacent single-char inputs in DOM order.
|
|
46
|
-
group = single;
|
|
47
|
-
} else {
|
|
48
|
-
const otpish = inputs.filter((el) => {
|
|
49
|
-
const ac = (el.getAttribute('autocomplete') || '').toLowerCase();
|
|
50
|
-
if (ac === 'one-time-code') return true;
|
|
51
|
-
const hint = [el.getAttribute('name'), el.id, el.getAttribute('aria-label')].filter(Boolean).join(' ');
|
|
52
|
-
return /otp|one[- ]?time|verif|code/i.test(hint);
|
|
53
|
-
});
|
|
54
|
-
if (otpish.length >= 4) group = otpish;
|
|
55
|
-
else if (otpish.length === 1 && single.length >= 2) group = [otpish[0], ...single.filter((el) => el !== otpish[0])];
|
|
56
|
-
}
|
|
57
|
-
if (group.length < 4) return null;
|
|
58
|
-
// Sort by on-screen position (top then left) so auto-advance order is right.
|
|
59
|
-
group = group.slice().sort((a, b) => {
|
|
60
|
-
const ra = a.getBoundingClientRect();
|
|
61
|
-
const rb = b.getBoundingClientRect();
|
|
62
|
-
if (Math.abs(ra.y - rb.y) > ra.height / 2) return ra.y - rb.y;
|
|
63
|
-
return ra.x - rb.x;
|
|
64
|
-
});
|
|
65
|
-
group.forEach((el, i) => el.setAttribute('data-ts-otp', String(i)));
|
|
66
|
-
return {
|
|
67
|
-
length: group.length,
|
|
68
|
-
tags: group.map((el) => String(el.tagName || '').toLowerCase()),
|
|
69
|
-
modal: scope !== document,
|
|
70
|
-
values: group.map((el) => typeof el.value === 'string' ? el.value : ''),
|
|
71
|
-
};
|
|
21
|
+
const FILL_OTP_JS = `(() => {
|
|
22
|
+
const vis = (el) => {
|
|
23
|
+
if (!el) return false;
|
|
24
|
+
const r = el.getBoundingClientRect();
|
|
25
|
+
if (r.width === 0 || r.height === 0) return false;
|
|
26
|
+
const cs = getComputedStyle(el);
|
|
27
|
+
return cs.visibility !== 'hidden' && cs.display !== 'none' && cs.opacity !== '0';
|
|
28
|
+
};
|
|
29
|
+
const dialogSel = 'dialog[open],[role="dialog"],[aria-modal="true"],' +
|
|
30
|
+
'[class*="modal"],[class*="Modal"],[class*="dialog"],[class*="Dialog"]';
|
|
31
|
+
const dialogs = [...document.querySelectorAll(dialogSel)].filter(vis);
|
|
32
|
+
const scope = dialogs.length ? dialogs[dialogs.length - 1] : document;
|
|
33
|
+
const inputs = [...scope.querySelectorAll('input')]
|
|
34
|
+
.filter(vis)
|
|
35
|
+
.filter((el) => !el.disabled && !el.readOnly && (el.type || '').toLowerCase() !== 'hidden');
|
|
36
|
+
const single = inputs.filter((el) => {
|
|
37
|
+
const ml = el.getAttribute('maxlength') ?? el.getAttribute('maxLength');
|
|
38
|
+
const n = ml === null || ml === undefined ? NaN : Number(ml);
|
|
39
|
+
return n === 1;
|
|
40
|
+
});
|
|
41
|
+
// A segmented OTP widget: at least 4 single-char inputs, or an explicit
|
|
42
|
+
// one-time-code input with siblings of the same shape.
|
|
43
|
+
let group = [];
|
|
44
|
+
if (single.length >= 4) {
|
|
45
|
+
// Keep the largest run of adjacent single-char inputs in DOM order.
|
|
46
|
+
group = single;
|
|
47
|
+
} else {
|
|
48
|
+
const otpish = inputs.filter((el) => {
|
|
49
|
+
const ac = (el.getAttribute('autocomplete') || '').toLowerCase();
|
|
50
|
+
if (ac === 'one-time-code') return true;
|
|
51
|
+
const hint = [el.getAttribute('name'), el.id, el.getAttribute('aria-label')].filter(Boolean).join(' ');
|
|
52
|
+
return /otp|one[- ]?time|verif|code/i.test(hint);
|
|
53
|
+
});
|
|
54
|
+
if (otpish.length >= 4) group = otpish;
|
|
55
|
+
else if (otpish.length === 1 && single.length >= 2) group = [otpish[0], ...single.filter((el) => el !== otpish[0])];
|
|
56
|
+
}
|
|
57
|
+
if (group.length < 4) return null;
|
|
58
|
+
// Sort by on-screen position (top then left) so auto-advance order is right.
|
|
59
|
+
group = group.slice().sort((a, b) => {
|
|
60
|
+
const ra = a.getBoundingClientRect();
|
|
61
|
+
const rb = b.getBoundingClientRect();
|
|
62
|
+
if (Math.abs(ra.y - rb.y) > ra.height / 2) return ra.y - rb.y;
|
|
63
|
+
return ra.x - rb.x;
|
|
64
|
+
});
|
|
65
|
+
group.forEach((el, i) => el.setAttribute('data-ts-otp', String(i)));
|
|
66
|
+
return {
|
|
67
|
+
length: group.length,
|
|
68
|
+
tags: group.map((el) => String(el.tagName || '').toLowerCase()),
|
|
69
|
+
modal: scope !== document,
|
|
70
|
+
values: group.map((el) => typeof el.value === 'string' ? el.value : ''),
|
|
71
|
+
};
|
|
72
72
|
})()`;
|
|
73
73
|
async function detectOtpGroup(page) {
|
|
74
74
|
try {
|
|
@@ -153,15 +153,15 @@ async function typeOtpDigit(page, digit) {
|
|
|
153
153
|
}
|
|
154
154
|
async function visibleOtpError(page) {
|
|
155
155
|
try {
|
|
156
|
-
const v = await (0, cdp_1.evaluateJs)(page, `(() => {
|
|
157
|
-
const sel = '[role="alert"],.error,.text-red-500,.text-destructive,[class*="error" i]';
|
|
158
|
-
const els = [...document.querySelectorAll(sel)].filter((el) => {
|
|
159
|
-
const r = el.getBoundingClientRect();
|
|
160
|
-
if (r.width === 0 || r.height === 0) return false;
|
|
161
|
-
const t = (el.innerText || '').trim();
|
|
162
|
-
return t.length > 0 && t.length < 300;
|
|
163
|
-
});
|
|
164
|
-
return els.length ? els[0].innerText.trim().slice(0, 300) : null;
|
|
156
|
+
const v = await (0, cdp_1.evaluateJs)(page, `(() => {
|
|
157
|
+
const sel = '[role="alert"],.error,.text-red-500,.text-destructive,[class*="error" i]';
|
|
158
|
+
const els = [...document.querySelectorAll(sel)].filter((el) => {
|
|
159
|
+
const r = el.getBoundingClientRect();
|
|
160
|
+
if (r.width === 0 || r.height === 0) return false;
|
|
161
|
+
const t = (el.innerText || '').trim();
|
|
162
|
+
return t.length > 0 && t.length < 300;
|
|
163
|
+
});
|
|
164
|
+
return els.length ? els[0].innerText.trim().slice(0, 300) : null;
|
|
165
165
|
})()`);
|
|
166
166
|
return typeof v === 'string' && v ? v : null;
|
|
167
167
|
}
|
|
@@ -171,18 +171,18 @@ async function visibleOtpError(page) {
|
|
|
171
171
|
}
|
|
172
172
|
async function clickOtpSubmit(page) {
|
|
173
173
|
try {
|
|
174
|
-
const clicked = await (0, cdp_1.evaluateJs)(page, `(() => {
|
|
175
|
-
const scope = document;
|
|
176
|
-
const btns = [...scope.querySelectorAll('button,input[type="submit"],[role="button"]')].filter((el) => {
|
|
177
|
-
const r = el.getBoundingClientRect();
|
|
178
|
-
if (r.width === 0 || r.height === 0) return false;
|
|
179
|
-
if (el.disabled) return false;
|
|
180
|
-
const t = ((el.innerText || el.textContent || el.value || '')).trim();
|
|
181
|
-
return /verify|confirm|continue|submit|next/i.test(t);
|
|
182
|
-
});
|
|
183
|
-
if (!btns.length) return false;
|
|
184
|
-
btns[0].click();
|
|
185
|
-
return true;
|
|
174
|
+
const clicked = await (0, cdp_1.evaluateJs)(page, `(() => {
|
|
175
|
+
const scope = document;
|
|
176
|
+
const btns = [...scope.querySelectorAll('button,input[type="submit"],[role="button"]')].filter((el) => {
|
|
177
|
+
const r = el.getBoundingClientRect();
|
|
178
|
+
if (r.width === 0 || r.height === 0) return false;
|
|
179
|
+
if (el.disabled) return false;
|
|
180
|
+
const t = ((el.innerText || el.textContent || el.value || '')).trim();
|
|
181
|
+
return /verify|confirm|continue|submit|next/i.test(t);
|
|
182
|
+
});
|
|
183
|
+
if (!btns.length) return false;
|
|
184
|
+
btns[0].click();
|
|
185
|
+
return true;
|
|
186
186
|
})()`);
|
|
187
187
|
return clicked === true;
|
|
188
188
|
}
|