teamshare-bridge 0.26.23 → 0.26.24
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/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/human-style.js +32 -32
- package/dist/lib/llm/usage-reader.js +4 -4
- package/dist/lib/orchestrator/worktree.js +118 -50
- package/dist/lib/orchestrator/worktree.js.map +1 -1
- package/dist/lib/workspace/mirror.d.ts +13 -0
- package/dist/lib/workspace/mirror.js +200 -43
- package/dist/lib/workspace/mirror.js.map +1 -1
- package/dist/lib/workspace/workspace-audit.d.ts +2 -2
- package/dist/lib/workspace/workspace-audit.js +27 -17
- package/dist/lib/workspace/workspace-audit.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/git/ensure-excludes.d.ts +0 -5
- package/dist/lib/git/ensure-excludes.js +0 -55
- package/dist/lib/git/ensure-excludes.js.map +0 -1
|
@@ -64,14 +64,14 @@ function installRoot() {
|
|
|
64
64
|
*/
|
|
65
65
|
function verifyInstall() {
|
|
66
66
|
const root = installRoot();
|
|
67
|
-
const script = `
|
|
68
|
-
const mods = ${JSON.stringify(REQUIRED_MODULES)};
|
|
69
|
-
const missing = [];
|
|
70
|
-
for (const m of mods) {
|
|
71
|
-
try { require.resolve(m, { paths: [${JSON.stringify(root)}] }); }
|
|
72
|
-
catch (e) { missing.push({ module: m, error: String(e && e.message || e) }); }
|
|
73
|
-
}
|
|
74
|
-
process.stdout.write(JSON.stringify({ missing }));
|
|
67
|
+
const script = `
|
|
68
|
+
const mods = ${JSON.stringify(REQUIRED_MODULES)};
|
|
69
|
+
const missing = [];
|
|
70
|
+
for (const m of mods) {
|
|
71
|
+
try { require.resolve(m, { paths: [${JSON.stringify(root)}] }); }
|
|
72
|
+
catch (e) { missing.push({ module: m, error: String(e && e.message || e) }); }
|
|
73
|
+
}
|
|
74
|
+
process.stdout.write(JSON.stringify({ missing }));
|
|
75
75
|
`;
|
|
76
76
|
const res = (0, node_child_process_1.spawnSync)(process.execPath, ['-e', script], {
|
|
77
77
|
stdio: ['ignore', 'pipe', 'pipe'],
|
package/dist/lib/agent-scope.js
CHANGED
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
20
|
exports.AGENT_SCOPE_BLOCK_LIGHT = exports.AGENT_SCOPE_BLOCK = void 0;
|
|
21
21
|
/** Full contract: task runs and tool/research runs. */
|
|
22
|
-
exports.AGENT_SCOPE_BLOCK = `## Your scope (read before acting)
|
|
23
|
-
|
|
24
|
-
You are here to do THIS task, not to operate TeamShare.
|
|
25
|
-
|
|
26
|
-
- In scope: the target system named in this brief, and the \`teamshare\` MCP tools this brief lists. Nothing else.
|
|
27
|
-
- You are NOT the operator of TeamShare, the bridge, the daemon, MCP, the API or this machine. Never debug, repair, restart or inspect them, even when a tool fails.
|
|
28
|
-
- Never read or print a credential: \`~/.teamshare/...\`, \`~/.config/opencode/...\`, session or config files, \`ts_...\` keys, \`X-Api-Key\` or \`X-TeamShare-*\` headers. Never run \`teamshare-agent\`, \`teamshare-bridge\` or \`opencode\`, and never call the TeamShare API by hand.
|
|
29
|
-
- If a TeamShare tool fails, retry it ONCE. If it fails again the run is BLOCKED: call \`ask_human\` (or submit a \`blocked\` report when the report path still works), name the tool and the exact error, and STOP.
|
|
22
|
+
exports.AGENT_SCOPE_BLOCK = `## Your scope (read before acting)
|
|
23
|
+
|
|
24
|
+
You are here to do THIS task, not to operate TeamShare.
|
|
25
|
+
|
|
26
|
+
- In scope: the target system named in this brief, and the \`teamshare\` MCP tools this brief lists. Nothing else.
|
|
27
|
+
- You are NOT the operator of TeamShare, the bridge, the daemon, MCP, the API or this machine. Never debug, repair, restart or inspect them, even when a tool fails.
|
|
28
|
+
- Never read or print a credential: \`~/.teamshare/...\`, \`~/.config/opencode/...\`, session or config files, \`ts_...\` keys, \`X-Api-Key\` or \`X-TeamShare-*\` headers. Never run \`teamshare-agent\`, \`teamshare-bridge\` or \`opencode\`, and never call the TeamShare API by hand.
|
|
29
|
+
- If a TeamShare tool fails, retry it ONCE. If it fails again the run is BLOCKED: call \`ask_human\` (or submit a \`blocked\` report when the report path still works), name the tool and the exact error, and STOP.
|
|
30
30
|
- An infrastructure failure is a blocker to report, never work to do.`;
|
|
31
31
|
/** Short form for conversational paths (chat/doc/board/blog/workflow author). */
|
|
32
|
-
exports.AGENT_SCOPE_BLOCK_LIGHT = `## Scope
|
|
33
|
-
|
|
32
|
+
exports.AGENT_SCOPE_BLOCK_LIGHT = `## Scope
|
|
33
|
+
|
|
34
34
|
Do the task; do not operate the platform. Never read or print keys or config (\`~/.teamshare\`, \`~/.config/opencode\`), never run \`teamshare-agent\`/\`teamshare-bridge\`/\`opencode\`, and never call the TeamShare API by hand. If a TeamShare tool fails twice, report the blocker with \`ask_human\` and stop.`;
|
|
35
35
|
//# sourceMappingURL=agent-scope.js.map
|
|
@@ -91,27 +91,27 @@ sessionId) {
|
|
|
91
91
|
}
|
|
92
92
|
// Ask the LLM to judge
|
|
93
93
|
console.log(`[browse] Code is ${matchPercent}% similar — asking LLM to judge...`);
|
|
94
|
-
const prompt = `You are a code comparison expert. Two versions of code are provided.
|
|
95
|
-
|
|
96
|
-
CURRENT editor content (truncated to first 500 chars):
|
|
97
|
-
\`\`\`
|
|
98
|
-
${currentContent.slice(0, 500)}
|
|
99
|
-
\`\`\`
|
|
100
|
-
|
|
101
|
-
TARGET code to write (truncated to first 500 chars):
|
|
102
|
-
\`\`\`
|
|
103
|
-
${targetCode.slice(0, 500)}
|
|
104
|
-
\`\`\`
|
|
105
|
-
|
|
106
|
-
The user wants to write the TARGET code into the editor.
|
|
107
|
-
|
|
108
|
-
TASK: Compare these two code versions. Are they semantically the same (same logic, same algorithm)? Ignore whitespace, formatting, variable naming differences. Focus on LOGIC.
|
|
109
|
-
|
|
110
|
-
Return EXACTLY one JSON object:
|
|
111
|
-
- {"decision":"skip","reason":"..."} — if the current code is already correct (same logic)
|
|
112
|
-
- {"decision":"partial","reason":"..."} — if mostly correct, only small changes needed
|
|
113
|
-
- {"decision":"full","reason":"..."} — if completely different code is needed
|
|
114
|
-
|
|
94
|
+
const prompt = `You are a code comparison expert. Two versions of code are provided.
|
|
95
|
+
|
|
96
|
+
CURRENT editor content (truncated to first 500 chars):
|
|
97
|
+
\`\`\`
|
|
98
|
+
${currentContent.slice(0, 500)}
|
|
99
|
+
\`\`\`
|
|
100
|
+
|
|
101
|
+
TARGET code to write (truncated to first 500 chars):
|
|
102
|
+
\`\`\`
|
|
103
|
+
${targetCode.slice(0, 500)}
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
The user wants to write the TARGET code into the editor.
|
|
107
|
+
|
|
108
|
+
TASK: Compare these two code versions. Are they semantically the same (same logic, same algorithm)? Ignore whitespace, formatting, variable naming differences. Focus on LOGIC.
|
|
109
|
+
|
|
110
|
+
Return EXACTLY one JSON object:
|
|
111
|
+
- {"decision":"skip","reason":"..."} — if the current code is already correct (same logic)
|
|
112
|
+
- {"decision":"partial","reason":"..."} — if mostly correct, only small changes needed
|
|
113
|
+
- {"decision":"full","reason":"..."} — if completely different code is needed
|
|
114
|
+
|
|
115
115
|
Return ONLY the JSON. No other text.`;
|
|
116
116
|
try {
|
|
117
117
|
let content;
|
|
@@ -805,27 +805,27 @@ sessionId) {
|
|
|
805
805
|
}
|
|
806
806
|
if (!screenChanged) {
|
|
807
807
|
try {
|
|
808
|
-
const flagResult = await (0, browse_cdp_1.cdpEval)(page, `
|
|
809
|
-
(() => {
|
|
810
|
-
const syms = Object.getOwnPropertySymbols(window);
|
|
811
|
-
for (const s of syms) {
|
|
812
|
-
if (s.description === '__ts_obs') return window[s]?.changed || 0;
|
|
813
|
-
}
|
|
814
|
-
return 0;
|
|
815
|
-
})()
|
|
808
|
+
const flagResult = await (0, browse_cdp_1.cdpEval)(page, `
|
|
809
|
+
(() => {
|
|
810
|
+
const syms = Object.getOwnPropertySymbols(window);
|
|
811
|
+
for (const s of syms) {
|
|
812
|
+
if (s.description === '__ts_obs') return window[s]?.changed || 0;
|
|
813
|
+
}
|
|
814
|
+
return 0;
|
|
815
|
+
})()
|
|
816
816
|
`);
|
|
817
817
|
const flagTs = flagResult?.result?.value;
|
|
818
818
|
if (flagTs && flagTs > startTime) {
|
|
819
819
|
screenChanged = true;
|
|
820
820
|
console.log(`[browse] DOM mutation detected (${elapsed}s) — aborting LLM`);
|
|
821
821
|
// Reset flag
|
|
822
|
-
await (0, browse_cdp_1.cdpEval)(page, `
|
|
823
|
-
(() => {
|
|
824
|
-
const syms = Object.getOwnPropertySymbols(window);
|
|
825
|
-
for (const s of syms) {
|
|
826
|
-
if (s.description === '__ts_obs') { window[s].changed = 0; return; }
|
|
827
|
-
}
|
|
828
|
-
})()
|
|
822
|
+
await (0, browse_cdp_1.cdpEval)(page, `
|
|
823
|
+
(() => {
|
|
824
|
+
const syms = Object.getOwnPropertySymbols(window);
|
|
825
|
+
for (const s of syms) {
|
|
826
|
+
if (s.description === '__ts_obs') { window[s].changed = 0; return; }
|
|
827
|
+
}
|
|
828
|
+
})()
|
|
829
829
|
`);
|
|
830
830
|
}
|
|
831
831
|
}
|
|
@@ -1112,14 +1112,14 @@ sessionId) {
|
|
|
1112
1112
|
return;
|
|
1113
1113
|
}
|
|
1114
1114
|
try {
|
|
1115
|
-
const flagResult = await (0, browse_cdp_1.cdpEval)(page, `
|
|
1116
|
-
(() => {
|
|
1117
|
-
const syms = Object.getOwnPropertySymbols(window);
|
|
1118
|
-
for (const s of syms) {
|
|
1119
|
-
if (s.description === '__ts_obs') return window[s]?.changed || 0;
|
|
1120
|
-
}
|
|
1121
|
-
return 0;
|
|
1122
|
-
})()
|
|
1115
|
+
const flagResult = await (0, browse_cdp_1.cdpEval)(page, `
|
|
1116
|
+
(() => {
|
|
1117
|
+
const syms = Object.getOwnPropertySymbols(window);
|
|
1118
|
+
for (const s of syms) {
|
|
1119
|
+
if (s.description === '__ts_obs') return window[s]?.changed || 0;
|
|
1120
|
+
}
|
|
1121
|
+
return 0;
|
|
1122
|
+
})()
|
|
1123
1123
|
`);
|
|
1124
1124
|
const flagTs = flagResult?.result?.value;
|
|
1125
1125
|
if (flagTs && flagTs > startTime) {
|
|
@@ -171,12 +171,12 @@ class TypingGuard {
|
|
|
171
171
|
async markOwn(char, key) {
|
|
172
172
|
if (!this.enabled || this.osLevel || this.stoppedFlag)
|
|
173
173
|
return;
|
|
174
|
-
await (0, cdp_1.evaluateJs)(this.page, `(() => {
|
|
175
|
-
const s = window[${JSON.stringify(this.key)}];
|
|
176
|
-
if (!s) return false;
|
|
177
|
-
s.exp = { ch: ${JSON.stringify(char)}, key: ${JSON.stringify(key ?? '')} };
|
|
178
|
-
s.until = performance.now() + ${OS_BRACKET_MS};
|
|
179
|
-
return true;
|
|
174
|
+
await (0, cdp_1.evaluateJs)(this.page, `(() => {
|
|
175
|
+
const s = window[${JSON.stringify(this.key)}];
|
|
176
|
+
if (!s) return false;
|
|
177
|
+
s.exp = { ch: ${JSON.stringify(char)}, key: ${JSON.stringify(key ?? '')} };
|
|
178
|
+
s.until = performance.now() + ${OS_BRACKET_MS};
|
|
179
|
+
return true;
|
|
180
180
|
})()`).catch(() => false);
|
|
181
181
|
}
|
|
182
182
|
async dispose() {
|
|
@@ -184,20 +184,20 @@ class TypingGuard {
|
|
|
184
184
|
return;
|
|
185
185
|
const key = this.key;
|
|
186
186
|
this.key = '';
|
|
187
|
-
await (0, cdp_1.evaluateJs)(this.page, `(() => {
|
|
188
|
-
const s = window[${JSON.stringify(key)}];
|
|
189
|
-
if (s) {
|
|
190
|
-
if (s.el && s.handler) s.el.removeEventListener('keydown', s.handler, true);
|
|
191
|
-
if (s.el && s.handler) s.el.removeEventListener('input', s.handler, true);
|
|
192
|
-
if (document && s.handler) {
|
|
193
|
-
document.removeEventListener('keydown', s.handler, true);
|
|
194
|
-
document.removeEventListener('beforeinput', s.handler, true);
|
|
195
|
-
document.removeEventListener('input', s.handler, true);
|
|
196
|
-
document.removeEventListener('paste', s.handler, true);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
try { delete window[${JSON.stringify(key)}]; } catch (e) {}
|
|
200
|
-
return true;
|
|
187
|
+
await (0, cdp_1.evaluateJs)(this.page, `(() => {
|
|
188
|
+
const s = window[${JSON.stringify(key)}];
|
|
189
|
+
if (s) {
|
|
190
|
+
if (s.el && s.handler) s.el.removeEventListener('keydown', s.handler, true);
|
|
191
|
+
if (s.el && s.handler) s.el.removeEventListener('input', s.handler, true);
|
|
192
|
+
if (document && s.handler) {
|
|
193
|
+
document.removeEventListener('keydown', s.handler, true);
|
|
194
|
+
document.removeEventListener('beforeinput', s.handler, true);
|
|
195
|
+
document.removeEventListener('input', s.handler, true);
|
|
196
|
+
document.removeEventListener('paste', s.handler, true);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
try { delete window[${JSON.stringify(key)}]; } catch (e) {}
|
|
200
|
+
return true;
|
|
201
201
|
})()`).catch(() => false);
|
|
202
202
|
}
|
|
203
203
|
fail(reason) {
|
|
@@ -228,95 +228,95 @@ class TypingGuard {
|
|
|
228
228
|
buildInstallScript(target, key) {
|
|
229
229
|
const selector = JSON.stringify(target.selector ?? '');
|
|
230
230
|
const isEditor = target.isCodeEditor === true;
|
|
231
|
-
return `(() => {
|
|
232
|
-
const KEY = ${JSON.stringify(key)};
|
|
233
|
-
const findEl = () => {
|
|
234
|
-
const sel = ${selector};
|
|
235
|
-
if (sel) { try { const e = document.querySelector(sel); if (e) return e; } catch (err) {} }
|
|
236
|
-
const a = document.activeElement;
|
|
237
|
-
if (a && a !== document.body) return a;
|
|
238
|
-
return document.body;
|
|
239
|
-
};
|
|
240
|
-
const readText = (el) => {
|
|
241
|
-
try {
|
|
242
|
-
const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
|
|
243
|
-
const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
|
|
244
|
-
if (${isEditor} && editors && editors.length) return editors[editors.length - 1].getValue();
|
|
245
|
-
const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
|
|
246
|
-
if (${isEditor} && cm6 && (cm6 === el || cm6.contains(el))) return cm6.innerText || '';
|
|
247
|
-
const cm5 = document.querySelector('.CodeMirror');
|
|
248
|
-
if (${isEditor} && cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
|
|
249
|
-
const ace = document.querySelector('.ace_editor');
|
|
250
|
-
if (${isEditor} && ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
|
|
251
|
-
} catch (err) {}
|
|
252
|
-
if (!el) return '';
|
|
253
|
-
if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') return el.value || '';
|
|
254
|
-
return el.innerText || el.textContent || '';
|
|
255
|
-
};
|
|
256
|
-
const el = findEl();
|
|
257
|
-
const state = { ext: false, info: '', exp: null, until: 0, el: el, handler: null };
|
|
258
|
-
const describe = (ev) => {
|
|
259
|
-
const t = ev.target && ev.target.tagName ? ev.target.tagName : '?';
|
|
260
|
-
const k = ev.key || ev.data || ev.inputType || ev.type;
|
|
261
|
-
return ev.type + ':' + t + ':' + String(k).slice(0, 24);
|
|
262
|
-
};
|
|
263
|
-
const handler = (ev) => {
|
|
264
|
-
const s = window[KEY];
|
|
265
|
-
if (!s) return;
|
|
266
|
-
// Only events ON the guarded field (or inside it) count. A keystroke in
|
|
267
|
-
// another field, a tab-switch key or any global shortcut must never stop
|
|
268
|
-
// the stream — that was a real false stop. When the guard fell back to
|
|
269
|
-
// <body> we cannot scope, so we do not filter.
|
|
270
|
-
const t = ev.target;
|
|
271
|
-
const guarded = s.el;
|
|
272
|
-
const scoped = guarded && guarded !== document.body && guarded !== document.documentElement;
|
|
273
|
-
if (scoped && t && t !== guarded && !(guarded.contains && guarded.contains(t))) return;
|
|
274
|
-
const now = performance.now();
|
|
275
|
-
if (s.exp && now <= s.until) {
|
|
276
|
-
const k = ev.key || '';
|
|
277
|
-
const d = ev.data || '';
|
|
278
|
-
if ((s.exp.ch && d === s.exp.ch) || (s.exp.key && k === s.exp.key) || (s.exp.ch && k === s.exp.ch)) {
|
|
279
|
-
s.exp = null;
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
s.ext = true;
|
|
284
|
-
s.info = describe(ev);
|
|
285
|
-
};
|
|
286
|
-
state.handler = handler;
|
|
287
|
-
Object.defineProperty(window, KEY, { value: state, enumerable: false, configurable: true });
|
|
288
|
-
document.addEventListener('keydown', handler, true);
|
|
289
|
-
document.addEventListener('beforeinput', handler, true);
|
|
290
|
-
document.addEventListener('input', handler, true);
|
|
291
|
-
document.addEventListener('paste', handler, true);
|
|
292
|
-
return { text: readText(el) };
|
|
231
|
+
return `(() => {
|
|
232
|
+
const KEY = ${JSON.stringify(key)};
|
|
233
|
+
const findEl = () => {
|
|
234
|
+
const sel = ${selector};
|
|
235
|
+
if (sel) { try { const e = document.querySelector(sel); if (e) return e; } catch (err) {} }
|
|
236
|
+
const a = document.activeElement;
|
|
237
|
+
if (a && a !== document.body) return a;
|
|
238
|
+
return document.body;
|
|
239
|
+
};
|
|
240
|
+
const readText = (el) => {
|
|
241
|
+
try {
|
|
242
|
+
const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
|
|
243
|
+
const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
|
|
244
|
+
if (${isEditor} && editors && editors.length) return editors[editors.length - 1].getValue();
|
|
245
|
+
const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
|
|
246
|
+
if (${isEditor} && cm6 && (cm6 === el || cm6.contains(el))) return cm6.innerText || '';
|
|
247
|
+
const cm5 = document.querySelector('.CodeMirror');
|
|
248
|
+
if (${isEditor} && cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
|
|
249
|
+
const ace = document.querySelector('.ace_editor');
|
|
250
|
+
if (${isEditor} && ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
|
|
251
|
+
} catch (err) {}
|
|
252
|
+
if (!el) return '';
|
|
253
|
+
if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') return el.value || '';
|
|
254
|
+
return el.innerText || el.textContent || '';
|
|
255
|
+
};
|
|
256
|
+
const el = findEl();
|
|
257
|
+
const state = { ext: false, info: '', exp: null, until: 0, el: el, handler: null };
|
|
258
|
+
const describe = (ev) => {
|
|
259
|
+
const t = ev.target && ev.target.tagName ? ev.target.tagName : '?';
|
|
260
|
+
const k = ev.key || ev.data || ev.inputType || ev.type;
|
|
261
|
+
return ev.type + ':' + t + ':' + String(k).slice(0, 24);
|
|
262
|
+
};
|
|
263
|
+
const handler = (ev) => {
|
|
264
|
+
const s = window[KEY];
|
|
265
|
+
if (!s) return;
|
|
266
|
+
// Only events ON the guarded field (or inside it) count. A keystroke in
|
|
267
|
+
// another field, a tab-switch key or any global shortcut must never stop
|
|
268
|
+
// the stream — that was a real false stop. When the guard fell back to
|
|
269
|
+
// <body> we cannot scope, so we do not filter.
|
|
270
|
+
const t = ev.target;
|
|
271
|
+
const guarded = s.el;
|
|
272
|
+
const scoped = guarded && guarded !== document.body && guarded !== document.documentElement;
|
|
273
|
+
if (scoped && t && t !== guarded && !(guarded.contains && guarded.contains(t))) return;
|
|
274
|
+
const now = performance.now();
|
|
275
|
+
if (s.exp && now <= s.until) {
|
|
276
|
+
const k = ev.key || '';
|
|
277
|
+
const d = ev.data || '';
|
|
278
|
+
if ((s.exp.ch && d === s.exp.ch) || (s.exp.key && k === s.exp.key) || (s.exp.ch && k === s.exp.ch)) {
|
|
279
|
+
s.exp = null;
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
s.ext = true;
|
|
284
|
+
s.info = describe(ev);
|
|
285
|
+
};
|
|
286
|
+
state.handler = handler;
|
|
287
|
+
Object.defineProperty(window, KEY, { value: state, enumerable: false, configurable: true });
|
|
288
|
+
document.addEventListener('keydown', handler, true);
|
|
289
|
+
document.addEventListener('beforeinput', handler, true);
|
|
290
|
+
document.addEventListener('input', handler, true);
|
|
291
|
+
document.addEventListener('paste', handler, true);
|
|
292
|
+
return { text: readText(el) };
|
|
293
293
|
})()`;
|
|
294
294
|
}
|
|
295
295
|
buildReadScript(key) {
|
|
296
|
-
return `(() => {
|
|
297
|
-
const s = window[${JSON.stringify(key)}];
|
|
298
|
-
if (!s) return null;
|
|
299
|
-
const el = s.el && document.contains(s.el) ? s.el : document.activeElement;
|
|
300
|
-
const read = (e) => {
|
|
301
|
-
try {
|
|
302
|
-
const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
|
|
303
|
-
const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
|
|
304
|
-
if (editors && editors.length) return editors[editors.length - 1].getValue();
|
|
305
|
-
const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
|
|
306
|
-
if (cm6) return cm6.innerText || '';
|
|
307
|
-
const cm5 = document.querySelector('.CodeMirror');
|
|
308
|
-
if (cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
|
|
309
|
-
const ace = document.querySelector('.ace_editor');
|
|
310
|
-
if (ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
|
|
311
|
-
} catch (err) {}
|
|
312
|
-
if (!e) return '';
|
|
313
|
-
if (e.tagName === 'INPUT' || e.tagName === 'TEXTAREA') return e.value || '';
|
|
314
|
-
return e.innerText || e.textContent || '';
|
|
315
|
-
};
|
|
316
|
-
const out = { text: read(el), external: s.ext === true, externalInfo: s.info || '' };
|
|
317
|
-
s.ext = false;
|
|
318
|
-
s.info = '';
|
|
319
|
-
return out;
|
|
296
|
+
return `(() => {
|
|
297
|
+
const s = window[${JSON.stringify(key)}];
|
|
298
|
+
if (!s) return null;
|
|
299
|
+
const el = s.el && document.contains(s.el) ? s.el : document.activeElement;
|
|
300
|
+
const read = (e) => {
|
|
301
|
+
try {
|
|
302
|
+
const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
|
|
303
|
+
const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
|
|
304
|
+
if (editors && editors.length) return editors[editors.length - 1].getValue();
|
|
305
|
+
const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
|
|
306
|
+
if (cm6) return cm6.innerText || '';
|
|
307
|
+
const cm5 = document.querySelector('.CodeMirror');
|
|
308
|
+
if (cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
|
|
309
|
+
const ace = document.querySelector('.ace_editor');
|
|
310
|
+
if (ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
|
|
311
|
+
} catch (err) {}
|
|
312
|
+
if (!e) return '';
|
|
313
|
+
if (e.tagName === 'INPUT' || e.tagName === 'TEXTAREA') return e.value || '';
|
|
314
|
+
return e.innerText || e.textContent || '';
|
|
315
|
+
};
|
|
316
|
+
const out = { text: read(el), external: s.ext === true, externalInfo: s.info || '' };
|
|
317
|
+
s.ext = false;
|
|
318
|
+
s.info = '';
|
|
319
|
+
return out;
|
|
320
320
|
})()`;
|
|
321
321
|
}
|
|
322
322
|
/**
|