@sideboard-ai/core 0.1.46 → 0.1.49
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/dist/{agents-6L6VENDT.js → agents-3P4N6KHC.js} +1 -1
- package/dist/agents-LUB3Q773.js +82 -0
- package/dist/app-settings-7XVDQJ7F.js +80 -0
- package/dist/{chunk-SZAKJ4TR.js → chunk-3NAS4MWH.js} +1 -1
- package/dist/{chunk-SPCU3MFY.js → chunk-5WYEJ3F3.js} +3 -3
- package/dist/chunk-7MV3RXSC.js +277 -0
- package/dist/chunk-DF5VQQKA.js +191 -0
- package/dist/chunk-E35APBHV.js +269 -0
- package/dist/chunk-EOYDCKQC.js +172 -0
- package/dist/chunk-GZXBYHJC.js +148 -0
- package/dist/chunk-HBJSHRY2.js +494 -0
- package/dist/chunk-ISY4EGF6.js +77 -0
- package/dist/chunk-KGZBYWZ3.js +23 -0
- package/dist/chunk-RQI4TOXK.js +2232 -0
- package/dist/chunk-S2LL5HA4.js +33 -0
- package/dist/{chunk-TQK2OYPU.js → chunk-SS34TVSY.js} +1 -1
- package/dist/chunk-V4JRXYYU.js +122 -0
- package/dist/{chunk-6NAPN2N5.js → chunk-ZQCQIWIP.js} +1 -1
- package/dist/chunk-ZVV5EEQN.js +1892 -0
- package/dist/connected-teams-UBXHZGO4.js +24 -0
- package/dist/{coordinator-prompt-2XFYG3C5.js → coordinator-prompt-SPGDT7J5.js} +1 -1
- package/dist/coordinator-prompt-VG4BZ5JL.js +25 -0
- package/dist/cursor-recover-NNK7JPQM.js +44 -0
- package/dist/{global-workspace-XFOXEQCP.js → global-workspace-KSR3E63K.js} +2 -2
- package/dist/global-workspace-OJF4ENH4.js +40 -0
- package/dist/index.cjs +243 -19
- package/dist/index.d.cts +49 -10
- package/dist/index.d.ts +49 -10
- package/dist/index.js +5768 -192
- package/dist/mcp/run-stdio.cjs +203 -21
- package/dist/mcp/run-stdio.js +5618 -15
- package/dist/paths-2OFB7UJG.js +28 -0
- package/dist/run-HMRSRG3U.js +12 -0
- package/dist/thread-store-XICUWFNM.js +32 -0
- package/dist/title-4WAKWZRF.js +27 -0
- package/dist/workspaces-OZE7LRDO.js +24 -0
- package/dist/{workspaces-SRL2HZTB.js → workspaces-UJX7JIGH.js} +3 -3
- package/dist/worktree-XG5PCLZY.js +94 -0
- package/package.json +2 -2
- package/dist/chunk-7DTJFP4D.js +0 -5680
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
CLAUDE_MODEL_CATALOG,
|
|
5
|
+
PLAN_MODE_INSTRUCTION,
|
|
6
|
+
allAdapters,
|
|
7
|
+
brightsyAdapter,
|
|
8
|
+
claudeAdapter,
|
|
9
|
+
codexAdapter,
|
|
10
|
+
cursorAdapter,
|
|
11
|
+
cursorSdkMessageToEvents,
|
|
12
|
+
decodeBrightsyTarget,
|
|
13
|
+
encodeBrightsyTarget,
|
|
14
|
+
getAdapter,
|
|
15
|
+
getAgentSetupInfo,
|
|
16
|
+
installAgent,
|
|
17
|
+
isCursorAutoModel,
|
|
18
|
+
isSessionQuotaLimit,
|
|
19
|
+
listAgentSetupInfo,
|
|
20
|
+
listBrightsyChatTargets,
|
|
21
|
+
listCodexModels,
|
|
22
|
+
listCursorModels,
|
|
23
|
+
listModelsForAgent,
|
|
24
|
+
listOpencodeModels,
|
|
25
|
+
loginAgent,
|
|
26
|
+
openInSystemTerminal,
|
|
27
|
+
opencodeAdapter,
|
|
28
|
+
parseCursorRunnerLine,
|
|
29
|
+
parseSessionQuotaResetAt,
|
|
30
|
+
permissionMode,
|
|
31
|
+
resolveCursorModelId,
|
|
32
|
+
resolveQuotaFallbackAgent
|
|
33
|
+
} from "./chunk-RQI4TOXK.js";
|
|
34
|
+
import "./chunk-E35APBHV.js";
|
|
35
|
+
import "./chunk-HBJSHRY2.js";
|
|
36
|
+
import {
|
|
37
|
+
ORCHESTRATOR_AGENT_KINDS,
|
|
38
|
+
assertOrchestratorCapableAgent,
|
|
39
|
+
coerceOrchestratorAgent,
|
|
40
|
+
isOrchestratorCapableAgent
|
|
41
|
+
} from "./chunk-S2LL5HA4.js";
|
|
42
|
+
import {
|
|
43
|
+
ensureAgentPath
|
|
44
|
+
} from "./chunk-ISY4EGF6.js";
|
|
45
|
+
import "./chunk-KGZBYWZ3.js";
|
|
46
|
+
import "./chunk-7MV3RXSC.js";
|
|
47
|
+
export {
|
|
48
|
+
CLAUDE_MODEL_CATALOG,
|
|
49
|
+
ORCHESTRATOR_AGENT_KINDS,
|
|
50
|
+
PLAN_MODE_INSTRUCTION,
|
|
51
|
+
allAdapters,
|
|
52
|
+
assertOrchestratorCapableAgent,
|
|
53
|
+
brightsyAdapter,
|
|
54
|
+
claudeAdapter,
|
|
55
|
+
codexAdapter,
|
|
56
|
+
coerceOrchestratorAgent,
|
|
57
|
+
cursorAdapter,
|
|
58
|
+
cursorSdkMessageToEvents,
|
|
59
|
+
decodeBrightsyTarget,
|
|
60
|
+
encodeBrightsyTarget,
|
|
61
|
+
ensureAgentPath,
|
|
62
|
+
getAdapter,
|
|
63
|
+
getAgentSetupInfo,
|
|
64
|
+
installAgent,
|
|
65
|
+
isCursorAutoModel,
|
|
66
|
+
isOrchestratorCapableAgent,
|
|
67
|
+
isSessionQuotaLimit,
|
|
68
|
+
listAgentSetupInfo,
|
|
69
|
+
listBrightsyChatTargets,
|
|
70
|
+
listCodexModels,
|
|
71
|
+
listCursorModels,
|
|
72
|
+
listModelsForAgent,
|
|
73
|
+
listOpencodeModels,
|
|
74
|
+
loginAgent,
|
|
75
|
+
openInSystemTerminal,
|
|
76
|
+
opencodeAdapter,
|
|
77
|
+
parseCursorRunnerLine,
|
|
78
|
+
parseSessionQuotaResetAt,
|
|
79
|
+
permissionMode,
|
|
80
|
+
resolveCursorModelId,
|
|
81
|
+
resolveQuotaFallbackAgent
|
|
82
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
HARNESS_ENV_KEYS,
|
|
5
|
+
appSettingsPath,
|
|
6
|
+
applyAppEnvironment,
|
|
7
|
+
autoCleanupOrphansEnabled,
|
|
8
|
+
autoRenameBranchEnabled,
|
|
9
|
+
autoRunAfterSetupEnabled,
|
|
10
|
+
brightsyCloudConnectAgent,
|
|
11
|
+
brightsyCloudConnectEnabled,
|
|
12
|
+
caffeinateWhileCloudConnectEnabled,
|
|
13
|
+
caffeinateWhileRunningEnabled,
|
|
14
|
+
childEnvWithAppSettings,
|
|
15
|
+
claudeChromeEnabled,
|
|
16
|
+
claudeUserSettingsPath,
|
|
17
|
+
deleteBranchOnPurgeEnabled,
|
|
18
|
+
getDefaultAgent,
|
|
19
|
+
getDefaultEffort,
|
|
20
|
+
getDefaultFast,
|
|
21
|
+
getDefaultModel,
|
|
22
|
+
getIssueSource,
|
|
23
|
+
getLinearApiKey,
|
|
24
|
+
harnessEnvKey,
|
|
25
|
+
isLinearConnected,
|
|
26
|
+
loadAppSettings,
|
|
27
|
+
maxConcurrentAgents,
|
|
28
|
+
orchestrationQuotaFallbackAgent,
|
|
29
|
+
orchestrationQuotaOnLimit,
|
|
30
|
+
resolveClaudeExecutable,
|
|
31
|
+
resolveEffectiveIssueSource,
|
|
32
|
+
resolveThreadDefaults,
|
|
33
|
+
saveAppSettings,
|
|
34
|
+
updateAdvancedSettings,
|
|
35
|
+
updateAppEnvironment,
|
|
36
|
+
updateBrightsySettings,
|
|
37
|
+
updateClaudeSettings,
|
|
38
|
+
updateDefaultsSettings,
|
|
39
|
+
updateIntegrationsSettings
|
|
40
|
+
} from "./chunk-HBJSHRY2.js";
|
|
41
|
+
import "./chunk-KGZBYWZ3.js";
|
|
42
|
+
import "./chunk-7MV3RXSC.js";
|
|
43
|
+
export {
|
|
44
|
+
HARNESS_ENV_KEYS,
|
|
45
|
+
appSettingsPath,
|
|
46
|
+
applyAppEnvironment,
|
|
47
|
+
autoCleanupOrphansEnabled,
|
|
48
|
+
autoRenameBranchEnabled,
|
|
49
|
+
autoRunAfterSetupEnabled,
|
|
50
|
+
brightsyCloudConnectAgent,
|
|
51
|
+
brightsyCloudConnectEnabled,
|
|
52
|
+
caffeinateWhileCloudConnectEnabled,
|
|
53
|
+
caffeinateWhileRunningEnabled,
|
|
54
|
+
childEnvWithAppSettings,
|
|
55
|
+
claudeChromeEnabled,
|
|
56
|
+
claudeUserSettingsPath,
|
|
57
|
+
deleteBranchOnPurgeEnabled,
|
|
58
|
+
getDefaultAgent,
|
|
59
|
+
getDefaultEffort,
|
|
60
|
+
getDefaultFast,
|
|
61
|
+
getDefaultModel,
|
|
62
|
+
getIssueSource,
|
|
63
|
+
getLinearApiKey,
|
|
64
|
+
harnessEnvKey,
|
|
65
|
+
isLinearConnected,
|
|
66
|
+
loadAppSettings,
|
|
67
|
+
maxConcurrentAgents,
|
|
68
|
+
orchestrationQuotaFallbackAgent,
|
|
69
|
+
orchestrationQuotaOnLimit,
|
|
70
|
+
resolveClaudeExecutable,
|
|
71
|
+
resolveEffectiveIssueSource,
|
|
72
|
+
resolveThreadDefaults,
|
|
73
|
+
saveAppSettings,
|
|
74
|
+
updateAdvancedSettings,
|
|
75
|
+
updateAppEnvironment,
|
|
76
|
+
updateBrightsySettings,
|
|
77
|
+
updateClaudeSettings,
|
|
78
|
+
updateDefaultsSettings,
|
|
79
|
+
updateIntegrationsSettings
|
|
80
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureGlobalCoordinatorCwd
|
|
3
|
-
} from "./chunk-6NAPN2N5.js";
|
|
4
1
|
import {
|
|
5
2
|
assertOrchestratorCapableAgent
|
|
6
3
|
} from "./chunk-GI7E5733.js";
|
|
4
|
+
import {
|
|
5
|
+
ensureGlobalCoordinatorCwd
|
|
6
|
+
} from "./chunk-ZQCQIWIP.js";
|
|
7
7
|
import {
|
|
8
8
|
allocateTeamName,
|
|
9
9
|
takenSlugsFromThread,
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// src/store/paths.ts
|
|
5
|
+
import { basename } from "path";
|
|
6
|
+
import { homedir as homedir2 } from "os";
|
|
7
|
+
import { join as join2 } from "path";
|
|
8
|
+
import { mkdirSync } from "fs";
|
|
9
|
+
|
|
10
|
+
// src/hook/settings.ts
|
|
11
|
+
import { existsSync, readFileSync } from "fs";
|
|
12
|
+
import { homedir } from "os";
|
|
13
|
+
import { join } from "path";
|
|
14
|
+
import { parse as parseToml } from "smol-toml";
|
|
15
|
+
function expandHome(path) {
|
|
16
|
+
if (path.startsWith("~/") || path === "~") {
|
|
17
|
+
return join(homedir(), path.slice(2));
|
|
18
|
+
}
|
|
19
|
+
return path;
|
|
20
|
+
}
|
|
21
|
+
function parseAvailableIn(raw) {
|
|
22
|
+
if (!Array.isArray(raw)) return void 0;
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const item of raw) {
|
|
25
|
+
if (item === "local" || item === "cloud") out.push(item);
|
|
26
|
+
}
|
|
27
|
+
return out.length ? out : void 0;
|
|
28
|
+
}
|
|
29
|
+
function parseSettingsFile(path, source) {
|
|
30
|
+
if (!existsSync(path)) return null;
|
|
31
|
+
const raw = readFileSync(path, "utf8");
|
|
32
|
+
const data = parseToml(raw);
|
|
33
|
+
const scripts = data.scripts ?? {};
|
|
34
|
+
const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
|
|
35
|
+
const archive = typeof scripts.archive === "string" ? scripts.archive : void 0;
|
|
36
|
+
const runMode = "run_mode" in scripts ? scripts.run_mode === "nonconcurrent" ? "nonconcurrent" : "concurrent" : void 0;
|
|
37
|
+
const filesToCopy = [];
|
|
38
|
+
const files = data.files;
|
|
39
|
+
if (Array.isArray(files?.copy)) {
|
|
40
|
+
filesToCopy.push(...files.copy.map(String));
|
|
41
|
+
}
|
|
42
|
+
const copySection = data["files-to-copy"];
|
|
43
|
+
if (Array.isArray(copySection?.paths)) {
|
|
44
|
+
filesToCopy.push(...copySection.paths.map(String));
|
|
45
|
+
}
|
|
46
|
+
const fileIncludeGlobs = [];
|
|
47
|
+
if (Array.isArray(data.file_include_globs)) {
|
|
48
|
+
fileIncludeGlobs.push(...data.file_include_globs.map(String));
|
|
49
|
+
}
|
|
50
|
+
const filesGlobs = files;
|
|
51
|
+
if (Array.isArray(filesGlobs?.include)) {
|
|
52
|
+
fileIncludeGlobs.push(...filesGlobs.include.map(String));
|
|
53
|
+
}
|
|
54
|
+
if (Array.isArray(filesGlobs?.include_globs)) {
|
|
55
|
+
fileIncludeGlobs.push(...filesGlobs.include_globs.map(String));
|
|
56
|
+
}
|
|
57
|
+
const runScripts = [];
|
|
58
|
+
const run = scripts.run;
|
|
59
|
+
if (typeof run === "string" && run.trim()) {
|
|
60
|
+
runScripts.push({ name: "dev", command: run, default: true });
|
|
61
|
+
} else if (run && typeof run === "object") {
|
|
62
|
+
for (const [name, value] of Object.entries(run)) {
|
|
63
|
+
if (value && typeof value.command === "string") {
|
|
64
|
+
runScripts.push({
|
|
65
|
+
name,
|
|
66
|
+
command: value.command,
|
|
67
|
+
default: Boolean(value.default),
|
|
68
|
+
icon: typeof value.icon === "string" ? value.icon : void 0,
|
|
69
|
+
availableIn: parseAvailableIn(value.available_in)
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const worktrees = data.worktrees;
|
|
75
|
+
const worktreesRoot2 = typeof worktrees?.root === "string" ? expandHome(worktrees.root) : void 0;
|
|
76
|
+
const editor = typeof data.editor === "string" ? String(data.editor) : void 0;
|
|
77
|
+
const promptsRaw = data.prompts ?? {};
|
|
78
|
+
const prompts = {
|
|
79
|
+
renameBranch: typeof promptsRaw.rename_branch === "string" ? promptsRaw.rename_branch : void 0,
|
|
80
|
+
createPr: typeof promptsRaw.create_pr === "string" ? promptsRaw.create_pr : void 0,
|
|
81
|
+
general: typeof promptsRaw.general === "string" ? promptsRaw.general : void 0
|
|
82
|
+
};
|
|
83
|
+
const hasPrompts = Boolean(prompts.renameBranch || prompts.createPr || prompts.general);
|
|
84
|
+
return {
|
|
85
|
+
source,
|
|
86
|
+
setup,
|
|
87
|
+
archive,
|
|
88
|
+
runMode,
|
|
89
|
+
filesToCopy: filesToCopy.length ? filesToCopy : void 0,
|
|
90
|
+
fileIncludeGlobs: fileIncludeGlobs.length ? fileIncludeGlobs : void 0,
|
|
91
|
+
runScripts,
|
|
92
|
+
worktreesRoot: worktreesRoot2,
|
|
93
|
+
editor,
|
|
94
|
+
prompts: hasPrompts ? prompts : void 0
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function mergeRunScripts(base, overlay) {
|
|
98
|
+
const byName = /* @__PURE__ */ new Map();
|
|
99
|
+
for (const s of base) byName.set(s.name, s);
|
|
100
|
+
for (const s of overlay) byName.set(s.name, s);
|
|
101
|
+
return [...byName.values()];
|
|
102
|
+
}
|
|
103
|
+
function mergeSettings(base, overlay) {
|
|
104
|
+
if (!base) return overlay;
|
|
105
|
+
if (!overlay) return base;
|
|
106
|
+
const prompts = {
|
|
107
|
+
renameBranch: overlay.prompts?.renameBranch ?? base.prompts?.renameBranch,
|
|
108
|
+
createPr: overlay.prompts?.createPr ?? base.prompts?.createPr,
|
|
109
|
+
general: overlay.prompts?.general ?? base.prompts?.general
|
|
110
|
+
};
|
|
111
|
+
const hasPrompts = Boolean(prompts.renameBranch || prompts.createPr || prompts.general);
|
|
112
|
+
return {
|
|
113
|
+
source: overlay.source,
|
|
114
|
+
setup: overlay.setup ?? base.setup,
|
|
115
|
+
archive: overlay.archive ?? base.archive,
|
|
116
|
+
runMode: overlay.runMode ?? base.runMode,
|
|
117
|
+
filesToCopy: overlay.filesToCopy ?? base.filesToCopy,
|
|
118
|
+
fileIncludeGlobs: overlay.fileIncludeGlobs ?? base.fileIncludeGlobs,
|
|
119
|
+
runScripts: mergeRunScripts(base.runScripts, overlay.runScripts),
|
|
120
|
+
worktreesRoot: overlay.worktreesRoot ?? base.worktreesRoot,
|
|
121
|
+
editor: overlay.editor ?? base.editor,
|
|
122
|
+
prompts: hasPrompts ? prompts : void 0
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function finalizeSettings(parsed) {
|
|
126
|
+
if (!parsed) return null;
|
|
127
|
+
return {
|
|
128
|
+
...parsed,
|
|
129
|
+
runMode: parsed.runMode ?? "concurrent",
|
|
130
|
+
runScripts: parsed.runScripts
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function familyFiles(rootPath, source) {
|
|
134
|
+
const dir = join(rootPath, `.${source}`);
|
|
135
|
+
return {
|
|
136
|
+
toml: join(dir, "settings.toml"),
|
|
137
|
+
local: join(dir, "settings.local.toml")
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function familyExists(rootPath, source) {
|
|
141
|
+
const files = familyFiles(rootPath, source);
|
|
142
|
+
return existsSync(files.toml) || existsSync(files.local);
|
|
143
|
+
}
|
|
144
|
+
function detectFamily(rootPath) {
|
|
145
|
+
if (familyExists(rootPath, "sideboard")) return "sideboard";
|
|
146
|
+
if (familyExists(rootPath, "conductor")) return "conductor";
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
function loadCommittedToml(rootPath, source) {
|
|
150
|
+
return parseSettingsFile(familyFiles(rootPath, source).toml, source);
|
|
151
|
+
}
|
|
152
|
+
function loadLocalToml(rootPath, source) {
|
|
153
|
+
return parseSettingsFile(familyFiles(rootPath, source).local, source);
|
|
154
|
+
}
|
|
155
|
+
function loadAnyLocal(rootPath) {
|
|
156
|
+
return mergeSettings(
|
|
157
|
+
loadLocalToml(rootPath, "conductor"),
|
|
158
|
+
loadLocalToml(rootPath, "sideboard")
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
function normPath(p) {
|
|
162
|
+
return p.replace(/\/+$/, "");
|
|
163
|
+
}
|
|
164
|
+
function loadRepoSettings(repoPath) {
|
|
165
|
+
const family = detectFamily(repoPath);
|
|
166
|
+
if (!family) return null;
|
|
167
|
+
const merged = mergeSettings(
|
|
168
|
+
loadCommittedToml(repoPath, family),
|
|
169
|
+
loadLocalToml(repoPath, family)
|
|
170
|
+
);
|
|
171
|
+
return finalizeSettings(merged);
|
|
172
|
+
}
|
|
173
|
+
function loadWorkspaceSettings(worktreePath, repoPath) {
|
|
174
|
+
const wtFamily = detectFamily(worktreePath);
|
|
175
|
+
const repoFamily = repoPath && normPath(repoPath) !== normPath(worktreePath) ? detectFamily(repoPath) : null;
|
|
176
|
+
const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
|
|
177
|
+
const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
|
|
178
|
+
let merged = wtToml ?? repoToml;
|
|
179
|
+
if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
|
|
180
|
+
merged = mergeSettings(merged, loadAnyLocal(repoPath));
|
|
181
|
+
}
|
|
182
|
+
merged = mergeSettings(merged, loadAnyLocal(worktreePath));
|
|
183
|
+
return finalizeSettings(merged);
|
|
184
|
+
}
|
|
185
|
+
function settingsSourceLabel(rootPath) {
|
|
186
|
+
const family = detectFamily(rootPath);
|
|
187
|
+
if (!family) return null;
|
|
188
|
+
const files = familyFiles(rootPath, family);
|
|
189
|
+
if (existsSync(files.toml) && existsSync(files.local)) {
|
|
190
|
+
return `.${family}/settings.toml + local`;
|
|
191
|
+
}
|
|
192
|
+
if (existsSync(files.local)) return `.${family}/settings.local.toml`;
|
|
193
|
+
return `.${family}/settings.toml`;
|
|
194
|
+
}
|
|
195
|
+
function workspaceSettingsSourceLabel(worktreePath, repoPath) {
|
|
196
|
+
const wt = settingsSourceLabel(worktreePath);
|
|
197
|
+
if (wt) return `${wt} (worktree)`;
|
|
198
|
+
if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
|
|
199
|
+
const repo = settingsSourceLabel(repoPath);
|
|
200
|
+
if (repo) return `${repo} (main repo)`;
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/store/paths.ts
|
|
206
|
+
function appDataDir() {
|
|
207
|
+
const override = process.env.SIDEBOARD_APP_DATA?.trim();
|
|
208
|
+
const base = override ? override : process.platform === "darwin" ? join2(homedir2(), "Library", "Application Support", "sideboard") : process.platform === "win32" ? join2(process.env.APPDATA ?? join2(homedir2(), "AppData", "Roaming"), "sideboard") : join2(homedir2(), ".local", "share", "sideboard");
|
|
209
|
+
mkdirSync(base, { recursive: true });
|
|
210
|
+
return base;
|
|
211
|
+
}
|
|
212
|
+
function threadsDir() {
|
|
213
|
+
const dir = join2(appDataDir(), "threads");
|
|
214
|
+
mkdirSync(dir, { recursive: true });
|
|
215
|
+
return dir;
|
|
216
|
+
}
|
|
217
|
+
function locksDir() {
|
|
218
|
+
const dir = join2(appDataDir(), "locks");
|
|
219
|
+
mkdirSync(dir, { recursive: true });
|
|
220
|
+
return dir;
|
|
221
|
+
}
|
|
222
|
+
function sideboardHomeDir() {
|
|
223
|
+
const dir = join2(homedir2(), "sideboard");
|
|
224
|
+
mkdirSync(dir, { recursive: true });
|
|
225
|
+
return dir;
|
|
226
|
+
}
|
|
227
|
+
function sideboardReposDir() {
|
|
228
|
+
const dir = join2(sideboardHomeDir(), "repos");
|
|
229
|
+
mkdirSync(dir, { recursive: true });
|
|
230
|
+
return dir;
|
|
231
|
+
}
|
|
232
|
+
function sideboardWorkspacesDir() {
|
|
233
|
+
const dir = join2(sideboardHomeDir(), "workspaces");
|
|
234
|
+
mkdirSync(dir, { recursive: true });
|
|
235
|
+
return dir;
|
|
236
|
+
}
|
|
237
|
+
function repoSlug(repoPath) {
|
|
238
|
+
return basename(repoPath.replace(/\/$/, "")) || "repo";
|
|
239
|
+
}
|
|
240
|
+
function worktreesRoot(repoPath) {
|
|
241
|
+
const settings = loadRepoSettings(repoPath);
|
|
242
|
+
if (settings?.worktreesRoot) {
|
|
243
|
+
mkdirSync(settings.worktreesRoot, { recursive: true });
|
|
244
|
+
return settings.worktreesRoot;
|
|
245
|
+
}
|
|
246
|
+
const dir = join2(sideboardWorkspacesDir(), repoSlug(repoPath));
|
|
247
|
+
mkdirSync(dir, { recursive: true });
|
|
248
|
+
return dir;
|
|
249
|
+
}
|
|
250
|
+
function threadFilePath(id) {
|
|
251
|
+
return join2(threadsDir(), `${id}.json`);
|
|
252
|
+
}
|
|
253
|
+
function threadLockPath(id) {
|
|
254
|
+
return join2(locksDir(), `${id}.lock`);
|
|
255
|
+
}
|
|
256
|
+
function globalAgentCwd() {
|
|
257
|
+
const dir = join2(appDataDir(), "global");
|
|
258
|
+
mkdirSync(dir, { recursive: true });
|
|
259
|
+
return dir;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export {
|
|
263
|
+
loadRepoSettings,
|
|
264
|
+
loadWorkspaceSettings,
|
|
265
|
+
workspaceSettingsSourceLabel,
|
|
266
|
+
appDataDir,
|
|
267
|
+
threadsDir,
|
|
268
|
+
locksDir,
|
|
269
|
+
sideboardHomeDir,
|
|
270
|
+
sideboardReposDir,
|
|
271
|
+
sideboardWorkspacesDir,
|
|
272
|
+
repoSlug,
|
|
273
|
+
worktreesRoot,
|
|
274
|
+
threadFilePath,
|
|
275
|
+
threadLockPath,
|
|
276
|
+
globalAgentCwd
|
|
277
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
assertOrchestratorCapableAgent
|
|
5
|
+
} from "./chunk-S2LL5HA4.js";
|
|
6
|
+
import {
|
|
7
|
+
ensureGlobalCoordinatorCwd
|
|
8
|
+
} from "./chunk-GZXBYHJC.js";
|
|
9
|
+
import {
|
|
10
|
+
allocateTeamName,
|
|
11
|
+
takenSlugsFromThread,
|
|
12
|
+
teamSlugFromName
|
|
13
|
+
} from "./chunk-ZVV5EEQN.js";
|
|
14
|
+
import {
|
|
15
|
+
createEmptyThread,
|
|
16
|
+
listThreads,
|
|
17
|
+
updateThread,
|
|
18
|
+
writeThread
|
|
19
|
+
} from "./chunk-EOYDCKQC.js";
|
|
20
|
+
import {
|
|
21
|
+
globalAgentCwd
|
|
22
|
+
} from "./chunk-7MV3RXSC.js";
|
|
23
|
+
|
|
24
|
+
// src/brightsy/cloud-connect-constants.ts
|
|
25
|
+
var CLOUD_ORCHESTRATOR_GOAL = "Cloud-connected Sideboard orchestrator";
|
|
26
|
+
var SIDEBOARD_FORCE_STOP = "SIDEBOARD_FORCE_STOP";
|
|
27
|
+
var CLOUD_COORDINATOR_BUSY_REPLY = [
|
|
28
|
+
"Sideboard is busy with an in-progress client/desktop tool turn on the global coordinator.",
|
|
29
|
+
"I did not start a new orchestration turn.",
|
|
30
|
+
`To force-stop the in-progress turn, send another desktop request whose first line is exactly ${SIDEBOARD_FORCE_STOP}`,
|
|
31
|
+
"(optional follow-up request on later lines).",
|
|
32
|
+
"What do you want me to do? (retry later, wait until idle, force-stop, rephrase, or cancel)"
|
|
33
|
+
].join(" ");
|
|
34
|
+
var CLOUD_COORDINATOR_STOPPED_REPLY = [
|
|
35
|
+
"Sideboard force-stopped the in-progress global coordinator turn.",
|
|
36
|
+
"No new orchestration request was started."
|
|
37
|
+
].join(" ");
|
|
38
|
+
var CLOUD_COORDINATOR_TIMEOUT_REPLY = [
|
|
39
|
+
"Sideboard global coordinator timed out waiting for the local agent turn to finish.",
|
|
40
|
+
"I did not produce a full orchestration result.",
|
|
41
|
+
`To force-stop the in-progress turn, send another desktop request whose first line is exactly ${SIDEBOARD_FORCE_STOP}`,
|
|
42
|
+
"(optional follow-up request on later lines).",
|
|
43
|
+
"What do you want me to do? (retry later, wait, force-stop, rephrase, or cancel)"
|
|
44
|
+
].join(" ");
|
|
45
|
+
|
|
46
|
+
// src/store/global-workspace.ts
|
|
47
|
+
var GLOBAL_WORKSPACE_ID = "__global__";
|
|
48
|
+
function isGlobalThread(thread) {
|
|
49
|
+
return Boolean(thread && thread.repoPath === GLOBAL_WORKSPACE_ID);
|
|
50
|
+
}
|
|
51
|
+
function isGlobalRepoPath(repoPath) {
|
|
52
|
+
return repoPath === GLOBAL_WORKSPACE_ID;
|
|
53
|
+
}
|
|
54
|
+
function isOrchestratorThread(thread) {
|
|
55
|
+
return Boolean(
|
|
56
|
+
thread && (thread.sourceType === "orchestration" || isGlobalThread(thread))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
function orchestratorSessionPoisonedByBuiltins(thread) {
|
|
60
|
+
if (!thread?.messages?.length) return false;
|
|
61
|
+
let usedBuiltin = false;
|
|
62
|
+
let usedSideboardMcp = false;
|
|
63
|
+
for (const msg of thread.messages) {
|
|
64
|
+
for (const part of msg.parts ?? []) {
|
|
65
|
+
if (part.type !== "tool") continue;
|
|
66
|
+
if (part.name.startsWith("mcp__sideboard")) {
|
|
67
|
+
usedSideboardMcp = true;
|
|
68
|
+
} else if (part.name === "Bash" || part.name === "Edit" || part.name === "Write" || part.name === "Read" || part.name === "Glob" || part.name === "Grep") {
|
|
69
|
+
usedBuiltin = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return usedBuiltin && !usedSideboardMcp;
|
|
74
|
+
}
|
|
75
|
+
function isCloudCoordinatorThread(thread) {
|
|
76
|
+
if (thread.sourceRef === CLOUD_ORCHESTRATOR_GOAL) {
|
|
77
|
+
return isGlobalThread(thread) || thread.sourceType === "orchestration";
|
|
78
|
+
}
|
|
79
|
+
if (thread.title === CLOUD_ORCHESTRATOR_GOAL) {
|
|
80
|
+
return isGlobalThread(thread) || thread.sourceType === "orchestration";
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
function orchestrationTitleNeedsSoccerNickname(thread) {
|
|
85
|
+
if (!isOrchestratorThread(thread)) return false;
|
|
86
|
+
const title = thread.title?.trim() ?? "";
|
|
87
|
+
if (teamSlugFromName(title)) return false;
|
|
88
|
+
if (title === CLOUD_ORCHESTRATOR_GOAL) return true;
|
|
89
|
+
if (!title || title === "Untitled") return true;
|
|
90
|
+
if (thread.userSetTitle) return false;
|
|
91
|
+
if (thread.sourceRef?.trim() && title === thread.sourceRef.trim()) return true;
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
function takenTeamSlugsForOrchestration() {
|
|
95
|
+
const taken = /* @__PURE__ */ new Set(["global"]);
|
|
96
|
+
for (const thread of listThreads({ includeArchived: true })) {
|
|
97
|
+
if (thread.status === "archived") continue;
|
|
98
|
+
for (const slug of takenSlugsFromThread(thread)) {
|
|
99
|
+
taken.add(slug);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return [...taken];
|
|
103
|
+
}
|
|
104
|
+
function createGlobalChat(opts) {
|
|
105
|
+
ensureGlobalCoordinatorCwd();
|
|
106
|
+
const isCloud = opts.sourceRef === CLOUD_ORCHESTRATOR_GOAL || opts.title?.trim() === CLOUD_ORCHESTRATOR_GOAL;
|
|
107
|
+
const explicit = opts.title?.trim();
|
|
108
|
+
const title = explicit && explicit !== CLOUD_ORCHESTRATOR_GOAL ? explicit : allocateTeamName(takenTeamSlugsForOrchestration()).name;
|
|
109
|
+
const sourceRef = opts.sourceRef?.trim() || (isCloud ? CLOUD_ORCHESTRATOR_GOAL : title);
|
|
110
|
+
const agent = assertOrchestratorCapableAgent(opts.agent);
|
|
111
|
+
const thread = createEmptyThread({
|
|
112
|
+
title,
|
|
113
|
+
// Stick nicknames the same way chat tabs do (avoid later sync overwrites).
|
|
114
|
+
userSetTitle: true,
|
|
115
|
+
sourceType: "orchestration",
|
|
116
|
+
sourceRef,
|
|
117
|
+
branchName: "global",
|
|
118
|
+
worktreePath: globalAgentCwd(),
|
|
119
|
+
repoPath: GLOBAL_WORKSPACE_ID,
|
|
120
|
+
agent,
|
|
121
|
+
autonomy: opts.autonomy ?? "default",
|
|
122
|
+
model: opts.model ?? null,
|
|
123
|
+
effort: opts.effort ?? "high",
|
|
124
|
+
fast: Boolean(opts.fast),
|
|
125
|
+
planMode: Boolean(opts.planMode),
|
|
126
|
+
attachments: opts.attachments ?? [],
|
|
127
|
+
parentThreadId: opts.parentThreadId ?? null,
|
|
128
|
+
status: "idle"
|
|
129
|
+
});
|
|
130
|
+
writeThread(thread);
|
|
131
|
+
return thread;
|
|
132
|
+
}
|
|
133
|
+
function healOrchestrationSoccerTitles() {
|
|
134
|
+
let healed = 0;
|
|
135
|
+
const taken = new Set(takenTeamSlugsForOrchestration());
|
|
136
|
+
for (const thread of listThreads({ includeArchived: true })) {
|
|
137
|
+
if (thread.status === "archived") continue;
|
|
138
|
+
if (!orchestrationTitleNeedsSoccerNickname(thread)) continue;
|
|
139
|
+
const team = allocateTeamName(taken);
|
|
140
|
+
taken.add(team.slug);
|
|
141
|
+
updateThread(thread.id, { title: team.name, userSetTitle: true });
|
|
142
|
+
healed += 1;
|
|
143
|
+
}
|
|
144
|
+
return healed;
|
|
145
|
+
}
|
|
146
|
+
function listGlobalThreads(includeArchived = false) {
|
|
147
|
+
return listThreads({ includeArchived }).filter(
|
|
148
|
+
(t) => t.repoPath === GLOBAL_WORKSPACE_ID
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
function findCloudCoordinator() {
|
|
152
|
+
return listThreads({ includeArchived: true }).find(
|
|
153
|
+
(t) => t.status !== "archived" && isCloudCoordinatorThread(t)
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
function ensureCloudCoordinator(agent) {
|
|
157
|
+
const existing = findCloudCoordinator();
|
|
158
|
+
if (existing) {
|
|
159
|
+
if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
|
|
160
|
+
return updateThread(existing.id, {
|
|
161
|
+
repoPath: GLOBAL_WORKSPACE_ID,
|
|
162
|
+
worktreePath: globalAgentCwd(),
|
|
163
|
+
branchName: "global"
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return existing;
|
|
167
|
+
}
|
|
168
|
+
const created = createGlobalChat({
|
|
169
|
+
sourceRef: CLOUD_ORCHESTRATOR_GOAL,
|
|
170
|
+
agent
|
|
171
|
+
});
|
|
172
|
+
const all = listThreads({ includeArchived: true }).filter(
|
|
173
|
+
(t) => t.status !== "archived" && isCloudCoordinatorThread(t)
|
|
174
|
+
).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
175
|
+
return all[0] ?? created;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export {
|
|
179
|
+
GLOBAL_WORKSPACE_ID,
|
|
180
|
+
isGlobalThread,
|
|
181
|
+
isGlobalRepoPath,
|
|
182
|
+
isOrchestratorThread,
|
|
183
|
+
orchestratorSessionPoisonedByBuiltins,
|
|
184
|
+
isCloudCoordinatorThread,
|
|
185
|
+
orchestrationTitleNeedsSoccerNickname,
|
|
186
|
+
takenTeamSlugsForOrchestration,
|
|
187
|
+
createGlobalChat,
|
|
188
|
+
healOrchestrationSoccerTitles,
|
|
189
|
+
listGlobalThreads,
|
|
190
|
+
ensureCloudCoordinator
|
|
191
|
+
};
|