@buoy-design/cli 0.4.0 → 0.5.0

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -21
  3. package/dist/bin.js +0 -0
  4. package/dist/cloud/config.d.ts +5 -0
  5. package/dist/cloud/config.d.ts.map +1 -1
  6. package/dist/cloud/config.js.map +1 -1
  7. package/dist/commands/ignore.d.ts +7 -3
  8. package/dist/commands/ignore.d.ts.map +1 -1
  9. package/dist/commands/ignore.js +81 -78
  10. package/dist/commands/ignore.js.map +1 -1
  11. package/dist/commands/index.d.ts +1 -0
  12. package/dist/commands/index.d.ts.map +1 -1
  13. package/dist/commands/index.js +1 -0
  14. package/dist/commands/index.js.map +1 -1
  15. package/dist/commands/login.d.ts.map +1 -1
  16. package/dist/commands/login.js +108 -33
  17. package/dist/commands/login.js.map +1 -1
  18. package/dist/commands/rescue.d.ts +3 -0
  19. package/dist/commands/rescue.d.ts.map +1 -0
  20. package/dist/commands/rescue.js +147 -0
  21. package/dist/commands/rescue.js.map +1 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +5 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/rescue/report.d.ts +9 -0
  26. package/dist/rescue/report.d.ts.map +1 -0
  27. package/dist/rescue/report.js +107 -0
  28. package/dist/rescue/report.js.map +1 -0
  29. package/dist/rescue/store.d.ts +9 -0
  30. package/dist/rescue/store.d.ts.map +1 -0
  31. package/dist/rescue/store.js +50 -0
  32. package/dist/rescue/store.js.map +1 -0
  33. package/dist/rescue/types.d.ts +76 -0
  34. package/dist/rescue/types.d.ts.map +1 -0
  35. package/dist/rescue/types.js +2 -0
  36. package/dist/rescue/types.js.map +1 -0
  37. package/dist/rescue/workflow.d.ts +37 -0
  38. package/dist/rescue/workflow.d.ts.map +1 -0
  39. package/dist/rescue/workflow.js +355 -0
  40. package/dist/rescue/workflow.js.map +1 -0
  41. package/dist/services/drift-analysis.d.ts +3 -1
  42. package/dist/services/drift-analysis.d.ts.map +1 -1
  43. package/dist/services/drift-analysis.js +179 -98
  44. package/dist/services/drift-analysis.js.map +1 -1
  45. package/dist/utils/upgrade-hints.d.ts +13 -2
  46. package/dist/utils/upgrade-hints.d.ts.map +1 -1
  47. package/dist/utils/upgrade-hints.js +43 -5
  48. package/dist/utils/upgrade-hints.js.map +1 -1
  49. package/package.json +14 -14
@@ -7,6 +7,8 @@ import { Command } from 'commander';
7
7
  import { createInterface } from 'readline';
8
8
  import { exec } from 'child_process';
9
9
  import { promisify } from 'util';
10
+ import { createServer } from 'http';
11
+ import { hostname } from 'os';
10
12
  import { updateCloudConfig, isLoggedIn, getApiEndpoint, readCloudConfig, } from '../cloud/config.js';
11
13
  import { getMe } from '../cloud/client.js';
12
14
  import { spinner, error, info, warning, keyValue, newline } from '../output/reporters.js';
@@ -29,21 +31,6 @@ async function openBrowser(url) {
29
31
  }
30
32
  await execAsync(command);
31
33
  }
32
- /**
33
- * Prompt for input
34
- */
35
- function prompt(question) {
36
- const rl = createInterface({
37
- input: process.stdin,
38
- output: process.stdout,
39
- });
40
- return new Promise((resolve) => {
41
- rl.question(question, (answer) => {
42
- rl.close();
43
- resolve(answer.trim());
44
- });
45
- });
46
- }
47
34
  /**
48
35
  * Validate API token by fetching user info
49
36
  */
@@ -63,6 +50,86 @@ async function validateToken(token) {
63
50
  account: result.data.account,
64
51
  };
65
52
  }
53
+ /**
54
+ * Listen on a random loopback port for the dashboard to POST the token.
55
+ * Resolves with the token, or null if the server could not start.
56
+ */
57
+ function waitForTokenOnLoopback() {
58
+ let resolveToken = () => { };
59
+ const token = new Promise((resolve) => { resolveToken = resolve; });
60
+ const server = createServer((req, res) => {
61
+ // Only the dashboard origin should be talking to us; answer preflight so
62
+ // the browser allows the cross-origin POST from app.buoy.design.
63
+ res.setHeader('Access-Control-Allow-Origin', '*');
64
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
65
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
66
+ if (req.method === 'OPTIONS') {
67
+ res.writeHead(204);
68
+ res.end();
69
+ return;
70
+ }
71
+ if (req.method !== 'POST' || req.url !== '/token') {
72
+ res.writeHead(404);
73
+ res.end();
74
+ return;
75
+ }
76
+ let body = '';
77
+ req.on('data', (chunk) => { body += chunk; if (body.length > 4096)
78
+ req.destroy(); });
79
+ req.on('end', () => {
80
+ try {
81
+ const parsed = JSON.parse(body);
82
+ if (parsed.token && parsed.token.startsWith('buoy_')) {
83
+ res.writeHead(200, { 'Content-Type': 'application/json' });
84
+ res.end('{"ok":true}');
85
+ resolveToken(parsed.token);
86
+ return;
87
+ }
88
+ }
89
+ catch { /* fall through */ }
90
+ res.writeHead(400);
91
+ res.end();
92
+ });
93
+ });
94
+ let url = null;
95
+ try {
96
+ server.listen(0, '127.0.0.1');
97
+ const addr = server.address();
98
+ if (addr && typeof addr === 'object')
99
+ url = `http://127.0.0.1:${addr.port}/token`;
100
+ }
101
+ catch {
102
+ url = null;
103
+ }
104
+ return { url, token, close: () => { try {
105
+ server.close();
106
+ }
107
+ catch { /* ignore */ } } };
108
+ }
109
+ /**
110
+ * Race a terminal prompt against the loopback listener. Whichever supplies a
111
+ * token first wins; the readline prompt is closed either way.
112
+ */
113
+ function promptOrLoopback(question, loopbackToken) {
114
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
115
+ return new Promise((resolve) => {
116
+ let done = false;
117
+ const finish = (value) => {
118
+ if (done)
119
+ return;
120
+ done = true;
121
+ rl.close();
122
+ resolve(value.trim());
123
+ };
124
+ rl.question(question, finish);
125
+ loopbackToken.then((t) => {
126
+ if (!done) {
127
+ process.stdout.write('\n');
128
+ finish(t);
129
+ }
130
+ });
131
+ });
132
+ }
66
133
  export function createLoginCommand() {
67
134
  const cmd = new Command('login');
68
135
  cmd
@@ -87,34 +154,42 @@ export function createLoginCommand() {
87
154
  token = options.token;
88
155
  }
89
156
  else {
90
- // Interactive login/signup flow
157
+ // Interactive login/signup flow. The dashboard's /cli-auth page mints
158
+ // an API key and POSTs it back to a loopback listener, so pasting is
159
+ // only the fallback.
91
160
  const endpoint = getApiEndpoint();
92
- const isSignup = options.signup;
93
- const authPath = isSignup ? '/signup?source=cli' : '/cli-auth';
94
- const authUrl = `${endpoint.replace('api.', 'app.')}${authPath}`;
161
+ const appOrigin = endpoint.replace('api.', 'app.');
162
+ const listener = waitForTokenOnLoopback();
163
+ const params = new URLSearchParams({ host: hostname() });
164
+ if (listener.url)
165
+ params.set('callback', listener.url);
166
+ const cliAuthPath = `/cli-auth?${params.toString()}`;
167
+ const authUrl = options.signup
168
+ ? `${appOrigin}/sign-up?redirect_url=${encodeURIComponent(cliAuthPath)}`
169
+ : `${appOrigin}${cliAuthPath}`;
95
170
  newline();
96
- if (isSignup) {
97
- info('Opening browser to create your Buoy account...');
98
- info('After signup, you\'ll get an API token to paste here.');
99
- }
100
- else {
101
- info('Opening browser to authenticate with Buoy Cloud...');
102
- }
171
+ info(options.signup
172
+ ? 'Opening browser to create your Buoy account...'
173
+ : 'Opening browser to connect the CLI to Buoy Cloud...');
103
174
  newline();
104
175
  if (options.browser !== false) {
105
176
  try {
106
177
  await openBrowser(authUrl);
107
- info('Browser opened. Complete authentication there.');
178
+ info('Browser opened. Approve the key there and this terminal will continue.');
108
179
  }
109
180
  catch {
110
181
  warning('Could not open browser automatically.');
111
182
  }
112
183
  }
113
184
  newline();
114
- info(`If browser didn't open, visit: ${authUrl}`);
185
+ info(`If the browser didn't open, visit: ${authUrl}`);
115
186
  newline();
116
- // Prompt for token
117
- token = await prompt('Paste your API token here: ');
187
+ try {
188
+ token = await promptOrLoopback('Waiting for the browser (or paste the key here): ', listener.token);
189
+ }
190
+ finally {
191
+ listener.close();
192
+ }
118
193
  if (!token) {
119
194
  error('No token provided. Login cancelled.');
120
195
  process.exit(1);
@@ -143,9 +218,9 @@ export function createLoginCommand() {
143
218
  keyValue('Plan', validation.account?.plan || 'free');
144
219
  newline();
145
220
  info('You can now use:');
146
- info(' buoy link - Connect this project to Buoy Cloud');
147
- info(' buoy whoami - Show current user');
148
- info(' buoy logout - Sign out');
221
+ info(' buoy ahoy github - Set up the GitHub PR bot');
222
+ info(' buoy ahoy status - Show current account');
223
+ info(' buoy ahoy logout - Sign out');
149
224
  });
150
225
  return cmd;
151
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function createRescueCommand(): Command;
3
+ //# sourceMappingURL=rescue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rescue.d.ts","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,wBAAgB,mBAAmB,IAAI,OAAO,CA8L7C"}
@@ -0,0 +1,147 @@
1
+ import { Command } from "commander";
2
+ import { error, header, info, keyValue, newline, setJsonMode, spinner, success, warning, } from "../output/reporters.js";
3
+ import { applyRescuePlan, createRescuePlan, guardRescueRun, reportRescueRun, rollbackRescueRun, verifyRescueRun, } from "../rescue/workflow.js";
4
+ import { rescueRunDir } from "../rescue/store.js";
5
+ function failure(cause) {
6
+ error(cause instanceof Error ? cause.message : String(cause));
7
+ process.exitCode = 1;
8
+ }
9
+ export function createRescueCommand() {
10
+ const command = new Command("rescue").description("Measure, repair, guard, and prove design-system health");
11
+ command
12
+ .command("plan", { isDefault: true })
13
+ .description("Create a read-only Rescue baseline and repair plan")
14
+ .option("--json", "Output the plan as JSON")
15
+ .action(async (options) => {
16
+ if (options.json)
17
+ setJsonMode(true);
18
+ const spin = spinner("Building Rescue plan...");
19
+ try {
20
+ const manifest = await createRescuePlan(process.cwd(), (message) => {
21
+ spin.text = message;
22
+ });
23
+ spin.stop();
24
+ if (options.json) {
25
+ console.log(JSON.stringify(manifest, null, 2));
26
+ return;
27
+ }
28
+ header("Buoy Rescue plan");
29
+ newline();
30
+ keyValue("Run", manifest.id);
31
+ keyValue("Findings", String(manifest.before.summary.total));
32
+ keyValue("High-confidence fixes", String(manifest.safeFixes.length));
33
+ keyValue("Review required", String(manifest.findings.filter((item) => item.classification === "review-required").length));
34
+ keyValue("Artifacts", rescueRunDir(manifest.projectRoot, manifest.id));
35
+ newline();
36
+ info(`Review report.html, then run \`buoy rescue apply --run ${manifest.id} --approve\`.`);
37
+ }
38
+ catch (cause) {
39
+ spin.stop();
40
+ failure(cause);
41
+ }
42
+ });
43
+ command
44
+ .command("apply")
45
+ .description("Apply approved high-confidence fixes on a new branch")
46
+ .option("--run <id>", "Rescue run ID (defaults to latest)")
47
+ .requiredOption("--approve", "Confirm that the generated plan has been reviewed")
48
+ .option("--limit <count>", "Maximum fixes to apply", (value) => Number.parseInt(value, 10))
49
+ .action(async (options) => {
50
+ const spin = spinner("Applying approved Rescue fixes...");
51
+ try {
52
+ const manifest = await applyRescuePlan(process.cwd(), options.run, { limit: options.limit }, (message) => {
53
+ spin.text = message;
54
+ });
55
+ spin.stop();
56
+ success(`${manifest.appliedFixIds.length} high-confidence fix(es) applied on ${manifest.rescueBranch}.`);
57
+ if (manifest.verification?.skipped) {
58
+ warning("No test or typecheck scripts were detected. Manual verification is still required.");
59
+ }
60
+ else {
61
+ success("Project verification passed.");
62
+ }
63
+ info(`Review ${rescueRunDir(manifest.projectRoot, manifest.id)}/report.html before committing.`);
64
+ }
65
+ catch (cause) {
66
+ spin.stop();
67
+ failure(cause);
68
+ }
69
+ });
70
+ command
71
+ .command("verify")
72
+ .description("Run project checks and refresh the before/after report")
73
+ .option("--run <id>", "Rescue run ID (defaults to latest)")
74
+ .action(async (options) => {
75
+ const spin = spinner("Verifying Rescue changes...");
76
+ try {
77
+ const manifest = await verifyRescueRun(process.cwd(), options.run, (message) => {
78
+ spin.text = message;
79
+ });
80
+ spin.stop();
81
+ if (manifest.verification?.passed)
82
+ success("Rescue verification passed.");
83
+ else if (manifest.verification?.skipped)
84
+ warning("No automated project checks were detected.");
85
+ else
86
+ failure("Rescue verification failed. Review the report before proceeding.");
87
+ }
88
+ catch (cause) {
89
+ spin.stop();
90
+ failure(cause);
91
+ }
92
+ });
93
+ command
94
+ .command("guard")
95
+ .description("Record reviewed legacy drift so checks focus on new violations")
96
+ .option("--run <id>", "Rescue run ID (defaults to latest)")
97
+ .requiredOption("--reason <reason>", "Why the remaining legacy drift is accepted")
98
+ .option("--actor <name>", "Person or team approving the baseline")
99
+ .action(async (options) => {
100
+ const spin = spinner("Recording reviewed legacy drift...");
101
+ try {
102
+ const manifest = await guardRescueRun(process.cwd(), options.run, options.reason, options.actor, (message) => {
103
+ spin.text = message;
104
+ });
105
+ spin.stop();
106
+ success(`${manifest.baseline?.count || 0} legacy finding(s) recorded with stable fingerprints.`);
107
+ info("Future drift checks focus on newly introduced violations.");
108
+ }
109
+ catch (cause) {
110
+ spin.stop();
111
+ failure(cause);
112
+ }
113
+ });
114
+ command
115
+ .command("report")
116
+ .description("Regenerate JSON, Markdown, and HTML Rescue reports")
117
+ .option("--run <id>", "Rescue run ID (defaults to latest)")
118
+ .action(async (options) => {
119
+ try {
120
+ const { paths } = await reportRescueRun(process.cwd(), options.run);
121
+ success("Rescue reports generated.");
122
+ keyValue("HTML", paths.html);
123
+ keyValue("Markdown", paths.markdown);
124
+ keyValue("JSON", paths.json);
125
+ }
126
+ catch (cause) {
127
+ failure(cause);
128
+ }
129
+ });
130
+ command
131
+ .command("rollback")
132
+ .description("Restore files saved before Rescue apply")
133
+ .option("--run <id>", "Rescue run ID (defaults to latest)")
134
+ .option("--force", "Overwrite files changed after Rescue apply")
135
+ .action(async (options) => {
136
+ try {
137
+ const manifest = await rollbackRescueRun(process.cwd(), options.run, options.force);
138
+ success(`Restored ${manifest.backups.length} file(s) from local Rescue backups.`);
139
+ info("The Rescue branch was retained for inspection and can be deleted manually.");
140
+ }
141
+ catch (cause) {
142
+ failure(cause);
143
+ }
144
+ });
145
+ return command;
146
+ }
147
+ //# sourceMappingURL=rescue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rescue.js","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,SAAS,IAAI,OAAO,CA6CnC;AAGD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,SAAS,IAAI,OAAO,CAkDnC;AAGD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import pkg from "../package.json" with { type: "json" };
3
- import { createShowCommand, createDriftCommand, createDockCommand, createAhoyCommand, createDesignMdCommand, createSystemCommand, } from "./commands/index.js";
3
+ import { createShowCommand, createDriftCommand, createDockCommand, createAhoyCommand, createDesignMdCommand, createSystemCommand, createRescueCommand, } from "./commands/index.js";
4
4
  export function createCli() {
5
5
  const program = new Command();
6
6
  program
@@ -14,6 +14,7 @@ export function createCli() {
14
14
  .addHelpText("after", `
15
15
  Command Groups:
16
16
  View show (components, tokens, drift, health, history, config, skills, agents, context, hooks, commands, graph, plugins, all), system
17
+ Product Journey rescue (plan, apply, verify, guard, report, rollback)
17
18
  Drift Actions drift (scan, check, fix, ignore)
18
19
  Setup dock (config, skills, agents, context, hooks, commands, plugins, tokens, graph)
19
20
  Cloud ahoy (login, logout, status, github, gitlab, billing, plans)
@@ -22,11 +23,14 @@ Command Groups:
22
23
  Quick Start:
23
24
  $ buoy show all # everything an AI agent needs
24
25
  $ buoy show drift # design system violations
26
+ $ buoy rescue plan # baseline and safe repair plan
25
27
  $ buoy dock # set up config, skills, agents, hooks
26
28
  `);
27
29
  // === View (read-only) ===
28
30
  program.addCommand(createShowCommand());
29
31
  program.addCommand(createSystemCommand());
32
+ // === Complete product journey ===
33
+ program.addCommand(createRescueCommand());
30
34
  // === Drift Actions ===
31
35
  program.addCommand(createDriftCommand());
32
36
  // === Setup ===
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxD,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,kDAAkD,CAAC;SAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;SACpB,aAAa,CAAC;QACb,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE;KACpC,CAAC;SACD,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;CAYL,CACI,CAAC;IAEJ,2BAA2B;IAC3B,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAE1C,wBAAwB;IACxB,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEzC,gBAAgB;IAChB,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAExC,gBAAgB;IAChB,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAExC,iBAAiB;IACjB,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAE5C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mDAAmD;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxD,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,kDAAkD,CAAC;SAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;SACpB,aAAa,CAAC;QACb,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE;KACpC,CAAC;SACD,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;CAcL,CACI,CAAC;IAEJ,2BAA2B;IAC3B,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAE1C,mCAAmC;IACnC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAE1C,wBAAwB;IACxB,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEzC,gBAAgB;IAChB,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAExC,gBAAgB;IAChB,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAExC,iBAAiB;IACjB,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAE5C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mDAAmD;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { RescueManifest } from "./types.js";
2
+ export declare function renderRescueMarkdown(manifest: RescueManifest): string;
3
+ export declare function renderRescueHtml(manifest: RescueManifest): string;
4
+ export declare function writeRescueReports(manifest: RescueManifest): Promise<{
5
+ json: string;
6
+ markdown: string;
7
+ html: string;
8
+ }>;
9
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/rescue/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,YAAY,CAAC;AAoBhE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAsDrE;AAWD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAsBjE;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAaD"}
@@ -0,0 +1,107 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { rescueRunDir } from "./store.js";
4
+ function summaryTable(before, after) {
5
+ const rows = [
6
+ ["Total", before.total, after?.total],
7
+ ["Critical", before.critical, after?.critical],
8
+ ["Warning", before.warning, after?.warning],
9
+ ["Info", before.info, after?.info],
10
+ ];
11
+ return [
12
+ "| Finding | Before | After | Change |",
13
+ "| --- | ---: | ---: | ---: |",
14
+ ...rows.map(([label, start, end]) => {
15
+ const afterValue = typeof end === "number" ? end : "—";
16
+ const delta = typeof end === "number" ? end - Number(start) : "—";
17
+ return `| ${label} | ${start} | ${afterValue} | ${typeof delta === "number" && delta > 0 ? "+" : ""}${delta} |`;
18
+ }),
19
+ ].join("\n");
20
+ }
21
+ export function renderRescueMarkdown(manifest) {
22
+ const reviewRequired = manifest.findings.filter((finding) => finding.classification === "review-required").length;
23
+ const acceptedLegacy = manifest.findings.filter((finding) => finding.classification === "accepted-legacy").length;
24
+ const verification = manifest.verification;
25
+ const checks = verification?.commands.length
26
+ ? verification.commands
27
+ .map((command) => `- ${command.passed ? "Passed" : "Failed"}: \`${command.command} ${command.args.join(" ")}\``)
28
+ .join("\n")
29
+ : "- No project test or typecheck scripts were detected; manual verification is required.";
30
+ return `# Buoy Rescue report
31
+
32
+ Run: \`${manifest.id}\`
33
+ Status: **${manifest.status}**
34
+ Generated: ${manifest.updatedAt}
35
+
36
+ ## Outcome
37
+
38
+ ${summaryTable(manifest.before.summary, manifest.after?.summary)}
39
+
40
+ - High-confidence fixes proposed: ${manifest.safeFixes.length}
41
+ - Fixes applied: ${manifest.appliedFixIds.length}
42
+ - Findings requiring review: ${reviewRequired}
43
+ - Findings already accepted as legacy: ${acceptedLegacy}
44
+
45
+ ## Verification
46
+
47
+ ${checks}
48
+
49
+ ${manifest.status === "verification_failed"
50
+ ? "Rescue restored every edited source file after the failed check. The branch and evidence remain for inspection."
51
+ : ""}
52
+
53
+ ## Guardrail
54
+
55
+ ${manifest.baseline
56
+ ? `Remaining legacy drift was recorded at \`${manifest.baseline.path}\` with reason: ${manifest.baseline.reason}`
57
+ : 'No legacy baseline was created by this run. Use `buoy rescue guard --reason "…"` after reviewing the remaining findings.'}
58
+
59
+ ## Safety and privacy
60
+
61
+ Buoy Rescue runs against local files. This run did not commit, push, merge, or upload source code. Ambiguous findings remain review-required, and backups are retained locally for rollback.
62
+ `;
63
+ }
64
+ function escapeHtml(value) {
65
+ return value
66
+ .replaceAll("&", "&amp;")
67
+ .replaceAll("<", "&lt;")
68
+ .replaceAll(">", "&gt;")
69
+ .replaceAll('"', "&quot;")
70
+ .replaceAll("'", "&#039;");
71
+ }
72
+ export function renderRescueHtml(manifest) {
73
+ const markdown = renderRescueMarkdown(manifest);
74
+ const before = manifest.before.summary;
75
+ const after = manifest.after?.summary;
76
+ const cards = [
77
+ ["Before", before.total],
78
+ ["After", after?.total ?? "—"],
79
+ ["Applied", manifest.appliedFixIds.length],
80
+ [
81
+ "Needs review",
82
+ manifest.findings.filter((item) => item.classification === "review-required").length,
83
+ ],
84
+ ];
85
+ return `<!doctype html>
86
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
87
+ <title>Buoy Rescue · ${escapeHtml(manifest.id)}</title>
88
+ <style>body{margin:0;background:#071827;color:#eaf6f8;font:16px/1.55 ui-sans-serif,system-ui,sans-serif}main{max-width:960px;margin:auto;padding:64px 24px}.eyebrow{color:#53d6df;font-weight:700}.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:16px;margin:32px 0}.card,pre{background:#0c2335;border:1px solid #244052;border-radius:14px;padding:20px}.value{font-size:32px;font-weight:800}pre{white-space:pre-wrap;color:#bfd0d8;overflow:auto}a{color:#53d6df}</style></head>
89
+ <body><main><p class="eyebrow">BUOY RESCUE</p><h1>Before-and-after implementation report</h1><p>Run ${escapeHtml(manifest.id)} · ${escapeHtml(manifest.status)}</p>
90
+ <section class="cards">${cards.map(([label, value]) => `<div class="card"><div>${escapeHtml(String(label))}</div><div class="value">${escapeHtml(String(value))}</div></div>`).join("")}</section>
91
+ <pre>${escapeHtml(markdown)}</pre></main></body></html>`;
92
+ }
93
+ export async function writeRescueReports(manifest) {
94
+ const dir = rescueRunDir(manifest.projectRoot, manifest.id);
95
+ const paths = {
96
+ json: join(dir, "report.json"),
97
+ markdown: join(dir, "report.md"),
98
+ html: join(dir, "report.html"),
99
+ };
100
+ await Promise.all([
101
+ writeFile(paths.json, JSON.stringify(manifest, null, 2), "utf8"),
102
+ writeFile(paths.markdown, renderRescueMarkdown(manifest), "utf8"),
103
+ writeFile(paths.html, renderRescueHtml(manifest), "utf8"),
104
+ ]);
105
+ return paths;
106
+ }
107
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/rescue/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { RescueManifest } from "./types.js";
2
+ export declare function rescueRoot(projectRoot: string): string;
3
+ export declare function rescueRunDir(projectRoot: string, runId: string): string;
4
+ export declare function rescueManifestPath(projectRoot: string, runId: string): string;
5
+ export declare function saveRescueManifest(manifest: RescueManifest): Promise<void>;
6
+ export declare function resolveRunId(projectRoot: string, requested?: string): Promise<string>;
7
+ export declare function loadRescueManifest(projectRoot: string, requested?: string): Promise<RescueManifest>;
8
+ export declare function createRunId(now?: Date): string;
9
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/rescue/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7E;AAMD,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,CAAC,CAKzB;AAED,wBAAgB,WAAW,CAAC,GAAG,OAAa,GAAG,MAAM,CAMpD"}
@@ -0,0 +1,50 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ export function rescueRoot(projectRoot) {
5
+ return join(projectRoot, ".buoy", "rescue");
6
+ }
7
+ export function rescueRunDir(projectRoot, runId) {
8
+ return join(rescueRoot(projectRoot), "runs", runId);
9
+ }
10
+ export function rescueManifestPath(projectRoot, runId) {
11
+ return join(rescueRunDir(projectRoot, runId), "manifest.json");
12
+ }
13
+ function latestPath(projectRoot) {
14
+ return join(rescueRoot(projectRoot), "latest.json");
15
+ }
16
+ export async function saveRescueManifest(manifest) {
17
+ const runDir = rescueRunDir(manifest.projectRoot, manifest.id);
18
+ await mkdir(runDir, { recursive: true });
19
+ manifest.updatedAt = new Date().toISOString();
20
+ await writeFile(rescueManifestPath(manifest.projectRoot, manifest.id), JSON.stringify(manifest, null, 2), "utf8");
21
+ await mkdir(rescueRoot(manifest.projectRoot), { recursive: true });
22
+ await writeFile(latestPath(manifest.projectRoot), JSON.stringify({ runId: manifest.id }, null, 2), "utf8");
23
+ }
24
+ export async function resolveRunId(projectRoot, requested) {
25
+ if (requested)
26
+ return requested;
27
+ const path = latestPath(projectRoot);
28
+ if (!existsSync(path)) {
29
+ throw new Error("No Rescue run found. Start with `buoy rescue plan`.");
30
+ }
31
+ const latest = JSON.parse(await readFile(path, "utf8"));
32
+ if (!latest.runId)
33
+ throw new Error("The latest Rescue run pointer is invalid.");
34
+ return latest.runId;
35
+ }
36
+ export async function loadRescueManifest(projectRoot, requested) {
37
+ const runId = await resolveRunId(projectRoot, requested);
38
+ const path = rescueManifestPath(projectRoot, runId);
39
+ if (!existsSync(path))
40
+ throw new Error(`Rescue run not found: ${runId}`);
41
+ return JSON.parse(await readFile(path, "utf8"));
42
+ }
43
+ export function createRunId(now = new Date()) {
44
+ const stamp = now
45
+ .toISOString()
46
+ .replace(/[-:]/g, "")
47
+ .replace(/\.\d{3}Z$/, "Z");
48
+ return `rescue-${stamp}`;
49
+ }
50
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/rescue/store.ts"],"names":[],"mappings":"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"}