@bridge_gpt/mcp-server 0.2.49 → 0.2.50

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 (47) hide show
  1. package/README.md +24 -7
  2. package/build/base-ref.js +28 -3
  3. package/build/claude-review-workflow-drift-probe.js +130 -0
  4. package/build/claude-review-workflow-drift.js +173 -0
  5. package/build/claude-review-workflow.js +81 -16
  6. package/build/commands.generated.js +5 -5
  7. package/build/conductor/done-gate.js +25 -3
  8. package/build/conductor/install-doctor.js +65 -5
  9. package/build/conductor/latest-check-selector.js +170 -0
  10. package/build/conductor/local-merge.js +8 -6
  11. package/build/conductor-bin.js +1 -1
  12. package/build/{brainstorm-files.js → council-files.js} +15 -15
  13. package/build/decision-page-schema.js +1 -1
  14. package/build/docs.generated.js +1 -1
  15. package/build/doctor.js +162 -4
  16. package/build/executor/worktree.js +46 -1
  17. package/build/index.js +92 -51
  18. package/build/init.js +9 -2
  19. package/build/install-bridge.js +60 -2
  20. package/build/install-reexec.js +47 -9
  21. package/build/pipelines.generated.js +1 -1
  22. package/build/plane/cli.js +12 -2
  23. package/build/plane/manifest.js +25 -1
  24. package/build/plane/member-roster.js +61 -7
  25. package/build/plane/preflight.js +24 -9
  26. package/build/plane/supervisor.js +77 -5
  27. package/build/plane/types.js +23 -3
  28. package/build/readme.generated.js +1 -1
  29. package/build/run-unit-tests-launcher.js +2 -1
  30. package/build/stale-worktree-doctor.js +120 -0
  31. package/build/start-tickets-prereqs.js +70 -0
  32. package/build/start-tickets.js +91 -3
  33. package/build/version.generated.js +3 -2
  34. package/package.json +4 -2
  35. package/build/chain-orchestrator.js +0 -1457
  36. package/build/chain-utils.js +0 -68
  37. package/build/command-catalog.js +0 -376
  38. package/build/schedule-run.js +0 -1300
  39. package/build/schedule-store.js +0 -172
  40. package/build/scheduled-prompt.js +0 -115
  41. package/build/scheduler-backends/at-fallback.js +0 -139
  42. package/build/scheduler-backends/escaping.js +0 -143
  43. package/build/scheduler-backends/index.js +0 -72
  44. package/build/scheduler-backends/launchd.js +0 -225
  45. package/build/scheduler-backends/systemd-user.js +0 -250
  46. package/build/scheduler-backends/task-scheduler.js +0 -214
  47. package/build/scheduler-backends/types.js +0 -23
@@ -1,214 +0,0 @@
1
- /**
2
- * Windows Task Scheduler backend (BAPI-327).
3
- *
4
- * Generates a `.cmd` wrapper (baked PATH + env, `cd /D <repo>`, absolute Claude
5
- * invocation, stdout/stderr redirection) plus a Task Scheduler `.xml` definition,
6
- * and registers a one-shot task via `schtasks /Create /XML`.
7
- *
8
- * Why XML instead of `/SC ONCE /SD /ST`: the CLI `/SD` date is parsed in the
9
- * host's short-date locale, so a hard-coded `MM/DD/YYYY` fails on UK/DE/JP/etc.
10
- * machines. The XML `<StartBoundary>` is ISO-8601 and locale-independent.
11
- *
12
- * Drift policy: the generated XML omits the missed-start catch-up element (its
13
- * schema default is already off), giving a real OS-level no-catch-up guarantee —
14
- * a missed start never runs late. (launchd and `at` cannot guarantee this; the
15
- * cross-backend staleness guard is the baked `--scheduled-at <T>` value checked by
16
- * `/full-automation` in Phase C.) Working directory is handled only by `cd /D`
17
- * inside the wrapper.
18
- */
19
- import { promises as fs } from "node:fs";
20
- import { pathApiForPlatform } from "./types.js";
21
- import { bakedEnvFromCreateInput, bakedEnvEntries, escapeWindowsCmdSetValue, windowsCmdQuote, xmlEscape, } from "./escaping.js";
22
- /** Task Scheduler task name for a NEW schedule id (neutral schedule-run naming). */
23
- export function taskNameForId(id) {
24
- return `BridgeGPT-ScheduleRun-${id}`;
25
- }
26
- /** `%USERPROFILE%\.bridge-gpt\schedules\<id>.cmd` wrapper path for a schedule id. */
27
- export function cmdWrapperPathForId(id, homeDir) {
28
- const pathApi = pathApiForPlatform("win32");
29
- return pathApi.join(homeDir, ".bridge-gpt", "schedules", `${id}.cmd`);
30
- }
31
- /** `%USERPROFILE%\.bridge-gpt\schedules\<id>.xml` task definition path. */
32
- export function taskXmlPathForId(id, homeDir) {
33
- const pathApi = pathApiForPlatform("win32");
34
- return pathApi.join(homeDir, ".bridge-gpt", "schedules", `${id}.xml`);
35
- }
36
- /**
37
- * Local ISO-8601 `<StartBoundary>` value (`YYYY-MM-DDTHH:MM:SS`, no `Z`). Task
38
- * Scheduler interprets a bare boundary as local time, preserving the prior
39
- * local-time scheduling semantics while staying locale-independent.
40
- */
41
- export function formatTaskSchedulerBoundary(runAtIso) {
42
- const d = new Date(runAtIso);
43
- const pad = (n) => String(n).padStart(2, "0");
44
- return (`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +
45
- `T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`);
46
- }
47
- /** Render the `.cmd` wrapper that the Task Scheduler task invokes. */
48
- export function renderWindowsCmdWrapper(input) {
49
- const env = bakedEnvEntries(bakedEnvFromCreateInput(input));
50
- const lines = ["@echo off"];
51
- for (const [key, value] of env) {
52
- if (key === "PATH") {
53
- // Prepend the baked PATH while preserving the runtime PATH behind it.
54
- lines.push(`set "PATH=${escapeWindowsCmdSetValue(value)};%PATH%"`);
55
- }
56
- else {
57
- lines.push(`set "${key}=${escapeWindowsCmdSetValue(value)}"`);
58
- }
59
- }
60
- lines.push(`cd /D ${windowsCmdQuote(input.repoPath)}`);
61
- // The wrapper runs the Node execution shim (trigger invocation), not the agent
62
- // binary directly; the shim spawns the stored agent invocation.
63
- const command = [input.triggerInvocation.exe, ...input.triggerInvocation.args]
64
- .map((part) => windowsCmdQuote(part))
65
- .join(" ");
66
- // Append stdout/stderr to the local schedule logs.
67
- lines.push(`${command} 1>>${windowsCmdQuote(input.paths.stdoutPath)} 2>>${windowsCmdQuote(input.paths.stderrPath)}`);
68
- lines.push("");
69
- return lines.join("\r\n");
70
- }
71
- /**
72
- * Render a minimal one-shot Task Scheduler XML document. The single `TimeTrigger`
73
- * fires once at the ISO-8601 `<StartBoundary>`; the action runs the generated
74
- * `.cmd` wrapper. The `<Settings>` block intentionally does not enable the
75
- * missed-start catch-up option, so a missed start never runs late.
76
- */
77
- export function renderTaskSchedulerXml(input) {
78
- const wrapperPath = cmdWrapperPathForId(input.id, input.deps.homeDir);
79
- const boundary = formatTaskSchedulerBoundary(input.runAtIso);
80
- return [
81
- '<?xml version="1.0" encoding="UTF-16"?>',
82
- '<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">',
83
- " <RegistrationInfo>",
84
- ` <Description>${xmlEscape(`Bridge GPT schedule-run one-shot (${input.id}: ${input.command})`)}</Description>`,
85
- " </RegistrationInfo>",
86
- " <Triggers>",
87
- " <TimeTrigger>",
88
- ` <StartBoundary>${xmlEscape(boundary)}</StartBoundary>`,
89
- " <Enabled>true</Enabled>",
90
- " </TimeTrigger>",
91
- " </Triggers>",
92
- " <Principals>",
93
- ' <Principal id="Author">',
94
- " <LogonType>InteractiveToken</LogonType>",
95
- " </Principal>",
96
- " </Principals>",
97
- " <Settings>",
98
- " <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>",
99
- " <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>",
100
- " <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>",
101
- " <Enabled>true</Enabled>",
102
- " </Settings>",
103
- ' <Actions Context="Author">',
104
- " <Exec>",
105
- ` <Command>${xmlEscape(wrapperPath)}</Command>`,
106
- " </Exec>",
107
- " </Actions>",
108
- "</Task>",
109
- "",
110
- ].join("\r\n");
111
- }
112
- /** Whether `schtasks` is resolvable (used by isAvailable). */
113
- async function schtasksResolvable(deps) {
114
- const probe = await deps.runCommand("where.exe", ["schtasks"]);
115
- return probe.exitCode === 0;
116
- }
117
- /** Create the Windows Task Scheduler backend. */
118
- export function createTaskSchedulerBackend() {
119
- return {
120
- name: "task-scheduler",
121
- async isAvailable(deps) {
122
- if (deps.platform !== "win32")
123
- return false;
124
- return schtasksResolvable(deps);
125
- },
126
- async create(input) {
127
- const wrapperPath = cmdWrapperPathForId(input.id, input.deps.homeDir);
128
- const xmlPath = taskXmlPathForId(input.id, input.deps.homeDir);
129
- const wrapperContent = renderWindowsCmdWrapper(input);
130
- const xmlContent = renderTaskSchedulerXml(input);
131
- const artifacts = [
132
- { path: wrapperPath, content: wrapperContent, kind: "windows-cmd-wrapper" },
133
- { path: xmlPath, content: xmlContent, kind: "task-scheduler-xml" },
134
- ];
135
- const taskName = taskNameForId(input.id);
136
- const unitPaths = [wrapperPath, xmlPath];
137
- if (input.dryRun) {
138
- return {
139
- ok: true,
140
- backend: "task-scheduler",
141
- unitPath: wrapperPath,
142
- unitPaths,
143
- backendJobId: taskName,
144
- artifacts,
145
- };
146
- }
147
- await fs.writeFile(wrapperPath, wrapperContent, "utf-8");
148
- // schtasks /XML requires the definition file to be UTF-16 with a BOM.
149
- await fs.writeFile(xmlPath, `${xmlContent}`, "utf16le");
150
- const result = await input.deps.runCommand("schtasks", [
151
- "/Create",
152
- "/TN",
153
- taskName,
154
- "/XML",
155
- xmlPath,
156
- "/F",
157
- ]);
158
- if (result.exitCode !== 0) {
159
- // Don't leave the orphaned wrapper + XML behind when registration fails.
160
- await fs.unlink(wrapperPath).catch(() => undefined);
161
- await fs.unlink(xmlPath).catch(() => undefined);
162
- return {
163
- ok: false,
164
- backend: "task-scheduler",
165
- unitPath: wrapperPath,
166
- unitPaths,
167
- backendJobId: taskName,
168
- artifacts,
169
- error: `schtasks /Create failed: ${(result.stderr || result.stdout).trim()}`,
170
- };
171
- }
172
- return {
173
- ok: true,
174
- backend: "task-scheduler",
175
- unitPath: wrapperPath,
176
- unitPaths,
177
- backendJobId: taskName,
178
- artifacts,
179
- };
180
- },
181
- async list(input) {
182
- const entries = [];
183
- for (const metadata of input.recorded) {
184
- const taskName = metadata.backend_job_id ?? taskNameForId(metadata.id);
185
- const query = await input.deps.runCommand("schtasks", ["/Query", "/TN", taskName]);
186
- entries.push({
187
- metadata,
188
- status: query.exitCode === 0 ? "active" : "stale",
189
- detail: query.exitCode === 0 ? "task registered" : "task not found",
190
- });
191
- }
192
- return entries;
193
- },
194
- async cancel(input) {
195
- const taskName = input.metadata.backend_job_id ?? taskNameForId(input.metadata.id);
196
- const result = await input.deps.runCommand("schtasks", ["/Delete", "/TN", taskName, "/F"]);
197
- // Remove the generated wrapper + XML definition; both are ENOENT-tolerant.
198
- const wrapperPath = input.metadata.unit_path ?? cmdWrapperPathForId(input.metadata.id, input.deps.homeDir);
199
- const xmlPath = taskXmlPathForId(input.metadata.id, input.deps.homeDir);
200
- for (const artifactPath of [wrapperPath, xmlPath]) {
201
- try {
202
- await fs.unlink(artifactPath);
203
- }
204
- catch (error) {
205
- if (error.code !== "ENOENT") {
206
- return { ok: false, nativeRemoved: result.exitCode === 0, stale: false, error: String(error) };
207
- }
208
- }
209
- }
210
- const nativeRemoved = result.exitCode === 0;
211
- return { ok: true, nativeRemoved, stale: !nativeRemoved };
212
- },
213
- };
214
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * Shared contract for the cross-platform `schedule-run` scheduler backends
3
- * (BAPI-327 / Phase B of the Full Automation v1 epic, BAPI-325).
4
- *
5
- * Every OS-native backend (launchd, Task Scheduler, systemd-user, at-fallback)
6
- * implements the {@link SchedulerBackend} interface against an injected
7
- * {@link SchedulerBackendDeps} so the create/list/cancel logic is fully unit
8
- * testable without touching real schedulers, the filesystem, or the network.
9
- *
10
- * The design mirrors `start-tickets.ts`: a list-based {@link RunCommand} boundary
11
- * (`execFile`, never `shell: true`), `platform`/`env`/`cwd`/`homeDir`/`execPath`
12
- * captured as data, and an optional injectable clock for deterministic tests.
13
- */
14
- import path from "node:path";
15
- /**
16
- * Return the platform-appropriate Node path API: `path.win32` on Windows so
17
- * generated unit paths use backslashes, `path.posix` everywhere else. Using a
18
- * data-driven platform (not the ambient `process.platform`) keeps generation
19
- * deterministic and unit-testable for every OS from any host.
20
- */
21
- export function pathApiForPlatform(platform) {
22
- return platform === "win32" ? path.win32 : path.posix;
23
- }