shortcutxl 0.4.0 → 0.4.2

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 (75) hide show
  1. package/BINARY-INVENTORY.json +12 -12
  2. package/CHANGELOG.md +6 -0
  3. package/dist/app/agent-session-runtime-adapter.d.ts +5 -0
  4. package/dist/app/agent-session-runtime-adapter.js +7 -4
  5. package/dist/app/agent-session.d.ts +7 -2
  6. package/dist/app/agent-session.js +9 -5
  7. package/dist/app/observability/client-logging/client-logger.d.ts +2 -1
  8. package/dist/app/observability/client-logging/client-logger.js +11 -5
  9. package/dist/app/providers/model-resolver.d.ts +6 -0
  10. package/dist/app/providers/model-resolver.js +23 -20
  11. package/dist/app/services/user-context.d.ts +2 -0
  12. package/dist/app/services/user-context.js +4 -1
  13. package/dist/app/session/account-default-model.d.ts +33 -0
  14. package/dist/app/session/account-default-model.js +53 -0
  15. package/dist/app/session/model-manager.d.ts +15 -4
  16. package/dist/app/session/model-manager.js +23 -8
  17. package/dist/app/session/session-lifecycle.js +14 -12
  18. package/dist/cli.js +1892 -956
  19. package/dist/config.d.ts +13 -5
  20. package/dist/config.js +37 -23
  21. package/dist/contracts/model-stream.d.ts +5 -0
  22. package/dist/contracts/wire.d.ts +3 -1
  23. package/dist/core/agent-engine.d.ts +2 -1
  24. package/dist/core/agent-engine.js +3 -0
  25. package/dist/core/agent-loop.js +8 -2
  26. package/dist/core/core-types.d.ts +3 -1
  27. package/dist/core/session/compaction/compaction.d.ts +2 -0
  28. package/dist/core/session/compaction/compaction.js +3 -0
  29. package/dist/core/session/compaction-bridge.d.ts +2 -1
  30. package/dist/core/session/compaction-bridge.js +4 -1
  31. package/dist/embedded-agent/compaction-wiring.js +4 -1
  32. package/dist/embedded-agent/compose.js +12 -4
  33. package/dist/main.d.ts +7 -0
  34. package/dist/main.js +21 -17
  35. package/dist/rpc/rpc-host.js +7 -1
  36. package/dist/shell/interactive/auth-workflow.js +7 -1
  37. package/dist/shortcut-default-model.d.ts +30 -0
  38. package/dist/shortcut-default-model.js +86 -0
  39. package/dist/startup/terminal-update-flow.js +4 -1
  40. package/dist/startup/update-action.d.ts +17 -2
  41. package/dist/startup/update-action.js +114 -40
  42. package/dist/startup/update-diagnostics.d.ts +85 -0
  43. package/dist/startup/update-diagnostics.js +188 -0
  44. package/dist/startup/update-execution.d.ts +13 -1
  45. package/dist/startup/update-execution.js +205 -6
  46. package/dist/startup/update-installation.d.ts +55 -0
  47. package/dist/startup/update-installation.js +242 -0
  48. package/dist/startup/update-manager.d.ts +5 -0
  49. package/dist/startup/update-manager.js +23 -5
  50. package/dist/startup/update-verification.d.ts +87 -0
  51. package/dist/startup/update-verification.js +204 -0
  52. package/dist/supported-models.generated.js +1 -1
  53. package/native-app/main/chunks/{config-CwtqLhpn.js → config-DSoKsgPT.js} +1 -1
  54. package/native-app/main/chunks/{linux-C5J5oKJy.js → linux-TBGGGecs.js} +3 -3
  55. package/native-app/main/chunks/{mac-Bt_bFwUg.js → mac-Dg93p_2s.js} +3 -3
  56. package/native-app/main/chunks/{setup-worker-protocol-QUVpcuEb.js → setup-worker-protocol-CHVmPxBP.js} +54 -35
  57. package/native-app/main/chunks/{shared-Q59yhreZ.js → shared-BbAcLTbB.js} +1 -1
  58. package/native-app/main/index.js +190 -16
  59. package/native-app/main/setup-worker.js +3 -3
  60. package/native-app/package.json +1 -1
  61. package/native-app/renderer/assets/{index-DkKrXRl6.js → index-BJUrz0xE.js} +2210 -167
  62. package/native-app/renderer/assets/server-PLrRTws-.js +2689 -0
  63. package/native-app/renderer/index.html +1 -1
  64. package/package.json +1 -1
  65. package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
  66. package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
  67. package/xll/python/Lib/site-packages/pip-26.2.dist-info/RECORD +3 -3
  68. package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
  69. package/xll/python/Scripts/httpx.exe +0 -0
  70. package/xll/python/Scripts/idna.exe +0 -0
  71. package/xll/python/Scripts/pip.exe +0 -0
  72. package/xll/python/Scripts/pip3.13.exe +0 -0
  73. package/xll/python/Scripts/pip3.exe +0 -0
  74. package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
  75. package/xll/python/Scripts/pywin32_testall.exe +0 -0
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Post-update check of the ShortcutXL that will actually run next (lyfegame/shortcut#14571).
3
+ *
4
+ * A package manager can exit 0 while the user's next `shortcut` still runs an old release: the
5
+ * update went to a different global prefix than the `shortcut` the terminal resolves first on
6
+ * PATH, or the configured registry served an older package. After the installer exits, the
7
+ * updater reads the updated installation back from disk, resolves `shortcut` on PATH the way each
8
+ * shell does, asks each of those for its version, and only then reports success.
9
+ */
10
+ import { type ActiveInstallation, type UpdateInstallationDeps } from './update-installation.js';
11
+ export interface ResolvedShortcutCommand {
12
+ /** A `shortcut` that a fresh shell runs first from PATH. */
13
+ path: string;
14
+ /** Package the command runs, when its shim can be followed. */
15
+ packageDir?: string;
16
+ /** Version the command runs. */
17
+ version?: string;
18
+ /** Whether the command runs the installation that was updated. */
19
+ runsInstallation: boolean;
20
+ /** `probe`: printed by `<path> --version`; `package`: read from the package it runs. */
21
+ versionSource?: 'package' | 'probe';
22
+ }
23
+ export type UpdateVerification = {
24
+ kind: 'verified';
25
+ /** Version a fresh `shortcut` runs (the installed version without one on PATH). */
26
+ version: string;
27
+ /** Version read back from the updated installation's package.json. */
28
+ installedVersion: string;
29
+ installation: ActiveInstallation;
30
+ command?: ResolvedShortcutCommand;
31
+ } | {
32
+ /** The package manager exited 0 but the running installation is not the target release. */
33
+ kind: 'not-installed';
34
+ installedVersion?: string;
35
+ installation: ActiveInstallation;
36
+ command?: ResolvedShortcutCommand;
37
+ } | {
38
+ /** The target was installed, but a fresh `shortcut` still runs an older release. */
39
+ kind: 'shadowed';
40
+ installedVersion: string;
41
+ installation: ActiveInstallation;
42
+ command: ResolvedShortcutCommand;
43
+ /**
44
+ * Set when cmd.exe already runs the update from this `shortcut`, but PowerShell skips its
45
+ * quoted Path entry and runs `command` instead.
46
+ */
47
+ activePath?: string;
48
+ } | {
49
+ /**
50
+ * The target was installed, but a `shortcut` on PATH could neither report a version nor be
51
+ * followed to a package, so what a fresh invocation runs is unknown.
52
+ */
53
+ kind: 'unconfirmed';
54
+ installedVersion: string;
55
+ installation: ActiveInstallation;
56
+ command: ResolvedShortcutCommand;
57
+ };
58
+ export interface VerifyUpdateDeps extends UpdateInstallationDeps {
59
+ isFile?: (path: string) => boolean;
60
+ /** Version printed by `<path> --version`, or undefined when it can't be read. */
61
+ runVersion?: (path: string, env: NodeJS.ProcessEnv) => Promise<string | undefined>;
62
+ }
63
+ /**
64
+ * Verify that the target release is installed and is what every shell's fresh `shortcut` runs.
65
+ * Without a `shortcut` on PATH, the user runs the updated installation by path.
66
+ */
67
+ export declare function verifyInstalledUpdate(targetVersion: string, installation: ActiveInstallation, deps?: VerifyUpdateDeps): Promise<UpdateVerification>;
68
+ /**
69
+ * The `name` each terminal would run first from PATH (PATHEXT order on Windows), without
70
+ * duplicates. On Windows, cmd.exe unquotes a quoted PATH entry, while PowerShell and where.exe
71
+ * skip it, so the two can run different installs.
72
+ */
73
+ export declare function resolveCommandCandidates(name: string, env: NodeJS.ProcessEnv, platform?: NodeJS.Platform, isFile?: (path: string) => boolean): string[];
74
+ /** Strict major.minor.patch comparison; unparseable versions count as older. */
75
+ export declare function isOlderVersion(version: string, minimum: string): boolean;
76
+ /**
77
+ * The environment for `<path> --version`: the user's own, without the update check and without
78
+ * variables that would make the shim report the running installation instead of its own.
79
+ * Windows variable names are case-insensitive, so they are matched case-insensitively.
80
+ */
81
+ export declare function versionProbeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
82
+ /**
83
+ * The last semver in `shortcut --version` output. Releases before 0.4.1 clear the screen before
84
+ * printing even when piped (`\x1b[2J\x1b[3J\x1b[H0.4.0`), so escape codes are removed first.
85
+ */
86
+ export declare function parseVersionOutput(stdout: string): string | undefined;
87
+ //# sourceMappingURL=update-verification.d.ts.map
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Post-update check of the ShortcutXL that will actually run next (lyfegame/shortcut#14571).
3
+ *
4
+ * A package manager can exit 0 while the user's next `shortcut` still runs an old release: the
5
+ * update went to a different global prefix than the `shortcut` the terminal resolves first on
6
+ * PATH, or the configured registry served an older package. After the installer exits, the
7
+ * updater reads the updated installation back from disk, resolves `shortcut` on PATH the way each
8
+ * shell does, asks each of those for its version, and only then reports success.
9
+ */
10
+ import { spawn } from 'child_process';
11
+ import { statSync } from 'fs';
12
+ import { posix, win32 } from 'path';
13
+ import stripAnsi from 'strip-ansi';
14
+ import { isSameInstallation, packageOfCommand, readInstalledVersion, updatedInstallationDir } from './update-installation.js';
15
+ const COMMAND_NAME = 'shortcut';
16
+ const VERSION_TIMEOUT_MS = 60_000;
17
+ /**
18
+ * Variables that make a `shortcut` report another installation's version than its own:
19
+ * SHORTCUT_PACKAGE_DIR (config.ts getPackageDir) points every shim at the running package.
20
+ */
21
+ const VERSION_REDIRECTING_ENV = new Set(['SHORTCUT_PACKAGE_DIR']);
22
+ /**
23
+ * Verify that the target release is installed and is what every shell's fresh `shortcut` runs.
24
+ * Without a `shortcut` on PATH, the user runs the updated installation by path.
25
+ */
26
+ export async function verifyInstalledUpdate(targetVersion, installation, deps = {}) {
27
+ const env = deps.env ?? process.env;
28
+ const platform = deps.platform ?? process.platform;
29
+ const installationDir = updatedInstallationDir(installation, deps);
30
+ const installedVersion = readInstalledVersion(installationDir, deps);
31
+ const candidates = resolveCommandCandidates(COMMAND_NAME, env, platform, deps.isFile);
32
+ const describe = (path) => describeCommand(path, installationDir, env, deps);
33
+ if (!installedVersion || isOlderVersion(installedVersion, targetVersion)) {
34
+ const [first] = candidates;
35
+ const command = first === undefined ? undefined : await describe(first);
36
+ return { kind: 'not-installed', installedVersion, installation, command };
37
+ }
38
+ // Every shell that could run `shortcut` next must get the new release.
39
+ let active;
40
+ let unconfirmed;
41
+ for (const path of candidates) {
42
+ const command = await describe(path);
43
+ if (command.version === undefined) {
44
+ unconfirmed ??= command;
45
+ }
46
+ else if (isOlderVersion(command.version, targetVersion)) {
47
+ return active
48
+ ? { kind: 'shadowed', installedVersion, installation, command, activePath: active.path }
49
+ : { kind: 'shadowed', installedVersion, installation, command };
50
+ }
51
+ else {
52
+ active ??= command;
53
+ }
54
+ }
55
+ if (unconfirmed) {
56
+ return { kind: 'unconfirmed', installedVersion, installation, command: unconfirmed };
57
+ }
58
+ return {
59
+ kind: 'verified',
60
+ version: active?.version ?? installedVersion,
61
+ installedVersion,
62
+ installation,
63
+ command: active
64
+ };
65
+ }
66
+ /**
67
+ * What one `shortcut` on PATH runs. Its own `--version` output is the version a fresh invocation
68
+ * prints; the package its shim names is the fallback when it cannot be run.
69
+ */
70
+ async function describeCommand(path, installationDir, env, deps) {
71
+ const followed = packageOfCommand(path, deps);
72
+ const command = {
73
+ path,
74
+ runsInstallation: followed.packageDir !== undefined &&
75
+ isSameInstallation(followed.packageDir, installationDir, deps)
76
+ };
77
+ if (followed.packageDir)
78
+ command.packageDir = followed.packageDir;
79
+ const printed = await (deps.runVersion ?? runVersionCommand)(path, env).catch(() => undefined);
80
+ if (printed) {
81
+ command.version = printed;
82
+ command.versionSource = 'probe';
83
+ }
84
+ else if (followed.version) {
85
+ command.version = followed.version;
86
+ command.versionSource = 'package';
87
+ }
88
+ return command;
89
+ }
90
+ /**
91
+ * The `name` each terminal would run first from PATH (PATHEXT order on Windows), without
92
+ * duplicates. On Windows, cmd.exe unquotes a quoted PATH entry, while PowerShell and where.exe
93
+ * skip it, so the two can run different installs.
94
+ */
95
+ export function resolveCommandCandidates(name, env, platform = process.platform, isFile = isExistingFile) {
96
+ const pathKey = Object.keys(env).find((key) => key.toLowerCase() === 'path') ?? 'PATH';
97
+ const entries = (env[pathKey] ?? '')
98
+ .split(platform === 'win32' ? win32.delimiter : posix.delimiter)
99
+ .map((entry) => entry.trim());
100
+ if (platform !== 'win32') {
101
+ const found = firstOnPath(name, entries, posix, [''], isFile);
102
+ return found ? [found] : [];
103
+ }
104
+ const pathExtKey = Object.keys(env).find((key) => key.toLowerCase() === 'pathext') ?? 'PATHEXT';
105
+ const extensions = (env[pathExtKey] ?? '.COM;.EXE;.BAT;.CMD')
106
+ .split(';')
107
+ .map((extension) => extension.trim().toLowerCase())
108
+ .filter(Boolean);
109
+ const isQuoted = (entry) => /^".*"$/.test(entry);
110
+ const cmd = firstOnPath(name, entries.map((entry) => (isQuoted(entry) ? entry.slice(1, -1) : entry)), win32, extensions, isFile);
111
+ const powershell = firstOnPath(name, entries.filter((entry) => !isQuoted(entry)), win32, extensions, isFile);
112
+ return [...new Set([cmd, powershell].filter((path) => path !== undefined))];
113
+ }
114
+ function firstOnPath(name, directories, paths, extensions, isFile) {
115
+ for (const directory of directories) {
116
+ if (!directory || !paths.isAbsolute(directory))
117
+ continue;
118
+ for (const extension of extensions) {
119
+ const candidate = paths.join(directory, `${name}${extension}`);
120
+ if (isFile(candidate))
121
+ return candidate;
122
+ }
123
+ }
124
+ return undefined;
125
+ }
126
+ /** Strict major.minor.patch comparison; unparseable versions count as older. */
127
+ export function isOlderVersion(version, minimum) {
128
+ const parse = (value) => {
129
+ const parts = value.trim().split('-')[0].split('.').map(Number);
130
+ return parts.length === 3 && parts.every((part) => Number.isInteger(part) && part >= 0)
131
+ ? parts
132
+ : undefined;
133
+ };
134
+ const left = parse(version);
135
+ const right = parse(minimum);
136
+ if (!left || !right)
137
+ return true;
138
+ for (let index = 0; index < 3; index += 1) {
139
+ if (left[index] !== right[index])
140
+ return left[index] < right[index];
141
+ }
142
+ return false;
143
+ }
144
+ function isExistingFile(path) {
145
+ try {
146
+ return statSync(path).isFile();
147
+ }
148
+ catch {
149
+ return false;
150
+ }
151
+ }
152
+ /** Run `<path> --version` as the user's next terminal would, without an update check. */
153
+ function runVersionCommand(path, env) {
154
+ const options = {
155
+ env: versionProbeEnv(env),
156
+ stdio: ['ignore', 'pipe', 'ignore'],
157
+ windowsHide: true
158
+ };
159
+ return new Promise((resolve) => {
160
+ // A .cmd/.bat shim needs a shell. Pass it one command line, not an args array, which
161
+ // Node 24 deprecates with shell: true (DEP0190).
162
+ const child = /\.(cmd|bat)$/i.test(path)
163
+ ? spawn(`"${path}" --version`, { ...options, shell: true })
164
+ : spawn(path, ['--version'], options);
165
+ let stdout = '';
166
+ const timer = setTimeout(() => {
167
+ child.kill();
168
+ resolve(undefined);
169
+ }, VERSION_TIMEOUT_MS);
170
+ child.stdout?.on('data', (chunk) => {
171
+ stdout += String(chunk);
172
+ });
173
+ child.once('error', () => {
174
+ clearTimeout(timer);
175
+ resolve(undefined);
176
+ });
177
+ child.once('close', (code) => {
178
+ clearTimeout(timer);
179
+ resolve(code === 0 ? parseVersionOutput(stdout) : undefined);
180
+ });
181
+ });
182
+ }
183
+ /**
184
+ * The environment for `<path> --version`: the user's own, without the update check and without
185
+ * variables that would make the shim report the running installation instead of its own.
186
+ * Windows variable names are case-insensitive, so they are matched case-insensitively.
187
+ */
188
+ export function versionProbeEnv(env) {
189
+ const probeEnv = {};
190
+ for (const [key, value] of Object.entries(env)) {
191
+ if (!VERSION_REDIRECTING_ENV.has(key.toUpperCase()))
192
+ probeEnv[key] = value;
193
+ }
194
+ return { ...probeEnv, SHORTCUT_SKIP_VERSION_CHECK: '1' };
195
+ }
196
+ /**
197
+ * The last semver in `shortcut --version` output. Releases before 0.4.1 clear the screen before
198
+ * printing even when piped (`\x1b[2J\x1b[3J\x1b[H0.4.0`), so escape codes are removed first.
199
+ */
200
+ export function parseVersionOutput(stdout) {
201
+ const versions = stripAnsi(stdout).match(/\b\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b/g);
202
+ return versions ? versions[versions.length - 1] : undefined;
203
+ }
204
+ //# sourceMappingURL=update-verification.js.map
@@ -354,7 +354,7 @@ export const MODEL_CATALOG = {
354
354
  control: 'adaptive-effort',
355
355
  defaultLevel: 'medium',
356
356
  levels: ['low', 'medium', 'high', 'xhigh', 'max'],
357
- supportsOff: true
357
+ supportsOff: false
358
358
  }
359
359
  },
360
360
  protocol: 'anthropic-messages'
@@ -1,6 +1,6 @@
1
1
  import { appendFileSync, mkdirSync, existsSync, readFileSync, writeFileSync } from "fs";
2
2
  import { join, dirname } from "path";
3
- import { g as getAgentDir } from "./setup-worker-protocol-QUVpcuEb.js";
3
+ import { g as getAgentDir } from "./setup-worker-protocol-CHVmPxBP.js";
4
4
  import "node:process";
5
5
  import "node:os";
6
6
  import "node:tty";
@@ -1,9 +1,9 @@
1
1
  import { existsSync } from "fs";
2
- import { e as ensureUv$1 } from "./shared-Q59yhreZ.js";
3
- import { a, b, c, s } from "./shared-Q59yhreZ.js";
2
+ import { e as ensureUv$1 } from "./shared-BbAcLTbB.js";
3
+ import { a, b, c, s } from "./shared-BbAcLTbB.js";
4
4
  import { h as header, o as ok, l as log } from "../setup-worker.js";
5
5
  import "path";
6
- import "./setup-worker-protocol-QUVpcuEb.js";
6
+ import "./setup-worker-protocol-CHVmPxBP.js";
7
7
  import "node:process";
8
8
  import "node:os";
9
9
  import "node:tty";
@@ -1,9 +1,9 @@
1
1
  import { existsSync } from "fs";
2
- import { e as ensureUv$1 } from "./shared-Q59yhreZ.js";
3
- import { a, b, c, s } from "./shared-Q59yhreZ.js";
2
+ import { e as ensureUv$1 } from "./shared-BbAcLTbB.js";
3
+ import { a, b, c, s } from "./shared-BbAcLTbB.js";
4
4
  import { h as header, o as ok, l as log } from "../setup-worker.js";
5
5
  import "path";
6
- import "./setup-worker-protocol-QUVpcuEb.js";
6
+ import "./setup-worker-protocol-CHVmPxBP.js";
7
7
  import "node:process";
8
8
  import "node:os";
9
9
  import "node:tty";
@@ -508,33 +508,50 @@ function detectInstallMethod() {
508
508
  }
509
509
  function getUpdateInstruction(packageName) {
510
510
  const method = detectInstallMethod();
511
+ const suffix = process.platform === "win32" ? ".cmd" : "";
511
512
  switch (method) {
512
513
  case "pnpm":
513
514
  return `Run: pnpm add -g ${packageName}`;
514
515
  case "yarn":
515
516
  return `Run: yarn global add ${packageName}`;
516
517
  case "npm":
517
- return `Run: npm install -g ${packageName}`;
518
+ return `Run: npm${suffix} install -g ${packageName}`;
518
519
  default:
519
- return `Run: npm install -g ${packageName}`;
520
+ return `Run: npm${suffix} install -g ${packageName}`;
520
521
  }
521
522
  }
522
- function getUpdateCommand(packageName) {
523
- const command = getUpdateLaunchCommand(packageName);
524
- return [command.executable, ...command.args].join(" ");
523
+ function getUpdateCommand(packageName, target = {}) {
524
+ const command = getUpdateLaunchCommand(packageName, target);
525
+ return [command.executable, ...command.args.map(quoteShellArgument)].join(" ");
525
526
  }
526
- function getUpdateLaunchCommand(packageName) {
527
+ function getUpdateLaunchCommand(packageName, target = {}) {
528
+ const spec = target.version ? `${packageName}@${target.version}` : packageName;
527
529
  switch (detectInstallMethod()) {
528
530
  case "pnpm":
529
- return { executable: "pnpm", args: ["add", "-g", packageName] };
531
+ return { executable: "pnpm", args: ["add", "-g", spec] };
530
532
  case "yarn":
531
- return { executable: "yarn", args: ["global", "add", packageName] };
533
+ return { executable: "yarn", args: ["global", "add", spec] };
532
534
  case "npm":
533
535
  default:
534
- return { executable: "npm", args: ["install", "-g", packageName] };
536
+ return {
537
+ executable: "npm",
538
+ args: [
539
+ "install",
540
+ "-g",
541
+ // Forward slashes keep Windows paths intact in both Git Bash and cmd.exe.
542
+ ...target.npmPrefix ? ["--prefix", target.npmPrefix.replaceAll("\\", "/")] : [],
543
+ spec
544
+ ]
545
+ };
535
546
  }
536
547
  }
548
+ function quoteShellArgument(argument) {
549
+ return /^[\w@./:=+-]+$/.test(argument) ? argument : `"${argument.replaceAll('"', "")}"`;
550
+ }
537
551
  function getPackageDir() {
552
+ return getPackageDirOverride() ?? getRuntimePackageDir();
553
+ }
554
+ function getPackageDirOverride() {
538
555
  const envDir = process.env.SHORTCUT_PACKAGE_DIR;
539
556
  if (envDir) {
540
557
  if (envDir === "~")
@@ -543,6 +560,9 @@ function getPackageDir() {
543
560
  return homedir() + envDir.slice(1);
544
561
  return envDir;
545
562
  }
563
+ return void 0;
564
+ }
565
+ function getRuntimePackageDir() {
546
566
  let dir = __dirname$1;
547
567
  while (dir !== dirname(dir)) {
548
568
  if (existsSync(join(dir, "package.json"))) {
@@ -550,7 +570,7 @@ function getPackageDir() {
550
570
  }
551
571
  dir = dirname(dir);
552
572
  }
553
- return __dirname$1;
573
+ return getPackageDirOverride() ?? __dirname$1;
554
574
  }
555
575
  function isSourceCheckout() {
556
576
  return process.env.SHORTCUT_FORCE_SOURCE_CHECKOUT === "1";
@@ -589,9 +609,6 @@ function getExportTemplateDir() {
589
609
  "src/shell/export-html"
590
610
  ]);
591
611
  }
592
- function getPackageJsonPath() {
593
- return join(getPackageDir(), "package.json");
594
- }
595
612
  function getDocsPath() {
596
613
  return resolve(join(getPackageDir(), "agent-docs", "docs"));
597
614
  }
@@ -601,7 +618,7 @@ function getUserDocsPath() {
601
618
  function getChangelogPath() {
602
619
  return resolve(join(getPackageDir(), "CHANGELOG.md"));
603
620
  }
604
- const pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
621
+ const pkg = JSON.parse(readFileSync(join(getRuntimePackageDir(), "package.json"), "utf-8"));
605
622
  const APP_NAME = pkg.shortcutConfig?.name || "shortcut";
606
623
  const CONFIG_DIR_NAME = pkg.shortcutConfig?.configDir || ".shortcut";
607
624
  const VERSION = pkg.version;
@@ -627,7 +644,7 @@ function isNewSheetEnabled() {
627
644
  }
628
645
  const NPM_REGISTRY_URL = process.env.SHORTCUT_NPM_REGISTRY_URL?.trim() || `https://registry.npmjs.org/${NPM_PACKAGE_NAME}/latest`;
629
646
  function resolveOwnBinary() {
630
- const packageDir = getPackageDir();
647
+ const packageDir = getRuntimePackageDir();
631
648
  const currentScript = process.argv[1] ? resolve(process.argv[1]) : "";
632
649
  const preferSource = currentScript.endsWith(".ts");
633
650
  const candidates = preferSource ? [join(packageDir, "src/cli.ts"), join(packageDir, "dist/cli.js")] : [join(packageDir, "dist/cli.js"), join(packageDir, "src/cli.ts")];
@@ -793,6 +810,7 @@ const config = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
793
810
  getPowerPointBridgePath,
794
811
  getPromptsDir,
795
812
  getPythonPathDirs,
813
+ getRuntimePackageDir,
796
814
  getSessionsDir,
797
815
  getSettingsPath,
798
816
  getStableXllDir,
@@ -839,26 +857,27 @@ export {
839
857
  NPM_PACKAGE_NAME as N,
840
858
  VERSION as V,
841
859
  getPackageDir as a,
842
- getUpdateCachePath as b,
860
+ getRuntimePackageDir as b,
843
861
  chalk as c,
844
- NPM_REGISTRY_URL as d,
845
- getUpdateLaunchCommand as e,
846
- getUpdateCommand as f,
862
+ getUpdateCachePath as d,
863
+ NPM_REGISTRY_URL as e,
864
+ getUpdateLaunchCommand as f,
847
865
  getAgentDir as g,
848
- getUpdateInstruction as h,
849
- getBinDir as i,
850
- isSetupWorkerMessage as j,
851
- getStableXllDir as k,
852
- getXllPath as l,
853
- getEmbeddedPythonExe as m,
854
- getWordBridgePath as n,
855
- getPowerPointBridgePath as o,
856
- isInstalled as p,
857
- isSourceCheckout as q,
858
- isSetupWorkerResponse as r,
859
- getSettingsPath as s,
860
- getUvBinPath as t,
861
- getUvVenvDir as u,
862
- getUvPythonDir as v,
863
- config as w
866
+ getUpdateCommand as h,
867
+ getUpdateInstruction as i,
868
+ getBinDir as j,
869
+ isSetupWorkerMessage as k,
870
+ getStableXllDir as l,
871
+ getXllPath as m,
872
+ getEmbeddedPythonExe as n,
873
+ getWordBridgePath as o,
874
+ getPowerPointBridgePath as p,
875
+ isInstalled as q,
876
+ isSourceCheckout as r,
877
+ isSetupWorkerResponse as s,
878
+ getSettingsPath as t,
879
+ getUvBinPath as u,
880
+ getUvVenvDir as v,
881
+ getUvPythonDir as w,
882
+ config as x
864
883
  };
@@ -1,6 +1,6 @@
1
1
  import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, chmodSync } from "fs";
2
2
  import { join, dirname } from "path";
3
- import { s as getSettingsPath, t as getUvBinPath, u as getUvVenvDir, V as VERSION, v as getUvPythonDir } from "./setup-worker-protocol-QUVpcuEb.js";
3
+ import { t as getSettingsPath, u as getUvBinPath, v as getUvVenvDir, V as VERSION, w as getUvPythonDir } from "./setup-worker-protocol-CHVmPxBP.js";
4
4
  import { h as header, o as ok, l as log, n as note, r as runWithProgress, a as run } from "../setup-worker.js";
5
5
  const UV_VERSION = "0.7.2";
6
6
  const UV_PYTHON_VERSION = "3.13";