cli-jaw 2.17.57 → 2.17.58

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 (64) hide show
  1. package/README.md +2 -2
  2. package/dist/src/agent/cursor-runtime.js +61 -3
  3. package/dist/src/agent/cursor-runtime.js.map +1 -1
  4. package/dist/src/cli/claude-models.js +7 -2
  5. package/dist/src/cli/claude-models.js.map +1 -1
  6. package/dist/src/cli/handlers-runtime.js +2 -0
  7. package/dist/src/cli/handlers-runtime.js.map +1 -1
  8. package/dist/src/cli/registry-live.js +2 -1
  9. package/dist/src/cli/registry-live.js.map +1 -1
  10. package/dist/src/cli/registry.js +1 -1
  11. package/dist/src/cli/registry.js.map +1 -1
  12. package/package.json +3 -2
  13. package/public/dist/.vite/manifest.json +99 -99
  14. package/public/dist/assets/{Agent-Bni1QERf.js → Agent-D4g8TPjm.js} +1 -1
  15. package/public/dist/assets/{Heartbeat-BmkZshEU.js → Heartbeat-CIVtKWNc.js} +1 -1
  16. package/public/dist/assets/{Memory-DsK_yOCW.js → Memory-BSDIXT0B.js} +1 -1
  17. package/public/dist/assets/{ModelProvider-L_hW6YWJ.js → ModelProvider-DMh2tXUx.js} +1 -1
  18. package/public/dist/assets/agent-meta-94LMwZZK.js +1 -0
  19. package/public/dist/assets/{app-zazofyFd.js → app-Cn7mvbfa.js} +4 -4
  20. package/public/dist/assets/bgtask-badge-C_bWwh_e.js +1 -0
  21. package/public/dist/assets/{bgtask-badge-GHPSB8YA.js → bgtask-badge-DwA2ufcC.js} +1 -1
  22. package/public/dist/assets/constants-DmZ9Rjym.js +1 -0
  23. package/public/dist/assets/{employees-BxB7jajK.js → employees-DrXQ9oRa.js} +1 -1
  24. package/public/dist/assets/{iframe-renderer-BTTOQPS-.js → iframe-renderer-CLqxxRj1.js} +2 -2
  25. package/public/dist/assets/iframe-renderer-DjRrBgkV.js +1 -0
  26. package/public/dist/assets/{manager-DiDxQjGG.js → manager-B7QobNzw.js} +1 -1
  27. package/public/dist/assets/memory-BOwQYuLb.js +1 -0
  28. package/public/dist/assets/{memory-BtrzxI2f.js → memory-CPfFQFaW.js} +1 -1
  29. package/public/dist/assets/{message-history-BPlxn_fF.js → message-history-BhiEuMLw.js} +1 -1
  30. package/public/dist/assets/message-history-CqWYH9Sx.js +1 -0
  31. package/public/dist/assets/{render-DWNRmn6F.js → render-CdATJ4wM.js} +1 -1
  32. package/public/dist/assets/{settings-CBNWt2eS.js → settings-Bd6HveOX.js} +1 -1
  33. package/public/dist/assets/{settings-CoalzYdp.js → settings-Cjrg6SrM.js} +1 -1
  34. package/public/dist/assets/settings-core-BNFL4oSA.js +1 -0
  35. package/public/dist/assets/{settings-core-C9d6LGNB.js → settings-core-D_2F4S22.js} +1 -1
  36. package/public/dist/assets/{settings-embedding-DnOHL4gj.js → settings-embedding-DeOQX-nw.js} +1 -1
  37. package/public/dist/assets/settings-kHiXb__9.js +1 -0
  38. package/public/dist/assets/{sidebar-ZriXonXN.js → sidebar-DE-2OtXs.js} +3 -3
  39. package/public/dist/assets/{skills-D0ZTAdcQ.js → skills-CD3PFa7e.js} +1 -1
  40. package/public/dist/assets/skills-iVr8hW-f.js +1 -0
  41. package/public/dist/assets/{slash-commands-CRaPab4c.js → slash-commands-Czgl_F8c.js} +1 -1
  42. package/public/dist/assets/slash-commands-DbBIj8wv.js +1 -0
  43. package/public/dist/assets/{trace-drawer-C4UrlIbL.js → trace-drawer-BYKkBIG-.js} +1 -1
  44. package/public/dist/assets/{ui-BYUrgEqP.js → ui-B0OYr3pK.js} +1 -1
  45. package/public/dist/assets/ui-CpxBqLlq.js +1 -0
  46. package/public/dist/index.html +1 -1
  47. package/public/dist/manager/index.html +1 -1
  48. package/public/dist/settings/index.html +1 -1
  49. package/public/js/constants.ts +6 -3
  50. package/public/manager/src/settings/pages/components/agent/agent-meta.ts +5 -2
  51. package/scripts/notarize-mac-dmg.mjs +207 -0
  52. package/scripts/verify-electron-update-metadata.mjs +21 -1
  53. package/scripts/verify-mac-signature.mjs +85 -2
  54. package/public/dist/assets/agent-meta-CkRJlOmN.js +0 -1
  55. package/public/dist/assets/bgtask-badge-DNOEtlYA.js +0 -1
  56. package/public/dist/assets/constants-DmRtjRj3.js +0 -1
  57. package/public/dist/assets/iframe-renderer-CKg5BMGK.js +0 -1
  58. package/public/dist/assets/memory-4jRy1vVN.js +0 -1
  59. package/public/dist/assets/message-history-S9ZHb1mg.js +0 -1
  60. package/public/dist/assets/settings-CO1kvTfO.js +0 -1
  61. package/public/dist/assets/settings-core-P9taYIOs.js +0 -1
  62. package/public/dist/assets/skills-BesnYjWa.js +0 -1
  63. package/public/dist/assets/slash-commands-Bjurf5lq.js +0 -1
  64. package/public/dist/assets/ui-B49acfZi.js +0 -1
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Notarize and staple the signed macOS disk image, then re-describe it.
4
+ *
5
+ * electron-builder 25.1.8 notarizes and staples the app bundle, and with
6
+ * `dmg.sign` it signs the disk image, but it never notarizes the disk image.
7
+ * A user who downloads the DMG therefore opens a container Gatekeeper cannot
8
+ * vouch for: `spctl --type open` rejects it and the stapler finds no ticket.
9
+ *
10
+ * Stapling is the part that needs care. dmg-builder hashes the DMG into its
11
+ * blockmap immediately after signing it (dmg-builder/out/dmg.js:62-67) and
12
+ * that hash is what lands in latest-mac.yml. Stapling appends the ticket to
13
+ * the file, so every description written before it (the DMG entry in
14
+ * latest-mac.yml and the .blockmap next to the DMG) would describe bytes that
15
+ * no longer exist. This script rebuilds both from the stapled file with the
16
+ * same app-builder command electron-builder uses, and only touches the DMG
17
+ * entry: the ZIP entry and the legacy top-level path/sha512 fields are the
18
+ * updater payload and must stay byte-for-byte what electron-builder wrote.
19
+ *
20
+ * Every step fails closed. A DMG that is unsigned, signed by another team,
21
+ * rejected by the notary service, or not stapled stops the release here
22
+ * instead of being uploaded as if it were trusted.
23
+ */
24
+ import childProcess from 'node:child_process';
25
+ import { createHash } from 'node:crypto';
26
+ import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
27
+ import { createRequire } from 'node:module';
28
+ import { basename, join, resolve } from 'node:path';
29
+ import { fileURLToPath } from 'node:url';
30
+ import { parseDocument } from 'yaml';
31
+
32
+ const projectRoot = resolve(fileURLToPath(import.meta.url), '..', '..');
33
+ const CREDENTIAL_NAMES = ['APPLE_ID', 'APPLE_APP_SPECIFIC_PASSWORD', 'APPLE_TEAM_ID'];
34
+
35
+ function defaultRun(cmd, args) {
36
+ const result = childProcess.spawnSync(cmd, args, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
37
+ return {
38
+ status: result.status,
39
+ stdout: result.stdout ?? '',
40
+ stderr: result.stderr ?? '',
41
+ error: result.error ?? null,
42
+ };
43
+ }
44
+
45
+ /** Locate the one DMG electron-builder produced; anything else is ambiguous. */
46
+ export function findDiskImage(distDir) {
47
+ if (!existsSync(distDir)) throw new Error(`No build output directory at ${distDir}`);
48
+ const images = readdirSync(distDir).filter(name => name.endsWith('.dmg'));
49
+ if (images.length !== 1) {
50
+ throw new Error(`Expected exactly one .dmg in ${distDir}, found ${images.length}${images.length ? `: ${images.join(', ')}` : ''}`);
51
+ }
52
+ return join(distDir, images[0]);
53
+ }
54
+
55
+ function requireCredentials(env) {
56
+ const missing = CREDENTIAL_NAMES.filter(name => !String(env[name] ?? '').trim());
57
+ if (missing.length > 0) throw new Error(`Missing notarization credential(s): ${missing.join(', ')}`);
58
+ return {
59
+ appleId: String(env['APPLE_ID']).trim(),
60
+ password: String(env['APPLE_APP_SPECIFIC_PASSWORD']).trim(),
61
+ teamId: String(env['APPLE_TEAM_ID']).trim(),
62
+ };
63
+ }
64
+
65
+ function outputOf(result) {
66
+ return `${result.stdout ?? ''}${result.stderr ?? ''}${result.error ? result.error.message : ''}`;
67
+ }
68
+
69
+ /** Keep the app-specific password out of every message this script can print. */
70
+ function redactor(secret) {
71
+ return text => (secret ? String(text).split(secret).join('[redacted]') : String(text));
72
+ }
73
+
74
+ function sha512Base64(path) {
75
+ return createHash('sha512').update(readFileSync(path)).digest('base64');
76
+ }
77
+
78
+ export function resolveAppBuilder() {
79
+ const electronRequire = createRequire(join(projectRoot, 'electron', 'package.json'));
80
+ const { appBuilderPath } = electronRequire('app-builder-bin');
81
+ if (!appBuilderPath || !existsSync(appBuilderPath)) {
82
+ throw new Error(`app-builder binary not found at ${String(appBuilderPath)}; run npm ci --prefix electron`);
83
+ }
84
+ return appBuilderPath;
85
+ }
86
+
87
+ /**
88
+ * Rewrite only the DMG entry of latest-mac.yml. Returns false when the
89
+ * metadata does not list the DMG at all, which leaves nothing stale to fix.
90
+ */
91
+ export function updateDiskImageMetadata(metadataPath, dmgName, { sha512, size }) {
92
+ const doc = parseDocument(readFileSync(metadataPath, 'utf8'));
93
+ if (doc.errors.length > 0) throw new Error(`Cannot parse YAML at ${metadataPath}: ${doc.errors[0].message}`);
94
+ if (doc.get('path') === dmgName) {
95
+ throw new Error(`latest-mac.yml names the DMG as the update payload; expected the ZIP`);
96
+ }
97
+ const files = doc.get('files');
98
+ const items = files?.items ?? [];
99
+ const matches = items.filter(item => item?.get?.('url') === dmgName);
100
+ if (matches.length > 1) throw new Error(`latest-mac.yml lists ${dmgName} more than once`);
101
+ if (matches.length === 0) return false;
102
+ matches[0].set('sha512', sha512);
103
+ matches[0].set('size', size);
104
+ writeFileSync(metadataPath, doc.toString());
105
+ return true;
106
+ }
107
+
108
+ export function notarizeMacDiskImage(options = {}) {
109
+ const run = options.run ?? defaultRun;
110
+ const env = options.env ?? process.env;
111
+ const distDir = resolve(options.distDir ?? join(projectRoot, 'electron', 'dist'));
112
+ const dmgPath = options.dmgPath ? resolve(options.dmgPath) : findDiskImage(distDir);
113
+ const metadataPath = options.metadataPath ?? join(distDir, 'latest-mac.yml');
114
+ const credentials = requireCredentials(env);
115
+ const redact = redactor(credentials.password);
116
+ const expectedTeam = String(options.expectedTeamId ?? env['EXPECTED_APPLE_TEAM_ID'] ?? '').trim() || null;
117
+ const log = options.log ?? (message => console.log(message));
118
+
119
+ if (!existsSync(dmgPath)) throw new Error(`No disk image at ${dmgPath}`);
120
+ if (expectedTeam && credentials.teamId !== expectedTeam) {
121
+ throw new Error('APPLE_TEAM_ID does not match the expected release signing team');
122
+ }
123
+
124
+ // 1. The DMG must already carry our Developer ID signature. dmg-builder
125
+ // skips signing silently when it cannot find an identity.
126
+ const info = run('/usr/bin/codesign', ['-dv', '--verbose=2', dmgPath]);
127
+ const infoText = outputOf(info);
128
+ if (info.error || info.status !== 0) throw new Error(`codesign -dv failed for ${dmgPath}:\n${infoText.trim()}`);
129
+ if (!/Authority=Developer ID Application:/.test(infoText)) {
130
+ throw new Error(`${basename(dmgPath)} is not signed with a Developer ID Application certificate`);
131
+ }
132
+ const signedTeam = (infoText.match(/TeamIdentifier=(\S+)/) ?? [, '(unknown)'])[1];
133
+ if (signedTeam !== credentials.teamId) {
134
+ throw new Error(`${basename(dmgPath)} is signed by team "${signedTeam}", not the notarizing team`);
135
+ }
136
+ if (!/^Timestamp=/m.test(infoText)) throw new Error(`${basename(dmgPath)} signature has no secure timestamp`);
137
+
138
+ // 2. Submit and wait for the notary verdict.
139
+ log(`[notarize-mac-dmg] submitting ${basename(dmgPath)}`);
140
+ const submit = run('/usr/bin/xcrun', [
141
+ 'notarytool', 'submit', dmgPath,
142
+ '--apple-id', credentials.appleId,
143
+ '--password', credentials.password,
144
+ '--team-id', credentials.teamId,
145
+ '--wait', '--timeout', '45m',
146
+ '--output-format', 'json',
147
+ ]);
148
+ let verdict = null;
149
+ try { verdict = JSON.parse(submit.stdout); } catch { verdict = null; }
150
+ if (submit.error || verdict?.status !== 'Accepted') {
151
+ let detail = redact(outputOf(submit).trim());
152
+ if (typeof verdict?.id === 'string' && /^[0-9a-f-]{36}$/i.test(verdict.id)) {
153
+ const notaryLog = run('/usr/bin/xcrun', [
154
+ 'notarytool', 'log', verdict.id,
155
+ '--apple-id', credentials.appleId,
156
+ '--password', credentials.password,
157
+ '--team-id', credentials.teamId,
158
+ ]);
159
+ detail += `\n\nnotary log:\n${redact(outputOf(notaryLog).trim())}`;
160
+ }
161
+ throw new Error(`notarization of ${basename(dmgPath)} was not accepted (status: ${String(verdict?.status ?? 'unknown')})\n${detail}`);
162
+ }
163
+ log(`[notarize-mac-dmg] accepted (submission ${verdict.id})`);
164
+
165
+ // 3. Staple so the first open works offline, then prove the ticket is there.
166
+ const staple = run('/usr/bin/xcrun', ['stapler', 'staple', dmgPath]);
167
+ if (staple.error || staple.status !== 0) throw new Error(`stapler staple failed:\n${outputOf(staple).trim()}`);
168
+ const validate = run('/usr/bin/xcrun', ['stapler', 'validate', dmgPath]);
169
+ if (validate.error || validate.status !== 0) throw new Error(`stapler validate failed:\n${outputOf(validate).trim()}`);
170
+
171
+ // 4. Rebuild the blockmap from the stapled bytes, exactly as electron-builder does.
172
+ const appBuilder = options.appBuilderPath ?? resolveAppBuilder();
173
+ const blockmapPath = `${dmgPath}.blockmap`;
174
+ const blockmap = run(appBuilder, ['blockmap', '--input', dmgPath, '--output', blockmapPath]);
175
+ if (blockmap.error || blockmap.status !== 0) throw new Error(`app-builder blockmap failed:\n${outputOf(blockmap).trim()}`);
176
+ let described;
177
+ try { described = JSON.parse(blockmap.stdout); } catch { described = null; }
178
+ const actualSize = statSync(dmgPath).size;
179
+ const actualHash = sha512Base64(dmgPath);
180
+ if (described?.size !== actualSize || described?.sha512 !== actualHash) {
181
+ throw new Error('app-builder blockmap description does not match the stapled disk image');
182
+ }
183
+
184
+ // 5. Point the DMG entry of latest-mac.yml at the stapled bytes.
185
+ const metadataUpdated = existsSync(metadataPath)
186
+ ? updateDiskImageMetadata(metadataPath, basename(dmgPath), { sha512: actualHash, size: actualSize })
187
+ : false;
188
+
189
+ return { dmgPath, blockmapPath, metadataPath, metadataUpdated, submissionId: verdict.id, sha512: actualHash, size: actualSize };
190
+ }
191
+
192
+ function main() {
193
+ try {
194
+ const report = notarizeMacDiskImage({ dmgPath: process.argv[2] });
195
+ console.log('[notarize-mac-dmg] OK');
196
+ console.log(` dmg ${report.dmgPath}`);
197
+ console.log(` stapled yes`);
198
+ console.log(` blockmap ${report.blockmapPath}`);
199
+ console.log(` metadata ${report.metadataUpdated ? 'DMG entry updated' : 'no DMG entry'}`);
200
+ console.log(` sha512 ${report.sha512}`);
201
+ } catch (error) {
202
+ console.error(`\n[notarize-mac-dmg] FAIL: ${error instanceof Error ? error.message : String(error)}\n`);
203
+ process.exit(1);
204
+ }
205
+ }
206
+
207
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) main();
@@ -73,6 +73,25 @@ export function verifyElectronUpdateMetadata(options = {}) {
73
73
  throw new Error('Legacy macOS update metadata fields do not match files[0]');
74
74
  }
75
75
 
76
+ // The other entries (the DMG) are not the updater payload, but they are
77
+ // published next to it and describe bytes users download. The DMG is
78
+ // stapled after electron-builder hashed it, so a stale description here
79
+ // means the post-staple metadata repair did not run or did not stick.
80
+ const otherArtifacts = [];
81
+ for (const file of metadata.files) {
82
+ if (file === entry) continue;
83
+ const artifactPath = join(distDir, file.url);
84
+ if (!existsSync(artifactPath)) throw new Error(`Missing listed update artifact: ${artifactPath}`);
85
+ const size = statSync(artifactPath).size;
86
+ if (file.size !== size) {
87
+ throw new Error(`${file.url} size mismatch: metadata=${String(file.size)} actual=${size}`);
88
+ }
89
+ if (file.sha512 !== sha512(artifactPath)) {
90
+ throw new Error(`${file.url} SHA-512 does not match update metadata`);
91
+ }
92
+ otherArtifacts.push(artifactPath);
93
+ }
94
+
76
95
  const provider = readYaml(appUpdatePath);
77
96
  for (const [key, expected] of Object.entries(EXPECTED_PROVIDER)) {
78
97
  if (provider?.[key] !== expected) {
@@ -80,7 +99,7 @@ export function verifyElectronUpdateMetadata(options = {}) {
80
99
  }
81
100
  }
82
101
 
83
- return { metadataPath, zipPath, blockmapPath, version, sha512: actualHash };
102
+ return { metadataPath, zipPath, blockmapPath, version, sha512: actualHash, otherArtifacts };
84
103
  }
85
104
 
86
105
  function main() {
@@ -95,6 +114,7 @@ function main() {
95
114
  console.log(` zip ${report.zipPath}`);
96
115
  console.log(` blockmap ${report.blockmapPath}`);
97
116
  console.log(` sha512 ${report.sha512}`);
117
+ for (const artifact of report.otherArtifacts) console.log(` listed ${artifact} (hash matches)`);
98
118
  } catch (error) {
99
119
  console.error(`\n[verify-electron-update-metadata] FAIL: ${error instanceof Error ? error.message : String(error)}\n`);
100
120
  process.exit(1);
@@ -15,8 +15,8 @@
15
15
  * code of the step that produced it.
16
16
  */
17
17
  import childProcess from 'node:child_process';
18
- import { existsSync } from 'node:fs';
19
- import { resolve } from 'node:path';
18
+ import { existsSync, readdirSync } from 'node:fs';
19
+ import { join, resolve } from 'node:path';
20
20
  import { fileURLToPath } from 'node:url';
21
21
 
22
22
  /** Capture stdout and stderr because macOS security tools report on stderr. */
@@ -112,7 +112,90 @@ function normalizeExpectedTeam(value) {
112
112
  return normalized || null;
113
113
  }
114
114
 
115
+ /**
116
+ * The disk image users download is a separate trust decision from the app
117
+ * inside it. Gatekeeper assesses a quarantined DMG with the `open` operation
118
+ * and the primary-signature context; an unsigned image reports "no usable
119
+ * signature" and a signed but unnotarized one reports "Unnotarized Developer
120
+ * ID". Only a notarized, stapled Developer ID image passes offline.
121
+ */
122
+ export function verifyMacDiskImage(options = {}) {
123
+ const dmgPath = resolve(options.dmgPath ?? findDiskImage(options.distDir ?? 'electron/dist'));
124
+ const expectedTeamId = normalizeExpectedTeam(options.expectedTeamId ?? process.env['VERIFY_EXPECTED_TEAM_ID']);
125
+
126
+ if (!existsSync(dmgPath)) {
127
+ throw new Error(`No disk image at ${dmgPath}. Did the build step run?`);
128
+ }
129
+
130
+ const problems = [];
131
+ const info = probe('/usr/bin/codesign', ['-dv', '--verbose=4', dmgPath]);
132
+ if (!info.ok) {
133
+ problems.push(`codesign -dv failed:\n${info.text.trim()}`);
134
+ } else {
135
+ if (!/Authority=Developer ID Application:/.test(info.text)) {
136
+ problems.push('disk image is not signed with a Developer ID Application certificate');
137
+ }
138
+ if (!/^Timestamp=/m.test(info.text)) {
139
+ problems.push('disk image signature has no secure timestamp');
140
+ }
141
+ }
142
+
143
+ const teamId = (info.text.match(/TeamIdentifier=(\S+)/) ?? [, '(unknown)'])[1];
144
+ if (expectedTeamId && teamId !== expectedTeamId) {
145
+ problems.push(`disk image team "${teamId}" does not match expected team "${expectedTeamId}"`);
146
+ }
147
+
148
+ const strict = probe('/usr/bin/codesign', ['--verify', '--strict', '--verbose=2', dmgPath]);
149
+ if (!strict.ok) {
150
+ problems.push(`codesign --verify failed:\n${strict.text.trim()}`);
151
+ }
152
+
153
+ const assess = probe('/usr/sbin/spctl', [
154
+ '--assess', '--type', 'open', '--context', 'context:primary-signature', '--verbose=4', dmgPath,
155
+ ]);
156
+ if (!assess.ok || !/source=Notarized Developer ID/.test(assess.text)) {
157
+ problems.push(`spctl did not accept the disk image as notarized:\n${assess.text.trim()}`);
158
+ }
159
+
160
+ const staple = probe('/usr/bin/xcrun', ['stapler', 'validate', dmgPath]);
161
+ if (!staple.ok) {
162
+ problems.push(`disk image has no stapled notarization ticket:\n${staple.text.trim()}`);
163
+ }
164
+
165
+ if (problems.length > 0) {
166
+ throw new Error(`${dmgPath}\n\n - ${problems.join('\n - ')}`);
167
+ }
168
+
169
+ const authority = (info.text.match(/Authority=(.+)/) ?? [, '(unknown)'])[1].trim();
170
+ return { dmgPath, authority, teamId };
171
+ }
172
+
173
+ function findDiskImage(distDir) {
174
+ const dir = resolve(distDir);
175
+ if (!existsSync(dir)) throw new Error(`No build output directory at ${dir}`);
176
+ const images = readdirSync(dir).filter(name => name.endsWith('.dmg'));
177
+ if (images.length !== 1) {
178
+ throw new Error(`Expected exactly one .dmg in ${dir}, found ${images.length}`);
179
+ }
180
+ return join(dir, images[0]);
181
+ }
182
+
115
183
  function main() {
184
+ if (process.argv[2] === '--dmg') {
185
+ try {
186
+ const report = verifyMacDiskImage({ dmgPath: process.argv[3] });
187
+ console.log('[verify-mac-signature] disk image OK');
188
+ console.log(` dmg ${report.dmgPath}`);
189
+ console.log(` authority ${report.authority}`);
190
+ console.log(` team ${report.teamId}`);
191
+ console.log(' notarized yes');
192
+ console.log(' stapled yes');
193
+ } catch (error) {
194
+ console.error(`\n[verify-mac-signature] FAIL: ${error instanceof Error ? error.message : String(error)}\n`);
195
+ process.exit(1);
196
+ }
197
+ return;
198
+ }
116
199
  try {
117
200
  const report = verifyMacSignature({ appPath: process.argv[2] });
118
201
  console.log('[verify-mac-signature] OK');
@@ -1 +0,0 @@
1
- import{r as e,t}from"./cli-engine-NdU0lzs_.js";var n=[`gpt-5.5`,`gpt-5.4`,`gpt-5.4-mini`,`gpt-5.3-codex-spark`,`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`],r=[`pi`,`claude`,`agy`,`codex`,`cursor`,`kiro-code`,`gemini`],i={agy:{label:`Antigravity`,models:[`Gemini 3.7 Flash (Medium)`,`Gemini 3.6 Flash (Medium)`],efforts:[],modelNote:`AGY model override is version-dependent. Observed AGY 1.1.13 supports --model; cli-jaw probes the installed binary and emits this field only when supported. Leave empty to use native AGY selection.`,effortNote:`AGY has no separate effort flag.`},pi:{label:`Pi`,defaultProvider:`progrok`,providers:[`progrok`],models:[`grok-composer-2.5-fast`,`grok-4.6`,`grok-4.5`,`grok-4.3`],efforts:[`low`,`medium`,`high`,`xhigh`,`max`],effortNote:`Pi runs through --mode rpc. grok-composer-2.5-fast is the verified default; bare grok-composer-2.5 currently has no team access.`},claude:{label:`Claude`,models:[`opus`,`sonnet`,`sonnet[1m]`,`haiku`,`claude-fable-5-1`,`claude-fable-5`,`claude-fable-5[1m]`,`claude-sonnet-5`,`claude-sonnet-5[1m]`,`claude-opus-5`,`claude-opus-5[1m]`,`claude-opus-4-8`,`claude-opus-4-8[1m]`,`claude-opus-4-7`,`claude-opus-4-7[1m]`,`claude-opus-4-6`,`claude-opus-4-6[1m]`,`claude-sonnet-4-6`,`claude-sonnet-4-6[1m]`,`claude-haiku-4-5`],efforts:[`low`,`medium`,`high`,`xhigh`,`max`]},codex:{label:`Codex`,models:n,efforts:[`low`,`medium`,`high`,`xhigh`]},"codex-app":{label:`Codex App`,models:n,efforts:[`low`,`medium`,`high`,`xhigh`]},cursor:{label:`Cursor`,models:`auto,composer-2.5,gpt-5.5,gpt-5.6-sol,gpt-5.6-terra,gpt-5.6-luna,gpt-5.4,gpt-5.4-mini,gpt-5.4-nano,gpt-5.3-codex,gpt-5.2,gpt-5.2-codex,gpt-5.1-codex-max,gpt-5.1-codex-mini,gpt-5.1,claude-sonnet-5,claude-fable-5,claude-fable-5-thinking,claude-opus-5,claude-opus-4-8,claude-opus-4-8-thinking,claude-opus-4-7,claude-opus-4-7-thinking,claude-4.6-opus,claude-4.6-sonnet,claude-4.5-opus-high,claude-4.5-sonnet,claude-4-sonnet,gemini-3.1-pro,gemini-3-flash,gemini-3-pro,gemini-3.5-flash,grok-4.6,grok-4.5,gpt-5-mini,glm-5.2,glm-5.3,gpt-5.5-extra,kimi-k2.7-code,kimi-k3,gemini-3.6-flash,gemini-3.7-flash`.split(`,`),efforts:[`none`,`none-fast`,`low`,`low-fast`,`medium`,`medium-fast`,`high`,`high-fast`,`xhigh`,`xhigh-fast`,`max`,`max-fast`],effortNote:`Cursor effort resolves to model IDs; no separate --effort flag`},"kiro-code":{label:`Kiro`,models:[`auto`,`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`,`claude-fable-5`,`claude-sonnet-5`,`claude-opus-5`,`claude-opus-4.8`,`claude-opus-4.7`,`claude-opus-4.6`,`claude-sonnet-4.6`,`claude-opus-4.5`,`claude-sonnet-4.5`,`claude-sonnet-4`,`claude-haiku-4.5`,`deepseek-3.2`,`minimax-m2.5`,`minimax-m2.1`,`glm-5`,`qwen3-coder-next`],efforts:[`low`,`medium`,`high`,`xhigh`],effortNote:`Kiro CLI forwards --effort; cli-jaw maps xhigh to Kiro max on the wire`},gemini:{label:`Gemini`,models:[`gemini-3-pro-preview`,`gemini-2.5-pro`,`gemini-3-flash-preview`],efforts:[]},grok:{label:`Grok`,models:[`grok-build`,`grok-composer-2.5-fast`],efforts:[],effortNote:`unsupported by grok-build/composer; do not pass --effort`},opencode:{label:`OpenCode`,models:[`opencode-go/kimi-k2.7-code`,`opencode-go/glm-5.2`,`opencode-go/glm-5.1`,`opencode-go/kimi-k2.6`,`opencode-go/mimo-v2.5-pro`,`opencode-go/mimo-v2.5`,`opencode-go/minimax-m2.7`,`opencode-go/qwen3.7-plus`,`opencode-go/qwen3.6-plus`,`opencode-go/deepseek-v4-pro`,`opencode-go/deepseek-v4-flash`],efforts:[`minimal`,`low`,`high`,`max`]},copilot:{label:`Copilot`,models:[`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`,`gpt-5.5`,`claude-fable-5`,`claude-opus-4.8`,`claude-opus-4.7`,`claude-sonnet-4.6`,`gpt-5.4`],efforts:[`low`,`medium`,`high`]}};function a(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function o(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))t[n]=a(r);return t}function s(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function c(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e)){let e=o(r);e&&(t[n]=e)}return t}function l(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e)){let e=s(r);e&&(t[n]=e)}return t}function u(e){if(!e||typeof e!=`object`||Array.isArray(e))return{};let n={};for(let[r,i]of Object.entries(e)){if(t(r)||!i||typeof i!=`object`||Array.isArray(i))continue;let e=i,u=o(e.modelsByProvider),d=o(e.effortsByProvider),f=o(e.effortsByModel),p=s(e.defaultEffortByModel),m=c(e.effortsByModelByProvider),h=l(e.defaultEffortByModelByProvider);n[r]={label:typeof e.label==`string`?e.label:r,models:a(e.models),efforts:a(e.efforts),...typeof e.defaultProvider==`string`?{defaultProvider:e.defaultProvider}:{},...e.providers?{providers:a(e.providers)}:{},...u?{modelsByProvider:u}:{},...d?{effortsByProvider:d}:{},...f?{effortsByModel:f}:{},...p?{defaultEffortByModel:p}:{},...m?{effortsByModelByProvider:m}:{},...h?{defaultEffortByModelByProvider:h}:{},...typeof e.modelSource==`string`?{modelSource:e.modelSource}:{},...typeof e.effortNote==`string`?{effortNote:e.effortNote}:{},...typeof e.modelNote==`string`?{modelNote:e.modelNote}:{}}}return n}function d(e,t,n,r){let i=(t||``).trim();if(r){let t=e.effortsByModelByProvider?.[r]?.[i];if(t)return t}return e.effortsByModel?.[i]||(n??e.efforts)}function f(e,t,n,r,i){let a=d(e,t,r,i);if(n&&a.includes(n))return n;let o=(t||``).trim(),s=(i?e.defaultEffortByModelByProvider?.[i]?.[o]:void 0)??e.defaultEffortByModel?.[o]??``;return a.includes(s)?s:``}function p(n,r){return t(n)?{label:e(n),models:[],efforts:[]}:r?.[n]||i[n]||{label:n,models:[],efforts:[]}}function m(e){return e.filter(e=>!t(e))}function h(e){let t=m(e),n=r.filter(e=>t.includes(e)),i=t.filter(e=>!r.includes(e));return[...n,...i]}function g(e,t={},n={}){return n[e]?.model||t[e]?.model||``}function _(e,t={},n={}){return n[e]?.effort||t[e]?.effort||``}function v(e,t=``){let n=new Set;t&&n.add(t);for(let t of e)n.add(t);return Array.from(n).map(e=>({value:e,label:e}))}export{p as a,h as c,m as d,d as i,_ as l,r as n,u as o,f as r,v as s,i as t,g as u};
@@ -1 +0,0 @@
1
- import{r as e,t}from"./bgtask-badge-GHPSB8YA.js";export{t as applyBgtaskUpdate,e as refreshBgtaskBadge};
@@ -1 +0,0 @@
1
- import{n as e}from"./api-CUtiCd2-.js";import{t}from"./cli-engine-NdU0lzs_.js";var n={agy:{label:`Antigravity`,efforts:[],effortNote:`AGY has no separate effort flag`,models:[`Gemini 3.7 Flash (Medium)`,`Gemini 3.6 Flash (Medium)`]},claude:{label:`Claude`,efforts:[`low`,`medium`,`high`,`xhigh`,`max`],models:[`opus`,`sonnet`,`sonnet[1m]`,`haiku`,`claude-fable-5-1`,`claude-fable-5`,`claude-fable-5[1m]`,`claude-sonnet-5`,`claude-sonnet-5[1m]`,`claude-opus-5`,`claude-opus-5[1m]`,`claude-opus-4-8`,`claude-opus-4-8[1m]`,`claude-opus-4-7`,`claude-opus-4-7[1m]`,`claude-opus-4-6`,`claude-opus-4-6[1m]`,`claude-sonnet-4-6`,`claude-sonnet-4-6[1m]`,`claude-haiku-4-5`]},codex:{label:`Codex`,efforts:[`low`,`medium`,`high`,`xhigh`],models:[`gpt-5.5`,`gpt-5.4`,`gpt-5.4-mini`,`gpt-5.3-codex-spark`,`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`]},"codex-app":{label:`Codex App`,efforts:[`low`,`medium`,`high`,`xhigh`],models:[`gpt-5.5`,`gpt-5.4`,`gpt-5.4-mini`,`gpt-5.3-codex-spark`,`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`]},cursor:{label:`Cursor`,efforts:[`none`,`none-fast`,`low`,`low-fast`,`medium`,`medium-fast`,`high`,`high-fast`,`xhigh`,`xhigh-fast`,`max`,`max-fast`],effortNote:`Cursor effort resolves to model IDs; cli-jaw never passes --effort`,models:`auto,composer-2.5,gpt-5.5,gpt-5.6-sol,gpt-5.6-terra,gpt-5.6-luna,gpt-5.4,gpt-5.4-mini,gpt-5.4-nano,gpt-5.3-codex,gpt-5.2,gpt-5.2-codex,gpt-5.1-codex-max,gpt-5.1-codex-mini,gpt-5.1,claude-sonnet-5,claude-fable-5,claude-fable-5-thinking,claude-opus-5,claude-opus-4-8,claude-opus-4-8-thinking,claude-opus-4-7,claude-opus-4-7-thinking,claude-4.6-opus,claude-4.6-sonnet,claude-4.5-opus-high,claude-4.5-sonnet,claude-4-sonnet,gemini-3.1-pro,gemini-3-flash,gemini-3-pro,gemini-3.5-flash,grok-4.6,grok-4.5,gpt-5-mini,glm-5.2,glm-5.3,gpt-5.5-extra,kimi-k2.7-code,kimi-k3,gemini-3.6-flash,gemini-3.7-flash`.split(`,`)},"kiro-code":{label:`Kiro`,efforts:[`low`,`medium`,`high`,`xhigh`],effortNote:`Kiro CLI forwards --effort; cli-jaw maps xhigh to Kiro max on the wire`,models:[`auto`,`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`,`claude-fable-5`,`claude-sonnet-5`,`claude-opus-5`,`claude-opus-4.8`,`claude-opus-4.7`,`claude-opus-4.6`,`claude-sonnet-4.6`,`claude-opus-4.5`,`claude-sonnet-4.5`,`claude-sonnet-4`,`claude-haiku-4.5`,`deepseek-3.2`,`minimax-m2.5`,`minimax-m2.1`,`glm-5`,`qwen3-coder-next`]},gemini:{label:`Gemini`,efforts:[],models:[`gemini-3.0-pro-preview`,`gemini-3.1-pro-preview`,`gemini-2.5-pro`,`gemini-3-flash-preview`,`gemini-2.5-flash`]},grok:{label:`Grok`,efforts:[],effortNote:`unsupported by grok-build/composer; do not pass --effort`,models:[`grok-build`,`grok-composer-2.5-fast`]},opencode:{label:`OpenCode`,efforts:[`minimal`,`low`,`high`,`max`],models:[`opencode-go/kimi-k2.7-code`,`opencode-go/kimi-k3`,`opencode-go/kimi-k2.6`,`opencode-go/kimi-k2.5`,`opencode-go/glm-5.3`,`opencode-go/glm-5.2`,`opencode-go/glm-5.1`,`opencode-go/glm-5`,`opencode-go/grok-4.6`,`opencode-go/grok-4.5`,`opencode-go/minimax-m3`,`opencode-go/minimax-m2.7`,`opencode-go/minimax-m2.5`,`opencode-go/qwen3.7-max`,`opencode-go/qwen3.7-plus`,`opencode-go/qwen3.6-plus`,`opencode-go/qwen3.5-plus`,`opencode-go/mimo-v2.5-pro`,`opencode-go/mimo-v2.5`,`opencode-go/mimo-v2-pro`,`opencode-go/mimo-v2-omni`,`opencode-go/deepseek-v4-pro`,`opencode-go/deepseek-v4-flash`,`opencode-go/hy3`]},copilot:{label:`Copilot`,efforts:[`low`,`medium`,`high`],effortNote:`-> ~/.copilot/config.json`,models:[`gpt-5.6-sol`,`gpt-5.6-terra`,`gpt-5.6-luna`,`gpt-5.5`,`claude-fable-5`,`claude-opus-4.8`,`claude-sonnet-4.6`,`claude-haiku-4.5`,`gpt-5.4`,`gpt-5.3-codex`,`gpt-5.2-codex`,`gpt-5.1-codex`,`gpt-4.1`,`gpt-5-mini`,`gemini-3-pro-preview`]}};function r(e){let t={};for(let[n,r]of Object.entries(e))t[n]=Array.isArray(r?.models)?[...r.models]:[];return t}function i(e){let n={};for(let[r,i]of Object.entries(e||{})){if(t(r)||!i||typeof i!=`object`)continue;let e=i,a={label:e.label||r,efforts:Array.isArray(e.efforts)?[...e.efforts]:[],models:Array.isArray(e.models)?[...e.models]:[]};typeof e.effortNote==`string`&&e.effortNote.trim()&&(a.effortNote=e.effortNote),typeof e.modelNote==`string`&&e.modelNote.trim()&&(a.modelNote=e.modelNote),typeof e.defaultProvider==`string`&&(a.defaultProvider=e.defaultProvider),Array.isArray(e.providers)&&(a.providers=[...e.providers]),e.modelsByProvider&&typeof e.modelsByProvider==`object`&&(a.modelsByProvider=Object.fromEntries(Object.entries(e.modelsByProvider).filter(e=>Array.isArray(e[1])).map(([e,t])=>[e,[...t]]))),e.effortsByProvider&&typeof e.effortsByProvider==`object`&&(a.effortsByProvider=Object.fromEntries(Object.entries(e.effortsByProvider).filter(e=>Array.isArray(e[1])).map(([e,t])=>[e,[...t]]))),e.effortsByModel&&typeof e.effortsByModel==`object`&&(a.effortsByModel=Object.fromEntries(Object.entries(e.effortsByModel).filter(e=>Array.isArray(e[1])).map(([e,t])=>[e,t.filter(e=>typeof e==`string`)]))),e.defaultEffortByModel&&typeof e.defaultEffortByModel==`object`&&(a.defaultEffortByModel=Object.fromEntries(Object.entries(e.defaultEffortByModel).filter(e=>typeof e[1]==`string`))),typeof e.modelSource==`string`&&(a.modelSource=e.modelSource),e.effortsByModelByProvider&&typeof e.effortsByModelByProvider==`object`&&(a.effortsByModelByProvider=Object.fromEntries(Object.entries(e.effortsByModelByProvider).filter(e=>!!e[1]&&typeof e[1]==`object`&&!Array.isArray(e[1])).map(([e,t])=>[e,Object.fromEntries(Object.entries(t).filter(e=>Array.isArray(e[1])).map(([e,t])=>[e,t.filter(e=>typeof e==`string`)]))]))),e.defaultEffortByModelByProvider&&typeof e.defaultEffortByModelByProvider==`object`&&(a.defaultEffortByModelByProvider=Object.fromEntries(Object.entries(e.defaultEffortByModelByProvider).filter(e=>!!e[1]&&typeof e[1]==`object`&&!Array.isArray(e[1])).map(([e,t])=>[e,Object.fromEntries(Object.entries(t).filter(e=>typeof e[1]==`string`))]))),n[r]=a}return n}var a=i(n),o=Object.keys(a),s=r(a);function c(e){let t=i(e);return Object.keys(t).length?(a=t,o=Object.keys(t),s=r(t),!0):!1}async function l(){try{let t=await e(`/api/cli-registry`);if(!t||!c(t))throw Error(`invalid registry`)}catch(e){console.warn(`[cli-registry] fallback:`,e.message),c(n)}return a}function u(){return o}function d(e){return a[e]||null}var f=[`pi`,`claude`,`agy`,`codex`,`cursor`,`kiro-code`,`gemini`],p=[{value:`frontend`,labelKey:`role.label.frontend`,label:`Frontend`,prompt:`Frontend employee — UI/UX, CSS, components`,skill:`jaw-dev-frontend`},{value:`backend`,labelKey:`role.label.backend`,label:`Backend`,prompt:`Backend employee — API, DB, server logic`,skill:`jaw-dev-backend`},{value:`data`,labelKey:`role.label.data`,label:`Data`,prompt:`Data employee — data pipeline, analysis, ML`,skill:`jaw-dev-data`},{value:`docs`,labelKey:`role.label.docs`,label:`Docs`,prompt:`Docs employee — documentation, README, API docs`,skill:`documentation`},{value:`security`,labelKey:`role.label.security`,label:`Security`,prompt:`Security reviewer — auth, secrets, injection, destructive-command, sandbox, and data exposure risks`,skill:`jaw-dev-security`},{value:`testing`,labelKey:`role.label.testing`,label:`Testing`,prompt:`Testing reviewer — unit, integration, regression, smoke, and edge-case coverage`,skill:`jaw-dev-testing`},{value:`custom`,labelKey:`role.label.custom`,label:`Custom...`,prompt:``,skill:null}];export{d as a,u as i,f as n,l as o,p as r,s as t};
@@ -1 +0,0 @@
1
- import{a as e}from"./iframe-renderer-BTTOQPS-.js";export{e as refreshFileWidget};
@@ -1 +0,0 @@
1
- import{a as e}from"./memory-BtrzxI2f.js";export{e as refreshMemorySidebar};
@@ -1 +0,0 @@
1
- import{o as e,s as t}from"./message-history-BPlxn_fF.js";export{e as historyReloadInFlight,t as loadMessages};
@@ -1 +0,0 @@
1
- import{c as e,n as t}from"./settings-core-C9d6LGNB.js";import"./settings-CoalzYdp.js";export{t as loadSettings,e as updateSettings};
@@ -1 +0,0 @@
1
- import{a as e}from"./settings-core-C9d6LGNB.js";export{e as refreshHeaderFromSettingsChange};
@@ -1 +0,0 @@
1
- import{n as e}from"./skills-D0ZTAdcQ.js";export{e as loadSkills};
@@ -1 +0,0 @@
1
- import{a as e}from"./slash-commands-CRaPab4c.js";export{e as loadCommands};
@@ -1 +0,0 @@
1
- import{p as e}from"./iframe-renderer-BTTOQPS-.js";import{I as t,s as n}from"./message-history-BPlxn_fF.js";import{r}from"./ui-BYUrgEqP.js";export{r as cleanupToolActivity,n as loadMessages,e as reconcileChatBottomAfterRestore,t as updateQueueBadge};