@alisaitteke/photoshop-mcp 0.1.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 (115) hide show
  1. package/.prettierrc +9 -0
  2. package/README.md +1300 -0
  3. package/dist/api/batch-play.d.ts +62 -0
  4. package/dist/api/batch-play.d.ts.map +1 -0
  5. package/dist/api/batch-play.js +131 -0
  6. package/dist/api/batch-play.js.map +1 -0
  7. package/dist/api/extendscript.d.ts +258 -0
  8. package/dist/api/extendscript.d.ts.map +1 -0
  9. package/dist/api/extendscript.js +1437 -0
  10. package/dist/api/extendscript.js.map +1 -0
  11. package/dist/api/photoshop-api.d.ts +20 -0
  12. package/dist/api/photoshop-api.d.ts.map +1 -0
  13. package/dist/api/photoshop-api.js +88 -0
  14. package/dist/api/photoshop-api.js.map +1 -0
  15. package/dist/core/server.d.ts +14 -0
  16. package/dist/core/server.d.ts.map +1 -0
  17. package/dist/core/server.js +191 -0
  18. package/dist/core/server.js.map +1 -0
  19. package/dist/core/session.d.ts +24 -0
  20. package/dist/core/session.d.ts.map +1 -0
  21. package/dist/core/session.js +83 -0
  22. package/dist/core/session.js.map +1 -0
  23. package/dist/core/tool-registry.d.ts +23 -0
  24. package/dist/core/tool-registry.d.ts.map +1 -0
  25. package/dist/core/tool-registry.js +55 -0
  26. package/dist/core/tool-registry.js.map +1 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +18 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/platform/connection.d.ts +20 -0
  32. package/dist/platform/connection.d.ts.map +1 -0
  33. package/dist/platform/connection.js +94 -0
  34. package/dist/platform/connection.js.map +1 -0
  35. package/dist/platform/detector.d.ts +19 -0
  36. package/dist/platform/detector.d.ts.map +1 -0
  37. package/dist/platform/detector.js +63 -0
  38. package/dist/platform/detector.js.map +1 -0
  39. package/dist/platform/macos-detector.d.ts +13 -0
  40. package/dist/platform/macos-detector.d.ts.map +1 -0
  41. package/dist/platform/macos-detector.js +145 -0
  42. package/dist/platform/macos-detector.js.map +1 -0
  43. package/dist/platform/macos-executor.d.ts +22 -0
  44. package/dist/platform/macos-executor.d.ts.map +1 -0
  45. package/dist/platform/macos-executor.js +161 -0
  46. package/dist/platform/macos-executor.js.map +1 -0
  47. package/dist/platform/script-executor.d.ts +23 -0
  48. package/dist/platform/script-executor.d.ts.map +1 -0
  49. package/dist/platform/script-executor.js +2 -0
  50. package/dist/platform/script-executor.js.map +1 -0
  51. package/dist/platform/windows-detector.d.ts +14 -0
  52. package/dist/platform/windows-detector.d.ts.map +1 -0
  53. package/dist/platform/windows-detector.js +173 -0
  54. package/dist/platform/windows-detector.js.map +1 -0
  55. package/dist/platform/windows-executor.d.ts +15 -0
  56. package/dist/platform/windows-executor.d.ts.map +1 -0
  57. package/dist/platform/windows-executor.js +148 -0
  58. package/dist/platform/windows-executor.js.map +1 -0
  59. package/dist/tools/action-tools.d.ts +4 -0
  60. package/dist/tools/action-tools.d.ts.map +1 -0
  61. package/dist/tools/action-tools.js +102 -0
  62. package/dist/tools/action-tools.js.map +1 -0
  63. package/dist/tools/adjustment-tools.d.ts +4 -0
  64. package/dist/tools/adjustment-tools.d.ts.map +1 -0
  65. package/dist/tools/adjustment-tools.js +274 -0
  66. package/dist/tools/adjustment-tools.js.map +1 -0
  67. package/dist/tools/document-tools.d.ts +4 -0
  68. package/dist/tools/document-tools.d.ts.map +1 -0
  69. package/dist/tools/document-tools.js +230 -0
  70. package/dist/tools/document-tools.js.map +1 -0
  71. package/dist/tools/filter-tools.d.ts +4 -0
  72. package/dist/tools/filter-tools.d.ts.map +1 -0
  73. package/dist/tools/filter-tools.js +230 -0
  74. package/dist/tools/filter-tools.js.map +1 -0
  75. package/dist/tools/history-tools.d.ts +4 -0
  76. package/dist/tools/history-tools.d.ts.map +1 -0
  77. package/dist/tools/history-tools.js +137 -0
  78. package/dist/tools/history-tools.js.map +1 -0
  79. package/dist/tools/image-placement-tools.d.ts +4 -0
  80. package/dist/tools/image-placement-tools.d.ts.map +1 -0
  81. package/dist/tools/image-placement-tools.js +109 -0
  82. package/dist/tools/image-placement-tools.js.map +1 -0
  83. package/dist/tools/image-tools.d.ts +4 -0
  84. package/dist/tools/image-tools.d.ts.map +1 -0
  85. package/dist/tools/image-tools.js +123 -0
  86. package/dist/tools/image-tools.js.map +1 -0
  87. package/dist/tools/layer-ordering-tools.d.ts +4 -0
  88. package/dist/tools/layer-ordering-tools.d.ts.map +1 -0
  89. package/dist/tools/layer-ordering-tools.js +210 -0
  90. package/dist/tools/layer-ordering-tools.js.map +1 -0
  91. package/dist/tools/layer-properties-tools.d.ts +4 -0
  92. package/dist/tools/layer-properties-tools.d.ts.map +1 -0
  93. package/dist/tools/layer-properties-tools.js +421 -0
  94. package/dist/tools/layer-properties-tools.js.map +1 -0
  95. package/dist/tools/layer-tools.d.ts +4 -0
  96. package/dist/tools/layer-tools.d.ts.map +1 -0
  97. package/dist/tools/layer-tools.js +251 -0
  98. package/dist/tools/layer-tools.js.map +1 -0
  99. package/dist/tools/layer-transform-tools.d.ts +4 -0
  100. package/dist/tools/layer-transform-tools.d.ts.map +1 -0
  101. package/dist/tools/layer-transform-tools.js +199 -0
  102. package/dist/tools/layer-transform-tools.js.map +1 -0
  103. package/dist/tools/selection-tools.d.ts +4 -0
  104. package/dist/tools/selection-tools.d.ts.map +1 -0
  105. package/dist/tools/selection-tools.js +295 -0
  106. package/dist/tools/selection-tools.js.map +1 -0
  107. package/dist/tools/text-tools.d.ts +4 -0
  108. package/dist/tools/text-tools.d.ts.map +1 -0
  109. package/dist/tools/text-tools.js +210 -0
  110. package/dist/tools/text-tools.js.map +1 -0
  111. package/dist/utils/logger.d.ts +17 -0
  112. package/dist/utils/logger.d.ts.map +1 -0
  113. package/dist/utils/logger.js +43 -0
  114. package/dist/utils/logger.js.map +1 -0
  115. package/package.json +47 -0
@@ -0,0 +1,94 @@
1
+ import { platform } from 'os';
2
+ import { Logger } from '../utils/logger.js';
3
+ import { PhotoshopDetector } from './detector.js';
4
+ import { WindowsExecutor } from './windows-executor.js';
5
+ import { MacOSExecutor } from './macos-executor.js';
6
+ export class PhotoshopConnection {
7
+ logger;
8
+ detector;
9
+ executor;
10
+ photoshopInfo = null;
11
+ macosExecutor;
12
+ constructor() {
13
+ this.logger = new Logger('PhotoshopConnection');
14
+ this.detector = new PhotoshopDetector();
15
+ // Initialize platform-specific executor
16
+ const platformType = platform();
17
+ if (platformType === 'win32') {
18
+ this.executor = new WindowsExecutor();
19
+ }
20
+ else if (platformType === 'darwin') {
21
+ this.macosExecutor = new MacOSExecutor();
22
+ this.executor = this.macosExecutor;
23
+ }
24
+ else {
25
+ throw new Error(`Unsupported platform: ${platformType}`);
26
+ }
27
+ }
28
+ async ping() {
29
+ try {
30
+ this.logger.debug('Pinging Photoshop...');
31
+ // Try to detect Photoshop if not already detected
32
+ if (!this.photoshopInfo) {
33
+ this.photoshopInfo = await this.detector.detect();
34
+ }
35
+ // For now, just check if Photoshop is detected
36
+ return this.photoshopInfo !== null;
37
+ }
38
+ catch (error) {
39
+ this.logger.error('Ping failed:', error);
40
+ return false;
41
+ }
42
+ }
43
+ async getVersion() {
44
+ try {
45
+ if (!this.photoshopInfo) {
46
+ this.photoshopInfo = await this.detector.detect();
47
+ }
48
+ return this.photoshopInfo?.version || 'Unknown';
49
+ }
50
+ catch (error) {
51
+ this.logger.error('Failed to get version:', error);
52
+ throw error;
53
+ }
54
+ }
55
+ async executeScript(script, timeout) {
56
+ try {
57
+ // Ensure Photoshop is detected
58
+ if (!this.photoshopInfo) {
59
+ this.photoshopInfo = await this.detector.detect();
60
+ }
61
+ // Set app name for macOS executor
62
+ if (this.macosExecutor && this.photoshopInfo.appName) {
63
+ this.macosExecutor.setAppName(this.photoshopInfo.appName);
64
+ }
65
+ // Check if Photoshop is running, launch if needed
66
+ const isRunning = await this.executor.isPhotoshopRunning();
67
+ if (!isRunning) {
68
+ this.logger.info('Photoshop not running, launching...');
69
+ await this.executor.launchPhotoshop(this.photoshopInfo.path);
70
+ }
71
+ // Execute the script
72
+ const result = await this.executor.execute(script, timeout);
73
+ return result;
74
+ }
75
+ catch (error) {
76
+ this.logger.error('Script execution failed:', error);
77
+ throw error;
78
+ }
79
+ }
80
+ getPhotoshopInfo() {
81
+ return this.photoshopInfo;
82
+ }
83
+ async ensurePhotoshopRunning() {
84
+ if (!this.photoshopInfo) {
85
+ this.photoshopInfo = await this.detector.detect();
86
+ }
87
+ const isRunning = await this.executor.isPhotoshopRunning();
88
+ if (!isRunning) {
89
+ this.logger.info('Launching Photoshop...');
90
+ await this.executor.launchPhotoshop(this.photoshopInfo.path);
91
+ }
92
+ }
93
+ }
94
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/platform/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { PhotoshopInfo } from './connection.js';
2
+ export declare class PhotoshopDetector {
3
+ private logger;
4
+ private platformType;
5
+ private windowsDetector?;
6
+ private macosDetector?;
7
+ constructor();
8
+ detect(): Promise<PhotoshopInfo>;
9
+ /**
10
+ * Determine if detected Photoshop version supports UXP
11
+ * UXP is supported in Photoshop 23.5+ (roughly 2022+)
12
+ */
13
+ supportsUXP(version: string): boolean;
14
+ /**
15
+ * Get recommended API type based on version
16
+ */
17
+ getRecommendedAPI(version: string): 'UXP' | 'ExtendScript';
18
+ }
19
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/platform/detector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAgB;;IAchC,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IAYtC;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAuBrC;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,cAAc;CAG3D"}
@@ -0,0 +1,63 @@
1
+ import { platform } from 'os';
2
+ import { Logger } from '../utils/logger.js';
3
+ import { WindowsDetector } from './windows-detector.js';
4
+ import { MacOSDetector } from './macos-detector.js';
5
+ export class PhotoshopDetector {
6
+ logger;
7
+ platformType;
8
+ windowsDetector;
9
+ macosDetector;
10
+ constructor() {
11
+ this.logger = new Logger('PhotoshopDetector');
12
+ this.platformType = platform();
13
+ // Initialize platform-specific detector
14
+ if (this.platformType === 'win32') {
15
+ this.windowsDetector = new WindowsDetector();
16
+ }
17
+ else if (this.platformType === 'darwin') {
18
+ this.macosDetector = new MacOSDetector();
19
+ }
20
+ }
21
+ async detect() {
22
+ this.logger.info(`Detecting Photoshop on ${this.platformType}...`);
23
+ if (this.platformType === 'win32' && this.windowsDetector) {
24
+ return await this.windowsDetector.detect();
25
+ }
26
+ else if (this.platformType === 'darwin' && this.macosDetector) {
27
+ return await this.macosDetector.detect();
28
+ }
29
+ else {
30
+ throw new Error(`Unsupported platform: ${this.platformType}`);
31
+ }
32
+ }
33
+ /**
34
+ * Determine if detected Photoshop version supports UXP
35
+ * UXP is supported in Photoshop 23.5+ (roughly 2022+)
36
+ */
37
+ supportsUXP(version) {
38
+ // Try to extract numeric version
39
+ const versionMatch = version.match(/(\d+)\.?(\d*)/);
40
+ if (versionMatch) {
41
+ const major = parseInt(versionMatch[1], 10);
42
+ const minor = versionMatch[2] ? parseInt(versionMatch[2], 10) : 0;
43
+ // Photoshop 23.5 or higher supports UXP
44
+ return major > 23 || (major === 23 && minor >= 5);
45
+ }
46
+ // Try to extract year from version
47
+ const yearMatch = version.match(/20(\d{2})/);
48
+ if (yearMatch) {
49
+ const year = parseInt(`20${yearMatch[1]}`, 10);
50
+ // 2022 and later support UXP
51
+ return year >= 2022;
52
+ }
53
+ // Default to false for unknown versions
54
+ return false;
55
+ }
56
+ /**
57
+ * Get recommended API type based on version
58
+ */
59
+ getRecommendedAPI(version) {
60
+ return this.supportsUXP(version) ? 'UXP' : 'ExtendScript';
61
+ }
62
+ }
63
+ //# sourceMappingURL=detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/platform/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,iBAAiB;IACpB,MAAM,CAAS;IACf,YAAY,CAAkB;IAC9B,eAAe,CAAmB;IAClC,aAAa,CAAiB;IAEtC;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,GAAG,QAAQ,EAAE,CAAC;QAE/B,wCAAwC;QACxC,IAAI,IAAI,CAAC,YAAY,KAAK,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC/C,CAAC;aAAM,IAAI,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,YAAY,KAAK,CAAC,CAAC;QAEnE,IAAI,IAAI,CAAC,YAAY,KAAK,OAAO,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1D,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;QAC7C,CAAC;aAAM,IAAI,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAChE,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,OAAe;QACzB,iCAAiC;QACjC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAElE,wCAAwC;YACxC,OAAO,KAAK,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,mCAAmC;QACnC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC/C,6BAA6B;YAC7B,OAAO,IAAI,IAAI,IAAI,CAAC;QACtB,CAAC;QAED,wCAAwC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,OAAe;QAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC;IAC5D,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { PhotoshopInfo } from './connection.js';
2
+ export declare class MacOSDetector {
3
+ private logger;
4
+ constructor();
5
+ detect(): Promise<PhotoshopInfo>;
6
+ private detectUsingSpotlight;
7
+ private getCommonPaths;
8
+ private checkPath;
9
+ private extractVersionFromApp;
10
+ private checkIfRunning;
11
+ getAppBundleId(appPath: string): Promise<string | null>;
12
+ }
13
+ //# sourceMappingURL=macos-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-detector.d.ts","sourceRoot":"","sources":["../../src/platform/macos-detector.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;;IAMjB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;YA6BxB,oBAAoB;IAuBlC,OAAO,CAAC,cAAc;YAsBR,SAAS;YA2BT,qBAAqB;YAwCrB,cAAc;IActB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAW9D"}
@@ -0,0 +1,145 @@
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { access, constants, readFile } from 'fs/promises';
4
+ import { Logger } from '../utils/logger.js';
5
+ const execAsync = promisify(exec);
6
+ export class MacOSDetector {
7
+ logger;
8
+ constructor() {
9
+ this.logger = new Logger('MacOSDetector');
10
+ }
11
+ async detect() {
12
+ this.logger.info('Detecting Photoshop on macOS...');
13
+ // Try environment variable first
14
+ const envPath = process.env.PHOTOSHOP_PATH;
15
+ if (envPath) {
16
+ this.logger.debug(`Using environment variable: ${envPath}`);
17
+ const info = await this.checkPath(envPath);
18
+ if (info)
19
+ return info;
20
+ }
21
+ // Try mdfind (Spotlight) for fast detection
22
+ try {
23
+ const spotlightInfo = await this.detectUsingSpotlight();
24
+ if (spotlightInfo)
25
+ return spotlightInfo;
26
+ }
27
+ catch (error) {
28
+ this.logger.warn('Spotlight detection failed:', error);
29
+ }
30
+ // Try common installation paths
31
+ const commonPaths = this.getCommonPaths();
32
+ for (const path of commonPaths) {
33
+ const info = await this.checkPath(path);
34
+ if (info)
35
+ return info;
36
+ }
37
+ throw new Error('Photoshop not found on this system');
38
+ }
39
+ async detectUsingSpotlight() {
40
+ try {
41
+ // Use mdfind to search for Photoshop applications
42
+ const { stdout } = await execAsync('mdfind "kMDItemCFBundleIdentifier == com.adobe.Photoshop"');
43
+ const apps = stdout
44
+ .split('\n')
45
+ .filter((line) => line.trim() && line.endsWith('.app'))
46
+ .sort((a, b) => b.localeCompare(a)); // Sort descending to get latest version first
47
+ for (const appPath of apps) {
48
+ const info = await this.checkPath(appPath);
49
+ if (info)
50
+ return info;
51
+ }
52
+ }
53
+ catch (error) {
54
+ this.logger.debug('Spotlight search failed:', error);
55
+ }
56
+ return null;
57
+ }
58
+ getCommonPaths() {
59
+ const paths = [];
60
+ // Generate paths for versions 2012-2025
61
+ for (let year = 2025; year >= 2012; year--) {
62
+ paths.push(`/Applications/Adobe Photoshop ${year}/Adobe Photoshop ${year}.app`, `/Applications/Adobe Photoshop CC ${year}/Adobe Photoshop CC ${year}.app`, `/Applications/Adobe Photoshop ${year}.app`);
63
+ }
64
+ // Also check for version-less installation
65
+ paths.push('/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app', '/Applications/Adobe Photoshop/Adobe Photoshop.app', '/Applications/Adobe Photoshop.app');
66
+ return paths;
67
+ }
68
+ async checkPath(path) {
69
+ try {
70
+ // Clean up path
71
+ const cleanPath = path.trim();
72
+ // Check if path exists
73
+ await access(cleanPath, constants.F_OK);
74
+ // Get version from Info.plist
75
+ const version = await this.extractVersionFromApp(cleanPath);
76
+ // Extract app name from path
77
+ const appName = cleanPath.split('/').pop()?.replace('.app', '') || 'Adobe Photoshop 2025';
78
+ this.logger.info(`Found Photoshop at: ${cleanPath}`);
79
+ return {
80
+ version,
81
+ path: cleanPath,
82
+ isRunning: await this.checkIfRunning(cleanPath),
83
+ appName,
84
+ };
85
+ }
86
+ catch (error) {
87
+ return null;
88
+ }
89
+ }
90
+ async extractVersionFromApp(appPath) {
91
+ try {
92
+ // Try to read version from Info.plist
93
+ const plistPath = `${appPath}/Contents/Info.plist`;
94
+ try {
95
+ await access(plistPath, constants.F_OK);
96
+ // Use PlistBuddy to extract version
97
+ const { stdout: version } = await execAsync(`/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "${plistPath}"`);
98
+ if (version.trim()) {
99
+ return version.trim();
100
+ }
101
+ }
102
+ catch (error) {
103
+ // PlistBuddy failed, try parsing manually
104
+ const content = await readFile(plistPath, 'utf8');
105
+ const versionMatch = content.match(/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/);
106
+ if (versionMatch) {
107
+ return versionMatch[1];
108
+ }
109
+ }
110
+ // Fallback: extract year from path
111
+ const yearMatch = appPath.match(/(\d{4})/);
112
+ if (yearMatch) {
113
+ return yearMatch[1];
114
+ }
115
+ }
116
+ catch (error) {
117
+ this.logger.debug('Failed to extract version from app:', error);
118
+ }
119
+ return 'Unknown';
120
+ }
121
+ async checkIfRunning(appPath) {
122
+ try {
123
+ // Get the app name from path
124
+ const appName = appPath.split('/').pop()?.replace('.app', '') || 'Adobe Photoshop';
125
+ // Use pgrep to check if process is running
126
+ const { stdout } = await execAsync(`pgrep -f "${appName}"`);
127
+ return stdout.trim().length > 0;
128
+ }
129
+ catch (error) {
130
+ // pgrep returns non-zero exit code if no process found
131
+ return false;
132
+ }
133
+ }
134
+ async getAppBundleId(appPath) {
135
+ try {
136
+ const plistPath = `${appPath}/Contents/Info.plist`;
137
+ const { stdout } = await execAsync(`/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${plistPath}"`);
138
+ return stdout.trim();
139
+ }
140
+ catch (error) {
141
+ return null;
142
+ }
143
+ }
144
+ }
145
+ //# sourceMappingURL=macos-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-detector.js","sourceRoot":"","sources":["../../src/platform/macos-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { ScriptExecutor } from './script-executor.js';
2
+ export declare class MacOSExecutor implements ScriptExecutor {
3
+ private logger;
4
+ private scriptQueue;
5
+ private isProcessing;
6
+ private appName;
7
+ constructor();
8
+ setAppName(appName: string): void;
9
+ execute(script: string, timeout?: number): Promise<unknown>;
10
+ private processQueue;
11
+ private executeScript;
12
+ private createAppleScriptWrapper;
13
+ private parseResult;
14
+ isPhotoshopRunning(): Promise<boolean>;
15
+ launchPhotoshop(photoshopPath: string): Promise<void>;
16
+ /**
17
+ * Alternative method using 'do shell script' via AppleScript
18
+ * This can be more reliable for some versions
19
+ */
20
+ executeViaDoShellScript(script: string): Promise<unknown>;
21
+ }
22
+ //# sourceMappingURL=macos-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-executor.d.ts","sourceRoot":"","sources":["../../src/platform/macos-executor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAItD,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAkC;;IAMjD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAc,GAAG,OAAO,CAAC,OAAO,CAAC;YAuB1D,YAAY;YAqBZ,aAAa;IAmC3B,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,WAAW;IAYb,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAUtC,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB3D;;;OAGG;IACG,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAoBhE"}
@@ -0,0 +1,161 @@
1
+ import { exec, spawn } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { writeFile, unlink } from 'fs/promises';
4
+ import { tmpdir } from 'os';
5
+ import { join } from 'path';
6
+ import { Logger } from '../utils/logger.js';
7
+ const execAsync = promisify(exec);
8
+ export class MacOSExecutor {
9
+ logger;
10
+ scriptQueue = [];
11
+ isProcessing = false;
12
+ appName = 'Adobe Photoshop 2025';
13
+ constructor() {
14
+ this.logger = new Logger('MacOSExecutor');
15
+ }
16
+ setAppName(appName) {
17
+ this.appName = appName;
18
+ this.logger.debug(`App name set to: ${appName}`);
19
+ }
20
+ async execute(script, timeout = 30000) {
21
+ return new Promise((resolve, reject) => {
22
+ const timeoutId = setTimeout(() => {
23
+ reject(new Error('Script execution timeout'));
24
+ }, timeout);
25
+ this.scriptQueue.push(async () => {
26
+ try {
27
+ const result = await this.executeScript(script);
28
+ clearTimeout(timeoutId);
29
+ resolve(result);
30
+ return result;
31
+ }
32
+ catch (error) {
33
+ clearTimeout(timeoutId);
34
+ reject(error);
35
+ throw error;
36
+ }
37
+ });
38
+ this.processQueue();
39
+ });
40
+ }
41
+ async processQueue() {
42
+ if (this.isProcessing || this.scriptQueue.length === 0) {
43
+ return;
44
+ }
45
+ this.isProcessing = true;
46
+ while (this.scriptQueue.length > 0) {
47
+ const task = this.scriptQueue.shift();
48
+ if (task) {
49
+ try {
50
+ await task();
51
+ }
52
+ catch (error) {
53
+ this.logger.error('Script execution failed:', error);
54
+ }
55
+ }
56
+ }
57
+ this.isProcessing = false;
58
+ }
59
+ async executeScript(script) {
60
+ // For macOS, we'll use AppleScript to execute JavaScript in Photoshop
61
+ const tempScriptPath = join(tmpdir(), `photoshop-script-${Date.now()}.jsx`);
62
+ const tempAppleScriptPath = join(tmpdir(), `photoshop-applescript-${Date.now()}.scpt`);
63
+ try {
64
+ await writeFile(tempScriptPath, script, 'utf8');
65
+ // Create AppleScript that tells Photoshop to execute the JSX
66
+ const appleScript = this.createAppleScriptWrapper(tempScriptPath);
67
+ await writeFile(tempAppleScriptPath, appleScript, 'utf8');
68
+ try {
69
+ // Execute AppleScript via osascript
70
+ const { stdout, stderr } = await execAsync(`osascript "${tempAppleScriptPath}"`);
71
+ if (stderr) {
72
+ this.logger.warn('Script execution warning:', stderr);
73
+ }
74
+ // Parse result
75
+ return this.parseResult(stdout);
76
+ }
77
+ catch (error) {
78
+ this.logger.error('AppleScript execution failed:', error);
79
+ throw error;
80
+ }
81
+ finally {
82
+ // Cleanup AppleScript file
83
+ await unlink(tempAppleScriptPath).catch(() => { });
84
+ }
85
+ }
86
+ finally {
87
+ // Cleanup JSX file
88
+ await unlink(tempScriptPath).catch(() => { });
89
+ }
90
+ }
91
+ createAppleScriptWrapper(jsxPath) {
92
+ // Use POSIX file path for AppleScript
93
+ const posixPath = jsxPath.replace(/\\/g, '/');
94
+ return `tell application "${this.appName}"
95
+ \tactivate
96
+ \tset jsxFile to POSIX file "${posixPath}"
97
+ \tdo javascript "$.evalFile(decodeURI('${encodeURI(posixPath)}'))"
98
+ end tell`;
99
+ }
100
+ parseResult(output) {
101
+ const trimmed = output.trim();
102
+ // Try to parse as JSON
103
+ try {
104
+ return JSON.parse(trimmed);
105
+ }
106
+ catch {
107
+ // Return as string if not JSON
108
+ return trimmed;
109
+ }
110
+ }
111
+ async isPhotoshopRunning() {
112
+ try {
113
+ const { stdout } = await execAsync('pgrep -f "Adobe Photoshop"');
114
+ return stdout.trim().length > 0;
115
+ }
116
+ catch (error) {
117
+ // pgrep returns non-zero exit code if no process found
118
+ return false;
119
+ }
120
+ }
121
+ async launchPhotoshop(photoshopPath) {
122
+ return new Promise((resolve, reject) => {
123
+ this.logger.info(`Launching Photoshop: ${photoshopPath}`);
124
+ // Use 'open' command on macOS to launch the app
125
+ const child = spawn('open', ['-a', photoshopPath], {
126
+ detached: true,
127
+ stdio: 'ignore',
128
+ });
129
+ child.unref();
130
+ // Wait a bit for Photoshop to start
131
+ setTimeout(() => {
132
+ resolve();
133
+ }, 5000);
134
+ child.on('error', (error) => {
135
+ reject(new Error(`Failed to launch Photoshop: ${error.message}`));
136
+ });
137
+ });
138
+ }
139
+ /**
140
+ * Alternative method using 'do shell script' via AppleScript
141
+ * This can be more reliable for some versions
142
+ */
143
+ async executeViaDoShellScript(script) {
144
+ const tempScriptPath = join(tmpdir(), `photoshop-script-${Date.now()}.jsx`);
145
+ const tempAppleScriptPath = join(tmpdir(), `photoshop-applescript-alt-${Date.now()}.scpt`);
146
+ try {
147
+ await writeFile(tempScriptPath, script, 'utf8');
148
+ const appleScript = `tell application "${this.appName}"
149
+ \tdo shell script "cat '${tempScriptPath}'"
150
+ end tell`;
151
+ await writeFile(tempAppleScriptPath, appleScript, 'utf8');
152
+ const { stdout } = await execAsync(`osascript "${tempAppleScriptPath}"`);
153
+ await unlink(tempAppleScriptPath).catch(() => { });
154
+ return this.parseResult(stdout);
155
+ }
156
+ finally {
157
+ await unlink(tempScriptPath).catch(() => { });
158
+ }
159
+ }
160
+ }
161
+ //# sourceMappingURL=macos-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-executor.js","sourceRoot":"","sources":["../../src/platform/macos-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface ScriptExecutor {
2
+ /**
3
+ * Execute a script in Photoshop
4
+ * @param script - The script code to execute
5
+ * @param timeout - Timeout in milliseconds (default: 30000)
6
+ * @returns The result from the script execution
7
+ */
8
+ execute(script: string, timeout?: number): Promise<unknown>;
9
+ /**
10
+ * Check if Photoshop is running
11
+ */
12
+ isPhotoshopRunning(): Promise<boolean>;
13
+ /**
14
+ * Launch Photoshop if not running
15
+ */
16
+ launchPhotoshop(photoshopPath: string): Promise<void>;
17
+ }
18
+ export interface ScriptResult {
19
+ success: boolean;
20
+ result?: unknown;
21
+ error?: string;
22
+ }
23
+ //# sourceMappingURL=script-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-executor.d.ts","sourceRoot":"","sources":["../../src/platform/script-executor.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5D;;OAEG;IACH,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvC;;OAEG;IACH,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=script-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-executor.js","sourceRoot":"","sources":["../../src/platform/script-executor.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { PhotoshopInfo } from './connection.js';
2
+ export declare class WindowsDetector {
3
+ private logger;
4
+ constructor();
5
+ detect(): Promise<PhotoshopInfo>;
6
+ private detectFromRegistry;
7
+ private parseRegistryOutput;
8
+ private extractPathFromCLSID;
9
+ private getCommonPaths;
10
+ private checkPath;
11
+ private extractVersionFromPath;
12
+ private checkIfRunning;
13
+ }
14
+ //# sourceMappingURL=windows-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-detector.d.ts","sourceRoot":"","sources":["../../src/platform/windows-detector.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAShD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAS;;IAMjB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;YA6BxB,kBAAkB;IAkDhC,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,cAAc;YAyBR,SAAS;IA0BvB,OAAO,CAAC,sBAAsB;YAgBhB,cAAc;CAQ7B"}