editmamei 1.4.0 → 1.5.1
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.
- package/README.md +7 -6
- package/dist/bin/editmamei-core-darwin-arm64 +0 -0
- package/dist/bin/editmamei-core-darwin-x64 +0 -0
- package/dist/bin/editmamei-core-win-x64.exe +0 -0
- package/dist/cli/help.js +1 -1
- package/dist/core/server.js +157 -19
- package/dist/core/tool-groups.js +1 -0
- package/dist/core/tool-tiers.js +1 -0
- package/dist/install-channel.js +52 -2
- package/dist/kernel/module-lifecycle.js +113 -26
- package/dist/license/advisory.js +109 -0
- package/dist/license/entitlement.js +34 -6
- package/dist/license/polar-client.js +50 -7
- package/dist/license/store.js +59 -0
- package/dist/skills/editmamei-skill.zip +0 -0
- package/dist/telemetry/activity.js +149 -0
- package/dist/telemetry/client.js +170 -22
- package/dist/telemetry/events.js +48 -1
- package/dist/telemetry/outbox.js +43 -18
- package/dist/tools/document-tools.js +23 -1
- package/dist/update/check.js +24 -10
- package/dist/utils/session-log.js +3 -3
- package/dist/utils/xmp-crs.js +682 -0
- package/dist/version.js +1 -1
- package/package.json +3 -3
|
@@ -83,6 +83,11 @@ const openDocumentSchema = {
|
|
|
83
83
|
description: 'Suppress all PS dialogs during open (raw/HEIC use last-used ACR settings). Default true for pipeline use.',
|
|
84
84
|
default: true,
|
|
85
85
|
},
|
|
86
|
+
bit_depth: {
|
|
87
|
+
type: 'number',
|
|
88
|
+
enum: [8, 16],
|
|
89
|
+
description: 'Open-time bits per channel, RAW sources only. Set this here rather than converting later: ps_convert_image_mode FLATTENS the document, so depth cannot be changed once an edit stack exists. Prefer 16 for anything with heavy gradients (skies, skin, long tonal moves). Ignored for non-raw files, and the returned bits_per_channel always reports what was actually opened.',
|
|
90
|
+
},
|
|
86
91
|
},
|
|
87
92
|
required: ['file_path'],
|
|
88
93
|
};
|
|
@@ -294,6 +299,10 @@ export function createDocumentTools(connection, snippetClient) {
|
|
|
294
299
|
},
|
|
295
300
|
already_open: { type: 'boolean' },
|
|
296
301
|
file_path: { type: 'string' },
|
|
302
|
+
bit_depth_warning: {
|
|
303
|
+
type: 'string',
|
|
304
|
+
description: 'Present only when a requested bit_depth was not what the document actually opened at — because the file is not a raw source, or Photoshop declined the requested depth. Absent means bits_per_channel is what you asked for.',
|
|
305
|
+
},
|
|
297
306
|
context: { type: 'object' },
|
|
298
307
|
},
|
|
299
308
|
required: ['success'],
|
|
@@ -524,8 +533,21 @@ async function openDocumentPipeline(connection, snippetClient, rawArgs) {
|
|
|
524
533
|
const args = validateArgs(openDocumentSchema, rawArgs);
|
|
525
534
|
filePath = args.file_path;
|
|
526
535
|
const suppressDialogs = args.suppress_dialogs;
|
|
527
|
-
const
|
|
536
|
+
const bitDepth = args.bit_depth;
|
|
537
|
+
const script = await snippetClient.build('openDocumentPipeline', {
|
|
538
|
+
filePath,
|
|
539
|
+
suppressDialogs,
|
|
540
|
+
rawBits: bitDepth ?? 0,
|
|
541
|
+
});
|
|
528
542
|
const result = await runScript(connection, script, OPEN_DOCUMENT_TIMEOUT_MS);
|
|
543
|
+
const payload = result;
|
|
544
|
+
if (bitDepth !== undefined && typeof payload.bits_per_channel === 'number') {
|
|
545
|
+
if (payload.bits_per_channel !== bitDepth) {
|
|
546
|
+
payload.bit_depth_warning = payload.is_raw_source
|
|
547
|
+
? `Requested ${bitDepth}-bit but Photoshop opened ${payload.bits_per_channel}-bit.`
|
|
548
|
+
: `bit_depth applies to RAW sources only; this file opened at ${payload.bits_per_channel}-bit.`;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
529
551
|
return {
|
|
530
552
|
content: [
|
|
531
553
|
{
|
package/dist/update/check.js
CHANGED
|
@@ -101,7 +101,15 @@ export function updateMessage(channel, latest) {
|
|
|
101
101
|
return `Download editmamei.mcpb (v${latest}) from ${RELEASES_URL} and reinstall the Claude Desktop extension.`;
|
|
102
102
|
case 'dev':
|
|
103
103
|
return `You're on a local dev build — pull the latest source and rebuild.`;
|
|
104
|
-
case '
|
|
104
|
+
case 'npx':
|
|
105
|
+
return `The next \`npx -y editmamei\` picks up v${latest} automatically — just restart your AI client.`;
|
|
106
|
+
case 'source':
|
|
107
|
+
return `You're running Editmamei from a source checkout — pull the latest changes and rebuild.`;
|
|
108
|
+
case 'npm_local':
|
|
109
|
+
return `Editmamei is installed locally in a project — update the \`editmamei\` dependency in that project (e.g. \`npm install editmamei@latest\`) and restart your MCP client.`;
|
|
110
|
+
case 'unknown':
|
|
111
|
+
return `Editmamei v${latest} is available. Update it the way you installed it, then restart your MCP client.`;
|
|
112
|
+
case 'npm_global':
|
|
105
113
|
default:
|
|
106
114
|
return `Run: npm install -g editmamei@latest (then restart your MCP client).`;
|
|
107
115
|
}
|
|
@@ -110,7 +118,7 @@ export function shouldCheckForUpdate(updateCheckEnabled, env = process.env) {
|
|
|
110
118
|
const inTest = env.VITEST !== undefined || env.NODE_ENV === 'test';
|
|
111
119
|
return updateCheckEnabled === true && !inTest;
|
|
112
120
|
}
|
|
113
|
-
export async function
|
|
121
|
+
export async function checkForUpdateWithStatus(opts = {}) {
|
|
114
122
|
try {
|
|
115
123
|
const env = opts.env ?? process.env;
|
|
116
124
|
const current = opts.current ?? VERSION;
|
|
@@ -118,19 +126,25 @@ export async function checkForUpdate(opts = {}) {
|
|
|
118
126
|
const fetchLatest = opts.fetchLatest ?? httpFetchLatest();
|
|
119
127
|
const manifest = await fetchLatest(resolveUpdateCheckUrl(env), opts.timeoutMs ?? 4000);
|
|
120
128
|
if (!manifest || !parseSemver(manifest.version))
|
|
121
|
-
return null;
|
|
129
|
+
return { status: 'failed', info: null };
|
|
122
130
|
const latest = manifest.version;
|
|
123
131
|
if (!isNewer(latest, current))
|
|
124
|
-
return null;
|
|
132
|
+
return { status: 'current', info: null };
|
|
125
133
|
return {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
status: 'newer',
|
|
135
|
+
info: {
|
|
136
|
+
current,
|
|
137
|
+
latest,
|
|
138
|
+
channel,
|
|
139
|
+
how_to_update: updateMessage(channel, latest),
|
|
140
|
+
fixed_tools: fixedToolsSince(manifest.fixesByVersion, current, latest),
|
|
141
|
+
},
|
|
131
142
|
};
|
|
132
143
|
}
|
|
133
144
|
catch {
|
|
134
|
-
return null;
|
|
145
|
+
return { status: 'failed', info: null };
|
|
135
146
|
}
|
|
136
147
|
}
|
|
148
|
+
export async function checkForUpdate(opts = {}) {
|
|
149
|
+
return (await checkForUpdateWithStatus(opts)).info;
|
|
150
|
+
}
|
|
@@ -267,7 +267,7 @@ export class SessionLog {
|
|
|
267
267
|
this.metaEmitted = true;
|
|
268
268
|
await this.writeLine(JSON.stringify(this.buildMetaEntry()));
|
|
269
269
|
}
|
|
270
|
-
async append(entry, result) {
|
|
270
|
+
async append(entry, result, resultBytes) {
|
|
271
271
|
if (!this.metaEmitted) {
|
|
272
272
|
await this.emitMeta();
|
|
273
273
|
}
|
|
@@ -277,7 +277,7 @@ export class SessionLog {
|
|
|
277
277
|
const callKey = JSON.stringify({ tool: entry.tool, args: sanitizedArgs });
|
|
278
278
|
const retrySignal = callKey === this.lastCallKey;
|
|
279
279
|
this.lastCallKey = callKey;
|
|
280
|
-
const
|
|
280
|
+
const finalResultBytes = resultBytes !== undefined ? resultBytes : computeResultBytes(result);
|
|
281
281
|
let hoisted = {};
|
|
282
282
|
try {
|
|
283
283
|
hoisted = hoistContextScalars(result);
|
|
@@ -302,7 +302,7 @@ export class SessionLog {
|
|
|
302
302
|
edition: EDITION,
|
|
303
303
|
platform: process.platform,
|
|
304
304
|
ps_version: this.psVersion,
|
|
305
|
-
result_bytes:
|
|
305
|
+
result_bytes: finalResultBytes,
|
|
306
306
|
...hoisted,
|
|
307
307
|
...(errorClass !== null ? { error_class: errorClass } : {}),
|
|
308
308
|
retry_signal: retrySignal,
|