teamshare-bridge 0.22.7 → 0.22.8

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 (82) hide show
  1. package/README.md +383 -383
  2. package/dist/bridge/daemon.js +43 -20
  3. package/dist/bridge/daemon.js.map +1 -1
  4. package/dist/bridge/install-verify.js +8 -8
  5. package/dist/bridge/spawn.d.ts +14 -0
  6. package/dist/bridge/spawn.js +7 -1
  7. package/dist/bridge/spawn.js.map +1 -1
  8. package/dist/bridge/wake-handler.d.ts +8 -15
  9. package/dist/bridge/wake-handler.js +109 -14
  10. package/dist/bridge/wake-handler.js.map +1 -1
  11. package/dist/bridge/wake-outbox.js +7 -0
  12. package/dist/bridge/wake-outbox.js.map +1 -1
  13. package/dist/cli/commands/plan.js +4 -0
  14. package/dist/cli/commands/plan.js.map +1 -1
  15. package/dist/lib/browser/human-input-guard.js +98 -98
  16. package/dist/lib/browser/screen-change.js +60 -60
  17. package/dist/lib/llm/usage-reader.js +4 -4
  18. package/dist/lib/workspace/classify.d.ts +29 -0
  19. package/dist/lib/workspace/classify.js +62 -0
  20. package/dist/lib/workspace/classify.js.map +1 -1
  21. package/dist/lib/workspace/presence.d.ts +31 -0
  22. package/dist/lib/workspace/presence.js +35 -1
  23. package/dist/lib/workspace/presence.js.map +1 -1
  24. package/dist/lib/workspace/shim-runner.js +23 -0
  25. package/dist/lib/workspace/shim-runner.js.map +1 -1
  26. package/package.json +70 -70
  27. package/skills/THIRD_PARTY_NOTICES.md +26 -26
  28. package/skills/architect/LICENSE +21 -21
  29. package/skills/codebase-design/LICENSE +21 -21
  30. package/skills/diagnosing-bugs/LICENSE +21 -21
  31. package/skills/domain-modeling/LICENSE +21 -21
  32. package/skills/improve-codebase-architecture/LICENSE +21 -21
  33. package/skills/recover/LICENSE +21 -21
  34. package/skills/review/LICENSE +21 -21
  35. package/skills/tdd/LICENSE +21 -21
  36. package/skills/teamshare-auth-rbac/SKILL.md +78 -78
  37. package/skills/teamshare-cdd/SKILL.md +205 -205
  38. package/skills/teamshare-modularity/SKILL.md +146 -146
  39. package/skills/teamshare-orchestrator-ask/SKILL.md +77 -77
  40. package/skills/teamshare-scaffold/SKILL.md +116 -116
  41. package/templates/backend/.env.example.tpl +13 -13
  42. package/templates/backend/nest-cli.json.tpl +8 -8
  43. package/templates/backend/package.json.tpl +41 -41
  44. package/templates/backend/prisma/schema.prisma.tpl +39 -39
  45. package/templates/backend/src/app.module.ts.tpl +24 -24
  46. package/templates/backend/src/common/filters/all-exceptions.filter.ts.tpl +59 -59
  47. package/templates/backend/src/common/guards/jwt-auth.guard.ts.tpl +27 -27
  48. package/templates/backend/src/common/guards/rbac.guard.ts.tpl +48 -48
  49. package/templates/backend/src/common/interceptors/transform.interceptor.ts.tpl +44 -44
  50. package/templates/backend/src/common/pipes/zod-validation.pipe.ts.tpl +29 -29
  51. package/templates/backend/src/common/swagger/envelope.schemas.ts.tpl +53 -53
  52. package/templates/backend/src/common/swagger/error.schemas.ts.tpl +62 -62
  53. package/templates/backend/src/main.ts.tpl +27 -27
  54. package/templates/backend/src/modules/example/example.controller.ts.tpl +102 -102
  55. package/templates/backend/src/modules/example/example.dto.ts.tpl +14 -14
  56. package/templates/backend/src/modules/example/example.module.ts.tpl +10 -10
  57. package/templates/backend/src/modules/example/example.service.ts.tpl +45 -45
  58. package/templates/backend/tsconfig.json.tpl +26 -26
  59. package/templates/common/.gitignore.tpl +42 -42
  60. package/templates/common/AGENTS.md.tpl +58 -58
  61. package/templates/common/docs/adr/README.md +25 -25
  62. package/templates/common/docs/api-contract.md.tpl +72 -72
  63. package/templates/web/next.config.ts.tpl +7 -7
  64. package/templates/web/package.json.tpl +37 -37
  65. package/templates/web/src/app/globals.css.tpl +48 -48
  66. package/templates/web/src/app/layout.tsx.tpl +25 -25
  67. package/templates/web/src/components/shared/app-button.tsx.tpl +59 -59
  68. package/templates/web/src/components/shared/app-empty-state.tsx.tpl +39 -39
  69. package/templates/web/src/components/shared/app-list-toolbar.tsx.tpl +63 -63
  70. package/templates/web/src/components/shared/app-skeleton.tsx.tpl +14 -14
  71. package/templates/web/src/components/shared/app-table.tsx.tpl +128 -128
  72. package/templates/web/src/components/shared/index.ts.tpl +5 -5
  73. package/templates/web/src/hooks/use-list-state.ts.tpl +72 -72
  74. package/templates/web/src/hooks/use-url-tab.ts.tpl +25 -25
  75. package/templates/web/src/lib/api/client.ts.tpl +123 -123
  76. package/templates/web/src/lib/providers.tsx.tpl +35 -35
  77. package/templates/web/src/lib/query-keys.ts.tpl +21 -21
  78. package/templates/web/src/lib/utils.ts.tpl +7 -7
  79. package/templates/web/src/lib/validation/schemas.ts.tpl +15 -15
  80. package/templates/web/src/modules/example/views/example-list-view.tsx.tpl +97 -97
  81. package/templates/web/tsconfig.json.tpl +23 -23
  82. package/tools/workspace-arbitration-check.mjs +389 -389
@@ -148,12 +148,12 @@ class TypingGuard {
148
148
  async markOwn(char, key) {
149
149
  if (!this.enabled || this.osLevel || this.stoppedFlag)
150
150
  return;
151
- await (0, cdp_1.evaluateJs)(this.page, `(() => {
152
- const s = window[${JSON.stringify(this.key)}];
153
- if (!s) return false;
154
- s.exp = { ch: ${JSON.stringify(char)}, key: ${JSON.stringify(key ?? '')} };
155
- s.until = performance.now() + ${OS_BRACKET_MS};
156
- return true;
151
+ await (0, cdp_1.evaluateJs)(this.page, `(() => {
152
+ const s = window[${JSON.stringify(this.key)}];
153
+ if (!s) return false;
154
+ s.exp = { ch: ${JSON.stringify(char)}, key: ${JSON.stringify(key ?? '')} };
155
+ s.until = performance.now() + ${OS_BRACKET_MS};
156
+ return true;
157
157
  })()`).catch(() => false);
158
158
  }
159
159
  async dispose() {
@@ -161,20 +161,20 @@ class TypingGuard {
161
161
  return;
162
162
  const key = this.key;
163
163
  this.key = '';
164
- await (0, cdp_1.evaluateJs)(this.page, `(() => {
165
- const s = window[${JSON.stringify(key)}];
166
- if (s) {
167
- if (s.el && s.handler) s.el.removeEventListener('keydown', s.handler, true);
168
- if (s.el && s.handler) s.el.removeEventListener('input', s.handler, true);
169
- if (document && s.handler) {
170
- document.removeEventListener('keydown', s.handler, true);
171
- document.removeEventListener('beforeinput', s.handler, true);
172
- document.removeEventListener('input', s.handler, true);
173
- document.removeEventListener('paste', s.handler, true);
174
- }
175
- }
176
- try { delete window[${JSON.stringify(key)}]; } catch (e) {}
177
- return true;
164
+ await (0, cdp_1.evaluateJs)(this.page, `(() => {
165
+ const s = window[${JSON.stringify(key)}];
166
+ if (s) {
167
+ if (s.el && s.handler) s.el.removeEventListener('keydown', s.handler, true);
168
+ if (s.el && s.handler) s.el.removeEventListener('input', s.handler, true);
169
+ if (document && s.handler) {
170
+ document.removeEventListener('keydown', s.handler, true);
171
+ document.removeEventListener('beforeinput', s.handler, true);
172
+ document.removeEventListener('input', s.handler, true);
173
+ document.removeEventListener('paste', s.handler, true);
174
+ }
175
+ }
176
+ try { delete window[${JSON.stringify(key)}]; } catch (e) {}
177
+ return true;
178
178
  })()`).catch(() => false);
179
179
  }
180
180
  fail(reason) {
@@ -204,87 +204,87 @@ class TypingGuard {
204
204
  buildInstallScript(target, key) {
205
205
  const selector = JSON.stringify(target.selector ?? '');
206
206
  const isEditor = target.isCodeEditor === true;
207
- return `(() => {
208
- const KEY = ${JSON.stringify(key)};
209
- const findEl = () => {
210
- const sel = ${selector};
211
- if (sel) { try { const e = document.querySelector(sel); if (e) return e; } catch (err) {} }
212
- const a = document.activeElement;
213
- if (a && a !== document.body) return a;
214
- return document.body;
215
- };
216
- const readText = (el) => {
217
- try {
218
- const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
219
- const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
220
- if (${isEditor} && editors && editors.length) return editors[editors.length - 1].getValue();
221
- const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
222
- if (${isEditor} && cm6 && (cm6 === el || cm6.contains(el))) return cm6.innerText || '';
223
- const cm5 = document.querySelector('.CodeMirror');
224
- if (${isEditor} && cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
225
- const ace = document.querySelector('.ace_editor');
226
- if (${isEditor} && ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
227
- } catch (err) {}
228
- if (!el) return '';
229
- if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') return el.value || '';
230
- return el.innerText || el.textContent || '';
231
- };
232
- const el = findEl();
233
- const state = { ext: false, info: '', exp: null, until: 0, el: el, handler: null };
234
- const describe = (ev) => {
235
- const t = ev.target && ev.target.tagName ? ev.target.tagName : '?';
236
- const k = ev.key || ev.data || ev.inputType || ev.type;
237
- return ev.type + ':' + t + ':' + String(k).slice(0, 24);
238
- };
239
- const handler = (ev) => {
240
- const s = window[KEY];
241
- if (!s) return;
242
- const now = performance.now();
243
- if (s.exp && now <= s.until) {
244
- const k = ev.key || '';
245
- const d = ev.data || '';
246
- if ((s.exp.ch && d === s.exp.ch) || (s.exp.key && k === s.exp.key) || (s.exp.ch && k === s.exp.ch)) {
247
- s.exp = null;
248
- return;
249
- }
250
- }
251
- s.ext = true;
252
- s.info = describe(ev);
253
- };
254
- state.handler = handler;
255
- Object.defineProperty(window, KEY, { value: state, enumerable: false, configurable: true });
256
- document.addEventListener('keydown', handler, true);
257
- document.addEventListener('beforeinput', handler, true);
258
- document.addEventListener('input', handler, true);
259
- document.addEventListener('paste', handler, true);
260
- return { text: readText(el) };
207
+ return `(() => {
208
+ const KEY = ${JSON.stringify(key)};
209
+ const findEl = () => {
210
+ const sel = ${selector};
211
+ if (sel) { try { const e = document.querySelector(sel); if (e) return e; } catch (err) {} }
212
+ const a = document.activeElement;
213
+ if (a && a !== document.body) return a;
214
+ return document.body;
215
+ };
216
+ const readText = (el) => {
217
+ try {
218
+ const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
219
+ const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
220
+ if (${isEditor} && editors && editors.length) return editors[editors.length - 1].getValue();
221
+ const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
222
+ if (${isEditor} && cm6 && (cm6 === el || cm6.contains(el))) return cm6.innerText || '';
223
+ const cm5 = document.querySelector('.CodeMirror');
224
+ if (${isEditor} && cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
225
+ const ace = document.querySelector('.ace_editor');
226
+ if (${isEditor} && ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
227
+ } catch (err) {}
228
+ if (!el) return '';
229
+ if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') return el.value || '';
230
+ return el.innerText || el.textContent || '';
231
+ };
232
+ const el = findEl();
233
+ const state = { ext: false, info: '', exp: null, until: 0, el: el, handler: null };
234
+ const describe = (ev) => {
235
+ const t = ev.target && ev.target.tagName ? ev.target.tagName : '?';
236
+ const k = ev.key || ev.data || ev.inputType || ev.type;
237
+ return ev.type + ':' + t + ':' + String(k).slice(0, 24);
238
+ };
239
+ const handler = (ev) => {
240
+ const s = window[KEY];
241
+ if (!s) return;
242
+ const now = performance.now();
243
+ if (s.exp && now <= s.until) {
244
+ const k = ev.key || '';
245
+ const d = ev.data || '';
246
+ if ((s.exp.ch && d === s.exp.ch) || (s.exp.key && k === s.exp.key) || (s.exp.ch && k === s.exp.ch)) {
247
+ s.exp = null;
248
+ return;
249
+ }
250
+ }
251
+ s.ext = true;
252
+ s.info = describe(ev);
253
+ };
254
+ state.handler = handler;
255
+ Object.defineProperty(window, KEY, { value: state, enumerable: false, configurable: true });
256
+ document.addEventListener('keydown', handler, true);
257
+ document.addEventListener('beforeinput', handler, true);
258
+ document.addEventListener('input', handler, true);
259
+ document.addEventListener('paste', handler, true);
260
+ return { text: readText(el) };
261
261
  })()`;
262
262
  }
263
263
  buildReadScript(key) {
264
- return `(() => {
265
- const s = window[${JSON.stringify(key)}];
266
- if (!s) return null;
267
- const el = s.el && document.contains(s.el) ? s.el : document.activeElement;
268
- const read = (e) => {
269
- try {
270
- const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
271
- const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
272
- if (editors && editors.length) return editors[editors.length - 1].getValue();
273
- const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
274
- if (cm6) return cm6.innerText || '';
275
- const cm5 = document.querySelector('.CodeMirror');
276
- if (cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
277
- const ace = document.querySelector('.ace_editor');
278
- if (ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
279
- } catch (err) {}
280
- if (!e) return '';
281
- if (e.tagName === 'INPUT' || e.tagName === 'TEXTAREA') return e.value || '';
282
- return e.innerText || e.textContent || '';
283
- };
284
- const out = { text: read(el), external: s.ext === true, externalInfo: s.info || '' };
285
- s.ext = false;
286
- s.info = '';
287
- return out;
264
+ return `(() => {
265
+ const s = window[${JSON.stringify(key)}];
266
+ if (!s) return null;
267
+ const el = s.el && document.contains(s.el) ? s.el : document.activeElement;
268
+ const read = (e) => {
269
+ try {
270
+ const monacoNs = typeof monaco !== 'undefined' ? monaco : window.monaco;
271
+ const editors = monacoNs && monacoNs.editor && monacoNs.editor.getEditors ? monacoNs.editor.getEditors() : null;
272
+ if (editors && editors.length) return editors[editors.length - 1].getValue();
273
+ const cm6 = document.querySelector('.cm-content[contenteditable="true"]');
274
+ if (cm6) return cm6.innerText || '';
275
+ const cm5 = document.querySelector('.CodeMirror');
276
+ if (cm5 && cm5.CodeMirror) return cm5.CodeMirror.getValue();
277
+ const ace = document.querySelector('.ace_editor');
278
+ if (ace && ace.env && ace.env.editor) return ace.env.editor.getValue();
279
+ } catch (err) {}
280
+ if (!e) return '';
281
+ if (e.tagName === 'INPUT' || e.tagName === 'TEXTAREA') return e.value || '';
282
+ return e.innerText || e.textContent || '';
283
+ };
284
+ const out = { text: read(el), external: s.ext === true, externalInfo: s.info || '' };
285
+ s.ext = false;
286
+ s.info = '';
287
+ return out;
288
288
  })()`;
289
289
  }
290
290
  /**
@@ -62,66 +62,66 @@ function isMainFrameNavigation(params) {
62
62
  * on the current document.
63
63
  */
64
64
  function buildObserverScript() {
65
- return `
66
- (() => {
67
- const KEY = Symbol('__ts_obs');
68
- if (window[KEY]) return 'already attached';
69
- const IGNORE = /timer|countdown|elapsed|clock|animation|animate|transition|spinner|progress|loading|toast|notification|alert|banner|snackbar|cookie|consent|modal|overlay|popup|tooltip|badge|tag|avatar|icon|svg|img|video|audio|canvas|font|stylesheet|script|meta|link|head/i;
70
- const observerChangeScore = ${observerChangeScore.toString()};
71
- let timer = null;
72
- let lastText = '';
73
- function getText() {
74
- const els = document.querySelectorAll('input[type="radio"],input[type="checkbox"],input[type="text"],input[type="email"],input[type="password"],textarea,label,button');
75
- return [...els].map(e => {
76
- const t = (e.innerText || e.textContent || '').trim().replace(/\\s+/g, ' ').slice(0, 200);
77
- return e.type + '|' + t + '|' + (e.checked || false);
78
- }).join('\\n');
79
- }
80
- function check() {
81
- try {
82
- const curr = getText();
83
- if (curr === lastText) return;
84
- const prev = lastText;
85
- lastText = curr;
86
- if (observerChangeScore(prev, curr) >= ${exports.SCREEN_CHANGE_THRESHOLD}) {
87
- window[KEY].changed = Date.now();
88
- }
89
- } catch {}
90
- }
91
- const obs = new MutationObserver((mutations) => {
92
- let hasRelevant = false;
93
- for (const m of mutations) {
94
- if (m.target instanceof Element) {
95
- const tag = m.target.tagName;
96
- if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'HEAD') continue;
97
- const cls = m.target.className || '';
98
- if (typeof cls === 'string' && IGNORE.test(cls)) continue;
99
- const id = m.target.id || '';
100
- if (IGNORE.test(id)) continue;
101
- if (m.type === 'characterData' && m.target.parentElement) {
102
- const ptag = m.target.parentElement.tagName;
103
- if (ptag === 'SCRIPT' || ptag === 'STYLE') continue;
104
- }
105
- }
106
- hasRelevant = true;
107
- }
108
- if (hasRelevant) {
109
- // Raw "something relevant changed" stamp, set immediately (no
110
- // debounce, no score gate). Used to verify that a click had ANY
111
- // effect, including a selection that scores below the material
112
- // threshold - without waiting for a full question swap.
113
- window[KEY].mutated = Date.now();
114
- clearTimeout(timer);
115
- timer = setTimeout(check, 500);
116
- }
117
- });
118
- lastText = getText();
119
- window[KEY] = { observer: obs, changed: 0, mutated: 0 };
120
- obs.observe(document.body || document.documentElement, {
121
- childList: true, subtree: true, characterData: true
122
- });
123
- return 'ok';
124
- })()
65
+ return `
66
+ (() => {
67
+ const KEY = Symbol('__ts_obs');
68
+ if (window[KEY]) return 'already attached';
69
+ const IGNORE = /timer|countdown|elapsed|clock|animation|animate|transition|spinner|progress|loading|toast|notification|alert|banner|snackbar|cookie|consent|modal|overlay|popup|tooltip|badge|tag|avatar|icon|svg|img|video|audio|canvas|font|stylesheet|script|meta|link|head/i;
70
+ const observerChangeScore = ${observerChangeScore.toString()};
71
+ let timer = null;
72
+ let lastText = '';
73
+ function getText() {
74
+ const els = document.querySelectorAll('input[type="radio"],input[type="checkbox"],input[type="text"],input[type="email"],input[type="password"],textarea,label,button');
75
+ return [...els].map(e => {
76
+ const t = (e.innerText || e.textContent || '').trim().replace(/\\s+/g, ' ').slice(0, 200);
77
+ return e.type + '|' + t + '|' + (e.checked || false);
78
+ }).join('\\n');
79
+ }
80
+ function check() {
81
+ try {
82
+ const curr = getText();
83
+ if (curr === lastText) return;
84
+ const prev = lastText;
85
+ lastText = curr;
86
+ if (observerChangeScore(prev, curr) >= ${exports.SCREEN_CHANGE_THRESHOLD}) {
87
+ window[KEY].changed = Date.now();
88
+ }
89
+ } catch {}
90
+ }
91
+ const obs = new MutationObserver((mutations) => {
92
+ let hasRelevant = false;
93
+ for (const m of mutations) {
94
+ if (m.target instanceof Element) {
95
+ const tag = m.target.tagName;
96
+ if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'HEAD') continue;
97
+ const cls = m.target.className || '';
98
+ if (typeof cls === 'string' && IGNORE.test(cls)) continue;
99
+ const id = m.target.id || '';
100
+ if (IGNORE.test(id)) continue;
101
+ if (m.type === 'characterData' && m.target.parentElement) {
102
+ const ptag = m.target.parentElement.tagName;
103
+ if (ptag === 'SCRIPT' || ptag === 'STYLE') continue;
104
+ }
105
+ }
106
+ hasRelevant = true;
107
+ }
108
+ if (hasRelevant) {
109
+ // Raw "something relevant changed" stamp, set immediately (no
110
+ // debounce, no score gate). Used to verify that a click had ANY
111
+ // effect, including a selection that scores below the material
112
+ // threshold - without waiting for a full question swap.
113
+ window[KEY].mutated = Date.now();
114
+ clearTimeout(timer);
115
+ timer = setTimeout(check, 500);
116
+ }
117
+ });
118
+ lastText = getText();
119
+ window[KEY] = { observer: obs, changed: 0, mutated: 0 };
120
+ obs.observe(document.body || document.documentElement, {
121
+ childList: true, subtree: true, characterData: true
122
+ });
123
+ return 'ok';
124
+ })()
125
125
  `;
126
126
  }
127
127
  //# sourceMappingURL=screen-change.js.map
@@ -72,10 +72,10 @@ function readOpencode(dbPath, day, agentFilter) {
72
72
  const db = new Database(dbPath, { readonly: true, fileMustExist: true });
73
73
  try {
74
74
  const { startMs, endMs } = dayBounds(day);
75
- const rows = db.prepare(`SELECT title, model, cost, tokens_input, tokens_output,
76
- tokens_reasoning, tokens_cache_read, tokens_cache_write,
77
- time_created, time_updated
78
- FROM session WHERE time_created >= ? AND time_created < ?
75
+ const rows = db.prepare(`SELECT title, model, cost, tokens_input, tokens_output,
76
+ tokens_reasoning, tokens_cache_read, tokens_cache_write,
77
+ time_created, time_updated
78
+ FROM session WHERE time_created >= ? AND time_created < ?
79
79
  ORDER BY time_created`).all(startMs, endMs);
80
80
  const sessions = [];
81
81
  for (const row of rows) {
@@ -30,3 +30,32 @@ export interface Classification {
30
30
  * passthrough.
31
31
  */
32
32
  export declare function classifyCommand(commandLine: string): Classification;
33
+ /**
34
+ * Why a command must not run in a READ-ONLY session, or null if it may (2026-10).
35
+ *
36
+ * ── WHY `cls.cls === 'exclusive'` IS NOT THE TEST ────────────────────────────
37
+ *
38
+ * The instinct is "exclusive means mutating, so refuse exclusive". That misses
39
+ * half of what actually writes: `git add`, `git commit`, `git push`, `git tag`
40
+ * and `git stash` are all classified **shared** (index.lock serializes them
41
+ * against other git writers, which is all that classification is about) and all
42
+ * of them mutate the working tree or the branch. A planning pass runs in the
43
+ * human's own linked folder, so "it got a shared classification" is not
44
+ * permission to commit on their branch.
45
+ *
46
+ * The rule this implements is the user's, stated as an invariant: **a plan must
47
+ * not have intrusive work.** Planning persists its deliverable over MCP
48
+ * (description, acceptance criteria, subtasks, checklist, a `plan.md` note) and
49
+ * reads the tree; it never needs to write to it. Because the bridge no longer
50
+ * serializes planning passes against each other (`NON_BLOCKING_PRESENCE_KINDS`),
51
+ * this is what makes that safe — the pass cannot touch the tree it shares.
52
+ *
53
+ * Deliberately a REFUSAL, not a queue. A shim that waited would hand an agent a
54
+ * command that succeeds minutes later, long after it reasoned about the tree; a
55
+ * refusal with a reason is something a planning agent can immediately adapt to
56
+ * ("use update_task instead").
57
+ *
58
+ * Shared commands that only read stay allowed, so a plan can still `git
59
+ * status`/`git log`/`git diff` and run read-only checks.
60
+ */
61
+ export declare function readOnlyRefusal(commandLine: string, cls: Classification): string | null;
@@ -12,6 +12,7 @@
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.classifyCommand = classifyCommand;
15
+ exports.readOnlyRefusal = readOnlyRefusal;
15
16
  const BUILD_SCRIPTS = new Set([
16
17
  'build', 'compile', 'dist', 'package', 'generate', 'gen', 'prisma',
17
18
  'migrate', 'seed', 'db:', 'prepare', 'prepack', 'postinstall', 'clean',
@@ -181,6 +182,67 @@ function classifyPrisma(rest) {
181
182
  ...(needsGlobal ? { global: ['prisma-generate'] } : {}),
182
183
  };
183
184
  }
185
+ /**
186
+ * Why a command must not run in a READ-ONLY session, or null if it may (2026-10).
187
+ *
188
+ * ── WHY `cls.cls === 'exclusive'` IS NOT THE TEST ────────────────────────────
189
+ *
190
+ * The instinct is "exclusive means mutating, so refuse exclusive". That misses
191
+ * half of what actually writes: `git add`, `git commit`, `git push`, `git tag`
192
+ * and `git stash` are all classified **shared** (index.lock serializes them
193
+ * against other git writers, which is all that classification is about) and all
194
+ * of them mutate the working tree or the branch. A planning pass runs in the
195
+ * human's own linked folder, so "it got a shared classification" is not
196
+ * permission to commit on their branch.
197
+ *
198
+ * The rule this implements is the user's, stated as an invariant: **a plan must
199
+ * not have intrusive work.** Planning persists its deliverable over MCP
200
+ * (description, acceptance criteria, subtasks, checklist, a `plan.md` note) and
201
+ * reads the tree; it never needs to write to it. Because the bridge no longer
202
+ * serializes planning passes against each other (`NON_BLOCKING_PRESENCE_KINDS`),
203
+ * this is what makes that safe — the pass cannot touch the tree it shares.
204
+ *
205
+ * Deliberately a REFUSAL, not a queue. A shim that waited would hand an agent a
206
+ * command that succeeds minutes later, long after it reasoned about the tree; a
207
+ * refusal with a reason is something a planning agent can immediately adapt to
208
+ * ("use update_task instead").
209
+ *
210
+ * Shared commands that only read stay allowed, so a plan can still `git
211
+ * status`/`git log`/`git diff` and run read-only checks.
212
+ */
213
+ function readOnlyRefusal(commandLine, cls) {
214
+ // Everything already known to rewrite tree/branch/install state.
215
+ if (cls.cls === 'exclusive')
216
+ return cls.label;
217
+ const { bin, rest } = base(commandLine);
218
+ if (bin !== 'git')
219
+ return null;
220
+ const sub = (rest[0] ?? '').toLowerCase();
221
+ const args = rest.slice(1).map((a) => a.toLowerCase());
222
+ if (GIT_WRITE_SUBS.has(sub)) {
223
+ // `git branch` only writes with -d/-D/-m/-M; `git stash` only writes for
224
+ // anything other than list/show. Both are read in their common form.
225
+ if (sub === 'branch' && !args.some((a) => ['-d', '-D', '-m', '-M', '--delete', '--move'].includes(a))) {
226
+ return null;
227
+ }
228
+ if (sub === 'stash' && args[0] && ['list', 'show'].includes(args[0])) {
229
+ return null;
230
+ }
231
+ // A BARE `git stash` saves the working tree, so it is a write with no flag to
232
+ // carve it out - unlike `classifyGit`, which treats it as shared.
233
+ return `git ${sub}`;
234
+ }
235
+ if (GIT_WRITE_SUBS_ALWAYS.has(sub))
236
+ return `git ${sub}`;
237
+ return null;
238
+ }
239
+ /**
240
+ * git subcommands classified `shared` (so they run concurrently) that STILL
241
+ * write. See {@link readOnlyRefusal}.
242
+ */
243
+ const GIT_WRITE_SUBS = new Set(['add', 'commit', 'push', 'tag', 'branch', 'stash']);
244
+ /** Write in every form — no read-only invocation to carve out. */
245
+ const GIT_WRITE_SUBS_ALWAYS = new Set(['update-ref', 'notes', 'am']);
184
246
  function classifyGit(rest) {
185
247
  const sub = (rest[0] ?? '').toLowerCase();
186
248
  if (GIT_EXCLUSIVE.has(sub))
@@ -1 +1 @@
1
- {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../src/lib/workspace/classify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../src/lib/workspace/classify.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,37 @@ export declare function listPresent(path: string): PresenceEntry[];
30
30
  export declare function registerPresence(path: string, info?: Omit<PresenceEntry, 'pid' | 'startedAt' | 'updatedAt'>): void;
31
31
  /** Remove THIS process from the folder's registry. */
32
32
  export declare function unregisterPresence(path: string): void;
33
+ /**
34
+ * Kinds that occupy a folder WITHOUT excluding anyone (2026-10).
35
+ *
36
+ * ── WHY A PLAN PASS IS NOT AN OCCUPANT ───────────────────────────────────────
37
+ *
38
+ * A planning pass runs no git pipeline — no branch, no stash, no commit, no
39
+ * push (that is the whole reason `preflightWake` gives it `needsMirror: false`
40
+ * and it works in the linked folder). It reads the tree and writes NOTHING to it:
41
+ * the deliverable is the task's description, acceptance criteria, subtasks,
42
+ * checklist and a `plan.md` note, all persisted over MCP.
43
+ *
44
+ * It nevertheless registered `presence`, and the folder-serialization gate
45
+ * treated any presence row as exclusive. So two agents planning in one folder
46
+ * locked each other out — and because the queue that gate pushed into was never
47
+ * drained (see `wake-handler.ts`), the loser did not wait, it was **lost**. That
48
+ * is the incident behind this set: a human pressed "Improve plan" twice and saw
49
+ * two `Wake received` rows and no work.
50
+ *
51
+ * So a plan is CONCURRENT by construction. This is only safe because a plan is
52
+ * also mechanically read-only: the session runs with `TS_READ_ONLY=1`, which
53
+ * makes the arbitration shims REFUSE every mutating command instead of queueing
54
+ * it (`shim-runner.ts` + `classify.ts#readOnlyRefusal`). A plan that cannot
55
+ * write cannot corrupt the tree it shares, so it has no reason to exclude
56
+ * anyone — and no reason to be excluded.
57
+ *
58
+ * Keep this set and `TS_READ_ONLY` in step. Adding a kind here is a claim that
59
+ * the session writes nothing; if that is not enforced, it is a bug.
60
+ */
61
+ export declare const NON_BLOCKING_PRESENCE_KINDS: ReadonlySet<string>;
62
+ /** True when this occupant excludes other sessions from the folder. */
63
+ export declare function presenceBlocks(entry: Pick<PresenceEntry, 'kind'>): boolean;
33
64
  /**
34
65
  * True when at least one OTHER live process occupies the folder. Used by the
35
66
  * daemon's auto-worktree escalation ("second agent showed up") and by
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PRESENCE_HEARTBEAT_MS = exports.PRESENCE_TTL_MS = void 0;
3
+ exports.NON_BLOCKING_PRESENCE_KINDS = exports.PRESENCE_HEARTBEAT_MS = exports.PRESENCE_TTL_MS = void 0;
4
4
  exports.listPresent = listPresent;
5
5
  exports.registerPresence = registerPresence;
6
6
  exports.unregisterPresence = unregisterPresence;
7
+ exports.presenceBlocks = presenceBlocks;
7
8
  exports.hasOtherOccupants = hasOtherOccupants;
8
9
  /**
9
10
  * Presence registry (IMP-950): who is working WHERE right now.
@@ -167,6 +168,39 @@ function unregisterPresence(path) {
167
168
  /* best-effort */
168
169
  }
169
170
  }
171
+ /**
172
+ * Kinds that occupy a folder WITHOUT excluding anyone (2026-10).
173
+ *
174
+ * ── WHY A PLAN PASS IS NOT AN OCCUPANT ───────────────────────────────────────
175
+ *
176
+ * A planning pass runs no git pipeline — no branch, no stash, no commit, no
177
+ * push (that is the whole reason `preflightWake` gives it `needsMirror: false`
178
+ * and it works in the linked folder). It reads the tree and writes NOTHING to it:
179
+ * the deliverable is the task's description, acceptance criteria, subtasks,
180
+ * checklist and a `plan.md` note, all persisted over MCP.
181
+ *
182
+ * It nevertheless registered `presence`, and the folder-serialization gate
183
+ * treated any presence row as exclusive. So two agents planning in one folder
184
+ * locked each other out — and because the queue that gate pushed into was never
185
+ * drained (see `wake-handler.ts`), the loser did not wait, it was **lost**. That
186
+ * is the incident behind this set: a human pressed "Improve plan" twice and saw
187
+ * two `Wake received` rows and no work.
188
+ *
189
+ * So a plan is CONCURRENT by construction. This is only safe because a plan is
190
+ * also mechanically read-only: the session runs with `TS_READ_ONLY=1`, which
191
+ * makes the arbitration shims REFUSE every mutating command instead of queueing
192
+ * it (`shim-runner.ts` + `classify.ts#readOnlyRefusal`). A plan that cannot
193
+ * write cannot corrupt the tree it shares, so it has no reason to exclude
194
+ * anyone — and no reason to be excluded.
195
+ *
196
+ * Keep this set and `TS_READ_ONLY` in step. Adding a kind here is a claim that
197
+ * the session writes nothing; if that is not enforced, it is a bug.
198
+ */
199
+ exports.NON_BLOCKING_PRESENCE_KINDS = new Set(['plan']);
200
+ /** True when this occupant excludes other sessions from the folder. */
201
+ function presenceBlocks(entry) {
202
+ return !exports.NON_BLOCKING_PRESENCE_KINDS.has(String(entry.kind ?? ''));
203
+ }
170
204
  /**
171
205
  * True when at least one OTHER live process occupies the folder. Used by the
172
206
  * daemon's auto-worktree escalation ("second agent showed up") and by
@@ -1 +1 @@
1
- {"version":3,"file":"presence.js","sourceRoot":"","sources":["../../../src/lib/workspace/presence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"presence.js","sourceRoot":"","sources":["../../../src/lib/workspace/presence.ts"],"names":[],"mappings":"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"}