@bli-cockpit/cli 0.2.241 → 0.2.243

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 (127) hide show
  1. package/dist/adapters/git-state.js +1 -0
  2. package/dist/adapters/raw-evidence-collection-state.js +22 -11
  3. package/dist/adapters/raw-evidence-git-diff.js +1 -0
  4. package/dist/agent-rules.js +8 -0
  5. package/dist/autostart-contract.js +12 -0
  6. package/dist/autostart-darwin-plist.js +2 -2
  7. package/dist/autostart-darwin.js +1 -1
  8. package/dist/autostart-remind.js +245 -0
  9. package/dist/autostart-self-heal.js +17 -1
  10. package/dist/autostart-windows-scripts.js +7 -7
  11. package/dist/autostart.js +16 -15
  12. package/dist/commands/approvals-check-where.js +14 -0
  13. package/dist/commands/approvals-render.js +8 -1
  14. package/dist/commands/approvals.js +3 -2
  15. package/dist/commands/autostart-command.js +10 -0
  16. package/dist/commands/autostart-heal.js +36 -1
  17. package/dist/commands/brain.js +1 -1
  18. package/dist/commands/cal-agenda.js +44 -0
  19. package/dist/commands/cal-availability-share.js +97 -0
  20. package/dist/commands/cal-booking.js +147 -0
  21. package/dist/commands/cal-join.js +62 -0
  22. package/dist/commands/cal-links.js +68 -0
  23. package/dist/commands/cal-people.js +136 -0
  24. package/dist/commands/cal-remind.js +176 -0
  25. package/dist/commands/cal-reminders.js +33 -0
  26. package/dist/commands/cal-suggest.js +89 -0
  27. package/dist/commands/cal.js +41 -1
  28. package/dist/commands/cycle-args.js +127 -0
  29. package/dist/commands/cycles.js +117 -0
  30. package/dist/commands/docs-comments-args.js +85 -0
  31. package/dist/commands/docs-comments.js +128 -0
  32. package/dist/commands/docs-files-args.js +49 -0
  33. package/dist/commands/docs-files.js +179 -0
  34. package/dist/commands/docs-formatting.js +45 -0
  35. package/dist/commands/docs-inbox-args.js +93 -0
  36. package/dist/commands/docs-inbox.js +126 -0
  37. package/dist/commands/docs-notion.js +5 -0
  38. package/dist/commands/docs-read.js +2 -1
  39. package/dist/commands/docs-recovery.js +173 -0
  40. package/dist/commands/docs-refs-args.js +104 -0
  41. package/dist/commands/docs-refs.js +153 -0
  42. package/dist/commands/docs-search-args.js +79 -0
  43. package/dist/commands/docs-search.js +64 -0
  44. package/dist/commands/docs-sync-args.js +82 -0
  45. package/dist/commands/docs-sync.js +197 -0
  46. package/dist/commands/docs-tree.js +136 -0
  47. package/dist/commands/docs.js +85 -51
  48. package/dist/commands/doctor-update.js +4 -1
  49. package/dist/commands/inbox-args.js +81 -0
  50. package/dist/commands/inbox.js +88 -0
  51. package/dist/commands/issue-batch.js +61 -0
  52. package/dist/commands/issue-relations.js +151 -0
  53. package/dist/commands/issue-write.js +38 -5
  54. package/dist/commands/issue.js +32 -1
  55. package/dist/commands/local-args-tower-approvals.js +16 -4
  56. package/dist/commands/local-args-tower-cal-booking.js +81 -0
  57. package/dist/commands/local-args-tower-cal-links.js +42 -0
  58. package/dist/commands/local-args-tower-cal-remind.js +74 -0
  59. package/dist/commands/local-args-tower-cal-share.js +41 -0
  60. package/dist/commands/local-args-tower-cal.js +81 -8
  61. package/dist/commands/local-args-tower-docs-msg.js +98 -9
  62. package/dist/commands/local-args-tower-msg.js +279 -10
  63. package/dist/commands/local-args-tower-search.js +32 -5
  64. package/dist/commands/local-args-tower-work.js +110 -34
  65. package/dist/commands/local-args-tower.js +1 -0
  66. package/dist/commands/local-args.js +2 -0
  67. package/dist/commands/local-auth.js +1 -1
  68. package/dist/commands/local-help-commands-tower-ops.js +2 -0
  69. package/dist/commands/local-help-commands-tower.js +48 -32
  70. package/dist/commands/local-help-commands.js +1 -0
  71. package/dist/commands/local-help-cycles.js +9 -0
  72. package/dist/commands/local-help-docs-files.js +10 -0
  73. package/dist/commands/local-help-docs-formatting.js +7 -0
  74. package/dist/commands/local-help-docs-inbox.js +10 -0
  75. package/dist/commands/local-help-docs-recovery.js +10 -0
  76. package/dist/commands/local-help-docs-refs.js +11 -0
  77. package/dist/commands/local-help-docs-sync.js +9 -0
  78. package/dist/commands/local-help-inbox.js +9 -0
  79. package/dist/commands/local-help-project.js +21 -0
  80. package/dist/commands/local-help-templates.js +9 -0
  81. package/dist/commands/local-help-views.js +10 -0
  82. package/dist/commands/local-help-work-notify.js +6 -0
  83. package/dist/commands/local-help.js +4 -2
  84. package/dist/commands/local.js +2 -0
  85. package/dist/commands/mcp-stdio-probe.js +1 -0
  86. package/dist/commands/msg-activity.js +134 -0
  87. package/dist/commands/msg-channel-args.js +92 -0
  88. package/dist/commands/msg-channel.js +125 -0
  89. package/dist/commands/msg-context-args.js +67 -0
  90. package/dist/commands/msg-context.js +65 -0
  91. package/dist/commands/msg-dm.js +28 -0
  92. package/dist/commands/msg-draft.js +193 -0
  93. package/dist/commands/msg-file.js +185 -0
  94. package/dist/commands/msg-mark-args.js +78 -0
  95. package/dist/commands/msg-mark.js +148 -0
  96. package/dist/commands/msg-notify-args.js +100 -0
  97. package/dist/commands/msg-notify.js +122 -0
  98. package/dist/commands/msg-schedule-args.js +114 -0
  99. package/dist/commands/msg-schedule.js +226 -0
  100. package/dist/commands/msg-search-args.js +71 -0
  101. package/dist/commands/msg-search.js +48 -0
  102. package/dist/commands/msg-write.js +15 -1
  103. package/dist/commands/msg.js +77 -39
  104. package/dist/commands/project-args.js +82 -0
  105. package/dist/commands/project.js +71 -7
  106. package/dist/commands/public-root.js +1 -1
  107. package/dist/commands/push.js +50 -0
  108. package/dist/commands/search.js +23 -0
  109. package/dist/commands/session-sync-failures.js +17 -4
  110. package/dist/commands/session-sync-health.js +7 -2
  111. package/dist/commands/session-sync-hold.js +42 -1
  112. package/dist/commands/session-sync-upload.js +2 -0
  113. package/dist/commands/session-sync.js +1 -0
  114. package/dist/commands/sync-doctor.js +14 -1
  115. package/dist/commands/sync-report.js +1 -1
  116. package/dist/commands/template-args.js +122 -0
  117. package/dist/commands/templates.js +162 -0
  118. package/dist/commands/view-args.js +131 -0
  119. package/dist/commands/views.js +138 -0
  120. package/dist/commands/work-notify-args.js +67 -0
  121. package/dist/commands/work-notify.js +63 -0
  122. package/dist/delivery-hold-notice.js +34 -0
  123. package/dist/log-rotation.js +2 -2
  124. package/dist/notifier.js +83 -0
  125. package/dist/process-runner.js +4 -0
  126. package/dist/repo-identity-git.js +1 -0
  127. package/package.json +4 -4
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The one place the collector paints an OS banner (BLI-21564, calendar slice 11).
3
+ *
4
+ * macOS goes through `osascript -e 'display notification ...'`, Windows through
5
+ * a PowerShell toast on PowerShell's own app id. Both are spawned through
6
+ * `process-runner.ts` with an ARRAY of arguments (never a shell line), and every
7
+ * string a person or a calendar can influence is escaped (AppleScript) or passed
8
+ * by environment variable (PowerShell), so a meeting title cannot become code.
9
+ *
10
+ * The result is always one of three named outcomes. A banner the OS refused is
11
+ * `permission_denied`; a helper that failed any other way is `notifier_failed`
12
+ * with its exit code; nothing here is silent. `osascript` exits 0 when the user
13
+ * switched notifications off for it, so a silent denial is not detectable: a
14
+ * desktop receipt, not this module, is the proof a banner appeared.
15
+ */
16
+ import { createCapturedExecRunner } from "./process-runner.js";
17
+ const NOTIFIER_TIMEOUT_MS = 15_000;
18
+ const MAX_TEXT = 200;
19
+ const DENIAL = /not allowed|not authorized|not permitted|access.*denied|notifications? (?:are |is )?(?:disabled|blocked|turned off)|\(-1743\)|\(-1744\)|blocked by/i;
20
+ /** Controls become spaces and the length is bounded; the text is a banner, not a document. */
21
+ function plain(value) {
22
+ // eslint-disable-next-line no-control-regex
23
+ return value.replace(/[\u0000-\u001f\u007f]+/g, " ").trim().slice(0, MAX_TEXT);
24
+ }
25
+ /** An AppleScript string literal body: backslash and double quote are the only escapes it needs. */
26
+ export function appleScriptEscape(value) {
27
+ return plain(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
28
+ }
29
+ export function macNotifyArgs(request) {
30
+ const sound = request.sound ? ' sound name "Glass"' : "";
31
+ return ["-e", `display notification "${appleScriptEscape(request.message)}" with title "${appleScriptEscape(request.title)}"${sound}`];
32
+ }
33
+ /** The toast script reads its text from the environment, so no title can reach the script body. */
34
+ export const WINDOWS_TOAST_SCRIPT = [
35
+ "$ErrorActionPreference = 'Stop'",
36
+ "[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null",
37
+ "[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null",
38
+ "$title = [System.Security.SecurityElement]::Escape($env:TOWER_TOAST_TITLE)",
39
+ "$message = [System.Security.SecurityElement]::Escape($env:TOWER_TOAST_MESSAGE)",
40
+ "$audio = if ($env:TOWER_TOAST_SOUND -eq '1') { '' } else { '<audio silent=\"true\"/>' }",
41
+ "$xml = New-Object Windows.Data.Xml.Dom.XmlDocument",
42
+ "$xml.LoadXml('<toast><visual><binding template=\"ToastText02\"><text id=\"1\">' + $title + '</text><text id=\"2\">' + $message + '</text></binding></visual>' + $audio + '</toast>')",
43
+ "$toast = New-Object Windows.UI.Notifications.ToastNotification $xml",
44
+ "$appId = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\\WindowsPowerShell\\v1.0\\powershell.exe'",
45
+ "[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($appId).Show($toast)",
46
+ ].join("\n");
47
+ export function windowsNotifyArgs() {
48
+ const encoded = Buffer.from(WINDOWS_TOAST_SCRIPT, "utf16le").toString("base64");
49
+ return ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-EncodedCommand", encoded];
50
+ }
51
+ export async function showNotification(request, options = {}) {
52
+ const platform = options.platform ?? process.platform;
53
+ const exec = options.exec ?? createCapturedExecRunner({ platform });
54
+ let command;
55
+ let args;
56
+ let env;
57
+ if (platform === "darwin") {
58
+ command = "osascript";
59
+ args = macNotifyArgs(request);
60
+ }
61
+ else if (platform === "win32") {
62
+ command = "powershell.exe";
63
+ args = windowsNotifyArgs();
64
+ env = { ...(options.env ?? process.env), TOWER_TOAST_TITLE: plain(request.title), TOWER_TOAST_MESSAGE: plain(request.message), TOWER_TOAST_SOUND: request.sound ? "1" : "0" };
65
+ }
66
+ else {
67
+ const reason = `no_notifier_for_${platform}`;
68
+ console.error("[notifier] not shown", JSON.stringify({ outcome: "notifier_failed", reason }));
69
+ return { outcome: "notifier_failed", reason };
70
+ }
71
+ const result = await exec(command, args, { timeoutMs: NOTIFIER_TIMEOUT_MS, ...(env ? { env } : {}) });
72
+ if (result.code === 0) {
73
+ console.error("[notifier] shown", JSON.stringify({ outcome: "shown", platform }));
74
+ return { outcome: "shown", reason: null };
75
+ }
76
+ if (DENIAL.test(`${result.stderr}\n${result.stdout}`)) {
77
+ console.error("[notifier] not shown", JSON.stringify({ outcome: "permission_denied", platform, exit: result.code }));
78
+ return { outcome: "permission_denied", reason: `os_refused_exit_${result.code}` };
79
+ }
80
+ const reason = result.code === 124 ? "timed_out" : `exit_${result.code}`;
81
+ console.error("[notifier] not shown", JSON.stringify({ outcome: "notifier_failed", platform, exit: result.code }));
82
+ return { outcome: "notifier_failed", reason };
83
+ }
@@ -35,6 +35,7 @@ export function createCapturedExecRunner(options = {}) {
35
35
  encoding: "utf8",
36
36
  env,
37
37
  windowsVerbatimArguments: invocation.windowsVerbatimArguments,
38
+ windowsHide: true,
38
39
  ...(runOptions?.timeoutMs ? { timeout: runOptions.timeoutMs } : {}),
39
40
  }, (error, stdout, stderr) => {
40
41
  const code = capturedExitCode(error, runOptions?.timeoutMs);
@@ -86,6 +87,9 @@ export function createInteractiveExecRunner(options = {}) {
86
87
  stdio,
87
88
  env,
88
89
  windowsVerbatimArguments: invocation.windowsVerbatimArguments,
90
+ // Ticket 21952: a scheduled sync has no console, so a child without this opens a visible window on Windows.
91
+ // With a console (a person typing `cockpit doctor`) the child shares it and the flag changes nothing.
92
+ windowsHide: true,
89
93
  });
90
94
  let settled = false;
91
95
  child.on("error", (error) => {
@@ -14,6 +14,7 @@ export async function runGit(args, cwd) {
14
14
  const { stdout } = await execFileAsync("git", args, {
15
15
  cwd,
16
16
  timeout: 2_000,
17
+ windowsHide: true,
17
18
  maxBuffer: 1024 * 1024,
18
19
  });
19
20
  return stdout;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/cli",
3
- "version": "0.2.241",
3
+ "version": "0.2.243",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,9 +27,9 @@
27
27
  "test": "node dist/cli.js --help && node ../../scripts/assert-public-cli-routing.mjs && node ../../scripts/assert-public-cli-verb-help.mjs && node ../../scripts/assert-public-cli-surface-doors.mjs && node ../../scripts/assert-public-cli-runtime-files.mjs && node ../../scripts/assert-public-cli-exit-contract.mjs && node ../../scripts/assert-public-cli-no-fleet-posts.mjs && node ../../scripts/assert-public-cli-doctor-json.mjs && node ../../scripts/assert-public-package-pack.mjs --workspace=@bli-cockpit/cli"
28
28
  },
29
29
  "dependencies": {
30
- "@bli-cockpit/memory-mcp": "0.1.70",
31
- "@bli-cockpit/mcp": "0.1.146",
32
- "@bli-cockpit/telemetry-core": "0.1.77"
30
+ "@bli-cockpit/memory-mcp": "0.1.71",
31
+ "@bli-cockpit/mcp": "0.1.148",
32
+ "@bli-cockpit/telemetry-core": "0.1.78"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",