teamshare-bridge 0.26.22 → 0.26.23

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 (58) hide show
  1. package/dist/bridge/daemon.js +32 -0
  2. package/dist/bridge/daemon.js.map +1 -1
  3. package/dist/cli/commands/blog.js +31 -16
  4. package/dist/cli/commands/blog.js.map +1 -1
  5. package/dist/cli/commands/build.js +2 -2
  6. package/dist/cli/commands/build.js.map +1 -1
  7. package/dist/cli/commands/chat.js +2 -3
  8. package/dist/cli/commands/chat.js.map +1 -1
  9. package/dist/cli/commands/cleanup.js +98 -27
  10. package/dist/cli/commands/cleanup.js.map +1 -1
  11. package/dist/cli/commands/plan.d.ts +4 -0
  12. package/dist/cli/commands/plan.js +33 -10
  13. package/dist/cli/commands/plan.js.map +1 -1
  14. package/dist/cli/commands/planner.js +15 -5
  15. package/dist/cli/commands/planner.js.map +1 -1
  16. package/dist/cli/commands/research.js +26 -20
  17. package/dist/cli/commands/research.js.map +1 -1
  18. package/dist/cli/commands/run.js +2 -5
  19. package/dist/cli/commands/run.js.map +1 -1
  20. package/dist/cli/commands/worker.js +2 -3
  21. package/dist/cli/commands/worker.js.map +1 -1
  22. package/dist/cli/index.js +2 -0
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/lib/cache-cleaner.js +226 -205
  25. package/dist/lib/cache-cleaner.js.map +1 -1
  26. package/dist/lib/git/git-auto.js +46 -4
  27. package/dist/lib/git/git-auto.js.map +1 -1
  28. package/dist/lib/git/git-core.d.ts +11 -0
  29. package/dist/lib/git/git-core.js +14 -0
  30. package/dist/lib/git/git-core.js.map +1 -1
  31. package/dist/lib/git/git-finalize.d.ts +4 -0
  32. package/dist/lib/git/git-finalize.js +46 -10
  33. package/dist/lib/git/git-finalize.js.map +1 -1
  34. package/dist/lib/git/git-runner.js +2 -5
  35. package/dist/lib/git/git-runner.js.map +1 -1
  36. package/dist/lib/git/index.d.ts +2 -1
  37. package/dist/lib/git/index.js +5 -4
  38. package/dist/lib/git/index.js.map +1 -1
  39. package/dist/lib/git/pr-token.d.ts +29 -0
  40. package/dist/lib/git/pr-token.js +102 -0
  41. package/dist/lib/git/pr-token.js.map +1 -0
  42. package/dist/lib/harness/run-scope.d.ts +23 -4
  43. package/dist/lib/harness/run-scope.js +237 -48
  44. package/dist/lib/harness/run-scope.js.map +1 -1
  45. package/dist/lib/llm/usage-reader.js +2 -1
  46. package/dist/lib/llm/usage-reader.js.map +1 -1
  47. package/dist/lib/orchestrator/worktree.d.ts +7 -1
  48. package/dist/lib/orchestrator/worktree.js +18 -1
  49. package/dist/lib/orchestrator/worktree.js.map +1 -1
  50. package/dist/lib/workspace/mirror.js +51 -5
  51. package/dist/lib/workspace/mirror.js.map +1 -1
  52. package/dist/lib/workspace/state-root.d.ts +44 -0
  53. package/dist/lib/workspace/state-root.js +266 -0
  54. package/dist/lib/workspace/state-root.js.map +1 -0
  55. package/dist/lib/workspace/workspace-audit.d.ts +20 -0
  56. package/dist/lib/workspace/workspace-audit.js +339 -0
  57. package/dist/lib/workspace/workspace-audit.js.map +1 -0
  58. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ghAuthToken = ghAuthToken;
4
+ exports.backendRunToken = backendRunToken;
5
+ exports.resolvePrToken = resolvePrToken;
6
+ /**
7
+ * PR/push token resolution for the task-run git pipeline (2026-10).
8
+ *
9
+ * WHY THIS EXISTS: finalize only knew a local PAT file (`git-tokens.json`)
10
+ * and `GITHUB_TOKEN`, so a linked GitHub App sat unused and every run ended
11
+ * with "PR: not opened - no credential found" while its push had succeeded.
12
+ * The App lives on the SERVER, so the bridge asks for a one-shot
13
+ * installation token via `POST /git-connections/run-token` with the run's
14
+ * own identity. Precedence mirrors the documented order:
15
+ *
16
+ * 1. project Repository PAT (stored locally from an orchestrator
17
+ * create_worktree command) — explicit per-repo credential, wins;
18
+ * 2. `GITHUB_TOKEN` / `GITEA_TOKEN` env — ambient machine credential;
19
+ * 3. `gh auth token` — ambient GitHub CLI credential (best-effort);
20
+ * 4. the backend run-token endpoint — the run caller's own App connection,
21
+ * verified against the exact repo before it is handed out.
22
+ *
23
+ * An installation token is MEMORY-ONLY: it expires in ~1h, is repo-scoped,
24
+ * and must never be written to `git-tokens.json` (that file is for durable
25
+ * PATs). Callers use the returned token transiently and drop it.
26
+ */
27
+ const node_child_process_1 = require("node:child_process");
28
+ const shims_1 = require("../workspace/shims");
29
+ const git_auth_1 = require("./git-auth");
30
+ /**
31
+ * Hub base URL default. This mirrors `DEFAULT_API_URL` in `../api-core`
32
+ * WITHOUT importing it: `api-core` requires the `./api` barrel, which pulls
33
+ * `api-content` → `api-tasks` → `api-agents` → back to `api-core`, and that
34
+ * cycle crashes standalone loads ("Class extends value undefined"). The
35
+ * bridge commands always pass their own `apiBaseUrl` anyway; this is only the
36
+ * direct-library-use fallback.
37
+ */
38
+ const DEFAULT_API_BASE_URL = process.env.TEAMSHARE_API_URL ?? 'https://api.teamshare.name.ng';
39
+ /** Best-effort ambient GitHub CLI token (null when gh is absent/logged-out). */
40
+ function ghAuthToken() {
41
+ try {
42
+ const out = (0, node_child_process_1.execFileSync)('gh', ['auth', 'token'], {
43
+ encoding: 'utf-8',
44
+ stdio: ['ignore', 'pipe', 'ignore'],
45
+ windowsHide: true,
46
+ env: (0, shims_1.envWithoutShims)(),
47
+ timeout: 10_000,
48
+ });
49
+ const token = out.trim();
50
+ return token || null;
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ /**
57
+ * Ask the hub for a one-shot token for this run (step 4). Returns null when
58
+ * there is no project, no run identity, no App connection — every one of
59
+ * those is a normal "not connected" state, never an error.
60
+ */
61
+ async function backendRunToken(opts) {
62
+ const { remoteUrl, projectId, apiKey, apiBaseUrl } = opts;
63
+ if (!remoteUrl || !projectId || !apiKey)
64
+ return null;
65
+ try {
66
+ const res = await fetch(`${(apiBaseUrl ?? DEFAULT_API_BASE_URL).replace(/\/+$/, '')}/git-connections/run-token`, {
67
+ method: 'POST',
68
+ headers: {
69
+ 'Content-Type': 'application/json',
70
+ 'X-Api-Key': apiKey,
71
+ },
72
+ body: JSON.stringify({ projectId, repoUrl: remoteUrl }),
73
+ signal: AbortSignal.timeout(15_000),
74
+ });
75
+ const raw = (await res.json().catch(() => null));
76
+ const token = raw?.data?.token;
77
+ if (!res.ok || raw?.success !== true || !token)
78
+ return null;
79
+ return { token, source: 'github_app' };
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * Full precedence chain. Pure except for the env/process reads and the
87
+ * optional backend call — `gh` and the network are only touched when every
88
+ * earlier step missed, so the common PAT/env path stays side-effect free.
89
+ */
90
+ async function resolvePrToken(opts) {
91
+ const local = (0, git_auth_1.tokenForUrl)(opts.remoteUrl);
92
+ if (local)
93
+ return { token: local, source: 'project' };
94
+ const env = process.env.GITHUB_TOKEN ?? process.env.GITEA_TOKEN;
95
+ if (env)
96
+ return { token: env, source: 'env' };
97
+ const cli = ghAuthToken();
98
+ if (cli)
99
+ return { token: cli, source: 'gh-cli' };
100
+ return backendRunToken(opts);
101
+ }
102
+ //# sourceMappingURL=pr-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-token.js","sourceRoot":"","sources":["../../../src/lib/git/pr-token.ts"],"names":[],"mappings":"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"}
@@ -28,8 +28,11 @@ export declare function createRunScope(projectRoot: string, runId: string): RunS
28
28
  /**
29
29
  * Remove a scope directory. The links are unlinked EXPLICITLY first: a
30
30
  * recursive delete of a directory holding junctions must never follow them
31
- * into the user's project.
32
- */ export declare function removeRunScope(dir: string): void;
31
+ * into the user's project. Hardened (2026-10-27): `.opencode` first (it holds
32
+ * the identity config), then links, then copies; EBUSY on Windows is retried,
33
+ * and a survivor is left for `sweepStaleScopes` rather than half-deleted.
34
+ */
35
+ export declare function removeRunScope(dir: string): void;
33
36
  /**
34
37
  * The block the agent sees when its session runs in a scope. Without it the
35
38
  * agent would guess that the scope IS the project root and write a top-level
@@ -37,7 +40,23 @@ export declare function createRunScope(projectRoot: string, runId: string): RunS
37
40
  */
38
41
  export declare function scopeWorkingDirectoryNotice(scope: RunScope): string;
39
42
  /**
40
- * Keep the scope out of the human's git status. LOCAL only (`.git/info/
41
- * exclude`) - the user's own `.gitignore` is never touched.
43
+ * Keep the scope out of the human's git status while it exists. LOCAL only
44
+ * (`.git/info/exclude`) - the user's own `.gitignore` is never touched.
45
+ * The entry is a MARKED block so cleanup can strip exactly what it added and
46
+ * leave every other line (including older unmarked bridge lines) alone.
42
47
  */
43
48
  export declare function excludeRunScopeFromGit(gitRoot: string): void;
49
+ /**
50
+ * Strip the marked scope block added by `excludeRunScopeFromGit`. Removes the
51
+ * block ONLY - every other line is preserved byte-for-byte. Safe to call when
52
+ * no scopes remain; also restores the file to zero-length difference when the
53
+ * block was the only addition.
54
+ */
55
+ export declare function unexcludeRunScopeFromGit(gitRoot: string): void;
56
+ /**
57
+ * Reap crash-leftover scopes: `<projectRoot>/.teamshare-runs/*` with no live
58
+ * harness record. A scope whose `scopeDir` is still claimed by
59
+ * `~/.teamshare/sessions/harness-*.json` is SKIPPED - a question pause, an
60
+ * idle kill or a stop-in-flight resume reuses the same tree.
61
+ */
62
+ export declare function sweepStaleScopes(projectRoots: string[]): string[];
@@ -6,8 +6,10 @@ exports.createRunScope = createRunScope;
6
6
  exports.removeRunScope = removeRunScope;
7
7
  exports.scopeWorkingDirectoryNotice = scopeWorkingDirectoryNotice;
8
8
  exports.excludeRunScopeFromGit = excludeRunScopeFromGit;
9
+ exports.unexcludeRunScopeFromGit = unexcludeRunScopeFromGit;
10
+ exports.sweepStaleScopes = sweepStaleScopes;
9
11
  /**
10
- * RUN SCOPE (2026-10): a run gets its OWN opencode project.
12
+ * RUN SCOPE (2026-10, revised 2026-10-27): a run gets its OWN opencode project.
11
13
  *
12
14
  * WHY THIS EXISTS
13
15
  * ---------------
@@ -28,27 +30,19 @@ exports.excludeRunScopeFromGit = excludeRunScopeFromGit;
28
30
  * session silently acted as the AGENT (and, after the run, kept the stale
29
31
  * client until the service re-resolved it).
30
32
  *
31
- * THE FIX
32
- * -------
33
- * A run in a SHARED folder gets a scope directory of its own:
34
- *
35
- * <projectRoot>/.teamshare-runs/<runId>/
36
- * .opencode/opencode.json <- the run's identity (its own project config)
37
- * <the project root's entries, linked>
38
- *
39
- * - the scope is INSIDE the project root, so `git` still resolves the REAL
40
- * repository root (the scope has no `.git` of its own) and the agent's
41
- * relative paths keep working: every top-level DIRECTORY is linked
42
- * (a Windows junction / a POSIX symlink), so `frontend/src/x.ts` resolves
43
- * to the real file and writes go to the real project;
44
- * - top-level FILES are copied (small ones) - a file symlink needs
45
- * elevated privileges on Windows, and a copy is the honest fallback;
46
- * - the scope is EXCLUDED from git (`.git/info/exclude`), so the human's
47
- * working tree never shows it;
48
- * - the scope is removed when the run ends, and the opencode project
49
- * registration for it is forgotten (the service would otherwise keep the
50
- * directory - and its cached MCP client - alive forever).
51
- *
33
+ * WORKSPACE-STATE RULE (2026-10-27)
34
+ * --------------------------------
35
+ * The bridge creates ZERO permanent entries inside a linked folder. The scope
36
+ * is the ONE allowed TRANSIENT exception - it must live inside the project
37
+ * root (that is what makes `git` resolve to the real repo and keeps opencode
38
+ * from filing the scope as a worktree of the human's project), but:
39
+ * - it is removed on EVERY exit path (clean, failure, forced stop);
40
+ * - it is NEVER committed (`git-pipeline.ts` filters `.teamshare-runs/`
41
+ * out of every `git add`, belt-and-braces beside the exclude);
42
+ * - the `.git/info/exclude` entry is a MARKED block added at creation and
43
+ * stripped again at cleanup, so the repo returns to its original state;
44
+ * - a crash leftover (no live harness record) is reaped by
45
+ * `sweepStaleScopes()` on daemon boot + periodically.
52
46
  * A run in an ISOLATED tree (the isolation mirror) needs none of this: the
53
47
  * mirror is already a directory of its own, so the human's project is never
54
48
  * touched. `needsRunScope()` is the single decision point.
@@ -63,6 +57,10 @@ exports.RUN_SCOPE_DIR_NAME = '.teamshare-runs';
63
57
  * mirror module is far too heavy to import from a harness helper.
64
58
  */
65
59
  const MIRROR_MARKER_FILE = '.teamshare-mirror.json';
60
+ /** Marked exclude block - the ONLY lines the bridge may add/remove. */
61
+ const EXCLUDE_BEGIN = '# >>> TeamShare run scope (auto, transient) - do not edit';
62
+ const EXCLUDE_END = '# <<< TeamShare run scope (auto, transient)';
63
+ const EXCLUDE_BODY = '.teamshare-runs/';
66
64
  /** Top-level files above this size are not copied into the scope. */
67
65
  const MAX_COPY_BYTES = 1024 * 1024;
68
66
  /**
@@ -135,37 +133,104 @@ function createRunScope(projectRoot, runId) {
135
133
  return null;
136
134
  }
137
135
  }
136
+ function sleepSync(ms) {
137
+ try {
138
+ const { execFileSync } = require('node:child_process');
139
+ execFileSync(process.execPath, ['-e', `setTimeout(()=>{},${ms})`], {
140
+ stdio: 'ignore',
141
+ });
142
+ }
143
+ catch {
144
+ /* best-effort */
145
+ }
146
+ }
138
147
  /**
139
148
  * Remove a scope directory. The links are unlinked EXPLICITLY first: a
140
149
  * recursive delete of a directory holding junctions must never follow them
141
- * into the user's project.
142
- */ function removeRunScope(dir) {
150
+ * into the user's project. Hardened (2026-10-27): `.opencode` first (it holds
151
+ * the identity config), then links, then copies; EBUSY on Windows is retried,
152
+ * and a survivor is left for `sweepStaleScopes` rather than half-deleted.
153
+ */
154
+ function removeRunScope(dir) {
143
155
  try {
144
- for (const entry of (0, node_fs_1.readdirSync)(dir)) {
145
- const path = (0, node_path_1.join)(dir, entry);
146
- try {
147
- const stat = (0, node_fs_1.lstatSync)(path);
148
- if (stat.isSymbolicLink()) {
149
- (0, node_fs_1.unlinkSync)(path);
156
+ if (!(0, node_fs_1.existsSync)(dir))
157
+ return;
158
+ // Pass 1: the identity config - the one file that must never survive.
159
+ try {
160
+ const cfg = (0, node_path_1.join)(dir, '.opencode');
161
+ if ((0, node_fs_1.existsSync)(cfg)) {
162
+ try {
163
+ const { rmSync } = require('node:fs');
164
+ rmSync(cfg, { recursive: true, force: true });
150
165
  }
151
- else if (stat.isDirectory()) {
152
- // A copied directory (rare) - remove its contents, never a link.
153
- (0, node_fs_1.rmdirSync)(path, { recursive: true });
166
+ catch {
167
+ /* fall through to the per-entry pass */
154
168
  }
155
- else {
156
- (0, node_fs_1.unlinkSync)(path);
169
+ }
170
+ }
171
+ catch {
172
+ /* best-effort */
173
+ }
174
+ for (let attempt = 0; attempt < 3; attempt++) {
175
+ try {
176
+ for (const entry of (0, node_fs_1.readdirSync)(dir)) {
177
+ const path = (0, node_path_1.join)(dir, entry);
178
+ try {
179
+ const stat = (0, node_fs_1.lstatSync)(path);
180
+ if (stat.isSymbolicLink()) {
181
+ (0, node_fs_1.unlinkSync)(path);
182
+ }
183
+ else if (stat.isDirectory()) {
184
+ // A copied directory (rare) - remove its contents, never a link.
185
+ (0, node_fs_1.rmdirSync)(path, { recursive: true });
186
+ }
187
+ else {
188
+ (0, node_fs_1.unlinkSync)(path);
189
+ }
190
+ }
191
+ catch {
192
+ /* best-effort per entry */
193
+ }
157
194
  }
195
+ (0, node_fs_1.rmdirSync)(dir, { recursive: true });
196
+ break;
158
197
  }
159
- catch {
160
- /* best-effort */
198
+ catch (err) {
199
+ // Windows: the opencode service can hold the dir briefly after the
200
+ // project registration is forgotten. Retry; the sweeper reaps a
201
+ // true survivor.
202
+ if (attempt < 2)
203
+ sleepSync(500 * (attempt + 1));
204
+ else {
205
+ try {
206
+ const { reportDiagnosticSafe } = require('../diagnostics');
207
+ reportDiagnosticSafe({
208
+ kind: 'scope_cleanup_failed',
209
+ severity: 'warning',
210
+ message: `run scope survived removal: ${dir} (${err instanceof Error ? err.message : String(err)})`,
211
+ context: { dir },
212
+ });
213
+ }
214
+ catch {
215
+ /* diagnostics must never fail cleanup */
216
+ }
217
+ }
161
218
  }
162
219
  }
163
- (0, node_fs_1.rmdirSync)(dir, { recursive: true });
164
- // Remove the parent when it is empty (no other run is using it).
220
+ // Remove the parent when it is empty (no other run is using it) - and
221
+ // only then strip the marked exclude block, so a still-running sibling
222
+ // scope keeps its cover.
165
223
  try {
166
224
  const parent = (0, node_path_1.join)(dir, '..');
167
- if ((0, node_fs_1.readdirSync)(parent).length === 0)
225
+ if ((0, node_fs_1.existsSync)(parent) && (0, node_fs_1.readdirSync)(parent).length === 0) {
168
226
  (0, node_fs_1.rmdirSync)(parent);
227
+ try {
228
+ unexcludeRunScopeFromGit((0, node_path_1.join)(parent, '..'));
229
+ }
230
+ catch {
231
+ /* best-effort */
232
+ }
233
+ }
169
234
  }
170
235
  catch {
171
236
  /* not empty / already gone */
@@ -184,20 +249,24 @@ function scopeWorkingDirectoryNotice(scope) {
184
249
  return [
185
250
  '## Working directory',
186
251
  '',
187
- `This session runs in \`${scope.dir}\` - a per-run directory that mirrors the project root \`${scope.projectRoot}\`.`,
252
+ `This session runs in \`${scope.dir}\` - a TRANSIENT per-run directory that mirrors the project root \`${scope.projectRoot}\`. It is removed when this run ends: never store anything here you need afterwards; deliverables belong in TeamShare documents.`,
188
253
  '- every top-level DIRECTORY is linked to the real one, so relative paths (e.g. `frontend/src/app.ts`) resolve to the real project and your edits land there;',
189
254
  '- top-level FILES are copies - if you must change one, write it to its real path under the project root;',
190
255
  `- the project root is \`${scope.projectRoot}\` - prefer absolute paths under it;`,
191
- '- `git` still sees the real repository (the scope has no `.git` of its own).',
256
+ '- `git` still sees the real repository (the scope has no `.git` of its own). Prefer `git -C <projectRoot>` for read-only git commands.',
192
257
  ].join('\n');
193
258
  }
194
259
  /**
195
- * Keep the scope out of the human's git status. LOCAL only (`.git/info/
196
- * exclude`) - the user's own `.gitignore` is never touched.
260
+ * Keep the scope out of the human's git status while it exists. LOCAL only
261
+ * (`.git/info/exclude`) - the user's own `.gitignore` is never touched.
262
+ * The entry is a MARKED block so cleanup can strip exactly what it added and
263
+ * leave every other line (including older unmarked bridge lines) alone.
197
264
  */
198
265
  function excludeRunScopeFromGit(gitRoot) {
199
266
  try {
200
- const file = (0, node_path_1.join)(gitRoot, '.git', 'info', 'exclude');
267
+ const file = gitExcludePath(gitRoot);
268
+ if (!file)
269
+ return;
201
270
  let current = '';
202
271
  try {
203
272
  current = (0, node_fs_1.readFileSync)(file, 'utf8');
@@ -205,14 +274,134 @@ function excludeRunScopeFromGit(gitRoot) {
205
274
  catch {
206
275
  /* the file may not exist yet - append creates it */
207
276
  }
208
- const existing = new Set(current.split('\n').map((l) => l.trim()));
209
- if (existing.has(`${exports.RUN_SCOPE_DIR_NAME}/`))
277
+ if (current.includes(EXCLUDE_BEGIN))
210
278
  return;
211
279
  const prefix = current.length > 0 && !current.endsWith('\n') ? '\n' : '';
212
- (0, node_fs_1.appendFileSync)(file, `${prefix}# TeamShare run scopes (per-run opencode projects) - added automatically\n${exports.RUN_SCOPE_DIR_NAME}/\n`);
280
+ (0, node_fs_1.appendFileSync)(file, `${prefix}${EXCLUDE_BEGIN}\n${EXCLUDE_BODY}\n${EXCLUDE_END}\n`);
213
281
  }
214
282
  catch {
215
283
  /* best-effort: an exclude problem must never fail a run */
216
284
  }
217
285
  }
286
+ /**
287
+ * Strip the marked scope block added by `excludeRunScopeFromGit`. Removes the
288
+ * block ONLY - every other line is preserved byte-for-byte. Safe to call when
289
+ * no scopes remain; also restores the file to zero-length difference when the
290
+ * block was the only addition.
291
+ */
292
+ function unexcludeRunScopeFromGit(gitRoot) {
293
+ try {
294
+ const file = gitExcludePath(gitRoot);
295
+ if (!file || !(0, node_fs_1.existsSync)(file))
296
+ return;
297
+ const current = (0, node_fs_1.readFileSync)(file, 'utf8');
298
+ if (!current.includes(EXCLUDE_BEGIN))
299
+ return;
300
+ const lines = current.split('\n');
301
+ const start = lines.findIndex((l) => l.includes(EXCLUDE_BEGIN));
302
+ const end = lines.findIndex((l) => l.includes(EXCLUDE_END));
303
+ if (start === -1 || end === -1 || end < start)
304
+ return;
305
+ lines.splice(start, end - start + 1);
306
+ // Collapse the blank line the append may have introduced, but never touch
307
+ // anything else.
308
+ const next = lines.join('\n').replace(/\n{3,}/g, '\n\n');
309
+ (0, node_fs_1.writeFileSync)(file, next, 'utf8');
310
+ }
311
+ catch {
312
+ /* best-effort */
313
+ }
314
+ }
315
+ function gitExcludePath(gitRoot) {
316
+ try {
317
+ // `--git-path` resolves correctly when `.git` is a FILE
318
+ // (`--separate-git-dir` containers) as well as a directory.
319
+ const { execFileSync } = require('node:child_process');
320
+ const { envWithoutShims } = require('../workspace/shims');
321
+ const out = execFileSync('git', ['rev-parse', '--git-path', 'info/exclude'], {
322
+ cwd: gitRoot,
323
+ encoding: 'utf-8',
324
+ timeout: 5_000,
325
+ stdio: ['pipe', 'pipe', 'pipe'],
326
+ env: envWithoutShims(),
327
+ })
328
+ .toString()
329
+ .trim();
330
+ if (!out)
331
+ return null;
332
+ const path = require('node:path');
333
+ return path.isAbsolute(out) ? out : path.resolve(gitRoot, out);
334
+ }
335
+ catch {
336
+ // Not a repo (or git missing) - fall back to the conventional path so a
337
+ // future `git init` still finds the file; never fail the run.
338
+ try {
339
+ return (0, node_path_1.join)(gitRoot, '.git', 'info', 'exclude');
340
+ }
341
+ catch {
342
+ return null;
343
+ }
344
+ }
345
+ }
346
+ /**
347
+ * Reap crash-leftover scopes: `<projectRoot>/.teamshare-runs/*` with no live
348
+ * harness record. A scope whose `scopeDir` is still claimed by
349
+ * `~/.teamshare/sessions/harness-*.json` is SKIPPED - a question pause, an
350
+ * idle kill or a stop-in-flight resume reuses the same tree.
351
+ */
352
+ function sweepStaleScopes(projectRoots) {
353
+ const removed = [];
354
+ const live = new Set();
355
+ try {
356
+ const { readdirSync: rs, readFileSync: rf, existsSync: ex, } = require('node:fs');
357
+ const { homedir } = require('node:os');
358
+ const path = require('node:path');
359
+ const sessionsDir = path.join(homedir(), '.teamshare', 'sessions');
360
+ if (ex(sessionsDir)) {
361
+ for (const name of rs(sessionsDir)) {
362
+ if (!name.startsWith('harness-') || !name.endsWith('.json'))
363
+ continue;
364
+ try {
365
+ const rec = JSON.parse(rf(path.join(sessionsDir, name), 'utf8'));
366
+ if (rec?.scopeDir)
367
+ live.add(rec.scopeDir.replace(/\\/g, '/').toLowerCase());
368
+ }
369
+ catch {
370
+ /* corrupt record - ignore */
371
+ }
372
+ }
373
+ }
374
+ }
375
+ catch {
376
+ /* best-effort: an unreadable live set reaps nothing extra */
377
+ }
378
+ for (const root of projectRoots) {
379
+ let names = [];
380
+ try {
381
+ const base = (0, node_path_1.join)(root, exports.RUN_SCOPE_DIR_NAME);
382
+ if (!(0, node_fs_1.existsSync)(base))
383
+ continue;
384
+ names = (0, node_fs_1.readdirSync)(base);
385
+ }
386
+ catch {
387
+ continue;
388
+ }
389
+ for (const name of names) {
390
+ const dir = (0, node_path_1.join)(root, exports.RUN_SCOPE_DIR_NAME, name);
391
+ try {
392
+ if ((0, node_fs_1.lstatSync)(dir).isSymbolicLink())
393
+ continue;
394
+ if (live.has(dir.replace(/\\/g, '/').toLowerCase()))
395
+ continue;
396
+ removeRunScope(dir);
397
+ if (!(0, node_fs_1.existsSync)(dir))
398
+ removed.push(dir);
399
+ }
400
+ catch {
401
+ /* best-effort per scope */
402
+ }
403
+ }
404
+ }
405
+ return removed;
406
+ }
218
407
  //# sourceMappingURL=run-scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-scope.js","sourceRoot":"","sources":["../../../src/lib/harness/run-scope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-scope.js","sourceRoot":"","sources":["../../../src/lib/harness/run-scope.ts"],"names":[],"mappings":"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"}
@@ -237,7 +237,8 @@ function estimateModelCost(modelId, tokens, style, home = (0, node_os_1.homedir)
237
237
  const TEAMSHARE_TITLE_RE = /^(TeamShare (task|chat|doc) |Tool run [\w-]+ \(|Plan task )/;
238
238
  function isTeamshareWork(title, directory) {
239
239
  if (directory.includes('.teamshare-runs') ||
240
- directory.includes('.teamshare-worktrees')) {
240
+ directory.includes('.teamshare-worktrees') ||
241
+ directory.includes('.teamshare/workspace')) {
241
242
  return true;
242
243
  }
243
244
  return TEAMSHARE_TITLE_RE.test(title);