emdash-emit 0.1.7 → 0.1.9
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 +237 -82
- package/dist/cli/commands/new.d.ts.map +1 -1
- package/dist/cli/commands/new.js +3 -1
- package/dist/cli/commands/new.js.map +1 -1
- package/dist/cli/commands/profile.d.ts.map +1 -1
- package/dist/cli/commands/profile.js +67 -13
- package/dist/cli/commands/profile.js.map +1 -1
- package/dist/cli/commands/pull.d.ts +5 -0
- package/dist/cli/commands/pull.d.ts.map +1 -1
- package/dist/cli/commands/pull.js +96 -39
- package/dist/cli/commands/pull.js.map +1 -1
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +17 -2
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/commands/status.d.ts +19 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +93 -4
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/context.d.ts +35 -0
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/context.js +112 -10
- package/dist/cli/context.js.map +1 -1
- package/dist/client/auth.d.ts +1 -0
- package/dist/client/auth.d.ts.map +1 -1
- package/dist/client/auth.js +1 -0
- package/dist/client/auth.js.map +1 -1
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +27 -10
- package/dist/client/http.js.map +1 -1
- package/dist/client/mapper.d.ts +12 -0
- package/dist/client/mapper.d.ts.map +1 -1
- package/dist/client/mapper.js +65 -0
- package/dist/client/mapper.js.map +1 -1
- package/dist/client/media.d.ts +141 -0
- package/dist/client/media.d.ts.map +1 -0
- package/dist/client/media.js +582 -0
- package/dist/client/media.js.map +1 -0
- package/dist/client/portable-text.d.ts +22 -1
- package/dist/client/portable-text.d.ts.map +1 -1
- package/dist/client/portable-text.js +85 -5
- package/dist/client/portable-text.js.map +1 -1
- package/dist/db/cache.d.ts +16 -0
- package/dist/db/cache.d.ts.map +1 -1
- package/dist/db/cache.js +67 -0
- package/dist/db/cache.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/context.d.ts +1 -0
- package/dist/mcp/context.d.ts.map +1 -1
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +60 -15
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-errors.d.ts +11 -0
- package/dist/mcp/tool-errors.d.ts.map +1 -0
- package/dist/mcp/tool-errors.js +62 -0
- package/dist/mcp/tool-errors.js.map +1 -0
- package/dist/mcp/tools/profile.d.ts +9 -2
- package/dist/mcp/tools/profile.d.ts.map +1 -1
- package/dist/mcp/tools/profile.js +49 -36
- package/dist/mcp/tools/profile.js.map +1 -1
- package/dist/mcp/tools/sync-diff.d.ts.map +1 -1
- package/dist/mcp/tools/sync-diff.js +18 -70
- package/dist/mcp/tools/sync-diff.js.map +1 -1
- package/dist/mcp/tools/sync-new.d.ts.map +1 -1
- package/dist/mcp/tools/sync-new.js +40 -21
- package/dist/mcp/tools/sync-new.js.map +1 -1
- package/dist/mcp/tools/sync-pull.d.ts.map +1 -1
- package/dist/mcp/tools/sync-pull.js +110 -86
- package/dist/mcp/tools/sync-pull.js.map +1 -1
- package/dist/mcp/tools/sync-push.d.ts.map +1 -1
- package/dist/mcp/tools/sync-push.js +24 -32
- package/dist/mcp/tools/sync-push.js.map +1 -1
- package/dist/mcp/tools/sync-status.d.ts.map +1 -1
- package/dist/mcp/tools/sync-status.js +55 -4
- package/dist/mcp/tools/sync-status.js.map +1 -1
- package/dist/sync/diff.d.ts +36 -0
- package/dist/sync/diff.d.ts.map +1 -1
- package/dist/sync/diff.js +118 -0
- package/dist/sync/diff.js.map +1 -1
- package/dist/sync/media.d.ts +16 -0
- package/dist/sync/media.d.ts.map +1 -1
- package/dist/sync/media.js +180 -26
- package/dist/sync/media.js.map +1 -1
- package/dist/sync/merge.d.ts.map +1 -1
- package/dist/sync/merge.js +1 -0
- package/dist/sync/merge.js.map +1 -1
- package/dist/sync/orchestrator.d.ts +6 -0
- package/dist/sync/orchestrator.d.ts.map +1 -1
- package/dist/sync/orchestrator.js +52 -27
- package/dist/sync/orchestrator.js.map +1 -1
- package/dist/sync/preflight.d.ts +30 -2
- package/dist/sync/preflight.d.ts.map +1 -1
- package/dist/sync/preflight.js +274 -10
- package/dist/sync/preflight.js.map +1 -1
- package/dist/sync/pull.d.ts +47 -0
- package/dist/sync/pull.d.ts.map +1 -1
- package/dist/sync/pull.js +148 -8
- package/dist/sync/pull.js.map +1 -1
- package/dist/sync/push.d.ts +2 -0
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +332 -6
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/status.d.ts +11 -1
- package/dist/sync/status.d.ts.map +1 -1
- package/dist/sync/status.js +40 -6
- package/dist/sync/status.js.map +1 -1
- package/dist/sync/taxonomies.d.ts.map +1 -1
- package/dist/sync/taxonomies.js +39 -4
- package/dist/sync/taxonomies.js.map +1 -1
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +14 -4
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +16 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +66 -7
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/profile.d.ts +3 -3
- package/dist/utils/profile.d.ts.map +1 -1
- package/dist/utils/profile.js +105 -8
- package/dist/utils/profile.js.map +1 -1
- package/package.json +4 -1
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import fs from 'node:fs';
|
|
23
23
|
import path from 'node:path';
|
|
24
|
-
import { listRemoteArticles, pullArticle, calculateHash, } from './pull.js';
|
|
24
|
+
import { listRemoteArticles, pullArticle, calculateHash, findLocalFilesByUlid, } from './pull.js';
|
|
25
25
|
import { pushArticle } from './push.js';
|
|
26
26
|
import { getWorkspaceStatus } from './status.js';
|
|
27
27
|
import { syncRemoteBylines } from './bylines.js';
|
|
@@ -78,43 +78,54 @@ export async function pullBatch(options) {
|
|
|
78
78
|
candidatesToPrune.push(syncState);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
// Safety guard: Check if any pushed-out candidate has unpushed local changes
|
|
81
|
+
// Safety guard: Check if any pushed-out candidate (or duplicate file sharing its ULID) has unpushed local changes
|
|
82
82
|
const unpushedConflicts = [];
|
|
83
83
|
for (const candidate of candidatesToPrune) {
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
84
|
+
const candidatePaths = new Set([
|
|
85
|
+
candidate.localFilePath,
|
|
86
|
+
...findLocalFilesByUlid(options.workspaceRoot, options.collection, candidate.id),
|
|
87
|
+
]);
|
|
88
|
+
for (const relPath of candidatePaths) {
|
|
89
|
+
const fullPath = path.join(options.workspaceRoot, relPath);
|
|
90
|
+
if (fs.existsSync(fullPath)) {
|
|
91
|
+
try {
|
|
92
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
93
|
+
const currentHash = calculateHash(content);
|
|
94
|
+
if (currentHash !== candidate.localHash) {
|
|
95
|
+
unpushedConflicts.push({
|
|
96
|
+
id: candidate.id,
|
|
97
|
+
slug: candidate.slug,
|
|
98
|
+
filePath: relPath,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// If read fails, safely ignore
|
|
95
104
|
}
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// If read fails, safely ignore
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
}
|
|
102
108
|
if (unpushedConflicts.length > 0) {
|
|
109
|
+
const affectedArticles = new Set(unpushedConflicts.map((i) => i.id)).size;
|
|
103
110
|
const filesList = unpushedConflicts.map((i) => ` - ${i.filePath} (${i.slug})`).join('\n');
|
|
104
111
|
const windowMsg = options.limit ? ` (currently: ${options.limit})` : '';
|
|
105
|
-
const message = `Pull aborted: ${unpushedConflicts.length} article(s) outside the sync window have unpushed local edits!\n\n` +
|
|
106
|
-
`The following
|
|
112
|
+
const message = `Pull aborted: ${unpushedConflicts.length} file(s) belonging to ${affectedArticles} article(s) outside the sync window have unpushed local edits!\n\n` +
|
|
113
|
+
`The following file(s) would be pruned from local cache, but contain unpushed changes` +
|
|
114
|
+
` (both the canonical file and any duplicate copy sharing its ULID are inspected):\n${filesList}\n\n` +
|
|
107
115
|
`💡 Why did this happen?\n` +
|
|
108
116
|
`The modified article(s) are older than the workspace sync window${windowMsg}.\n\n` +
|
|
109
117
|
`Recommended actions:\n` +
|
|
110
118
|
` 1. Push local changes: emit push <filePath>\n` +
|
|
111
|
-
` 2. Adjust sync window: update "postsSyncLimit" in .emit/config.json if a larger window is needed\n
|
|
119
|
+
` 2. Adjust sync window: update "postsSyncLimit" in .emit/config.json if a larger window is needed\n` +
|
|
120
|
+
` 3. Keep them for now: emit pull --no-prune (skips window pruning; local files stay untouched)\n`;
|
|
112
121
|
throw new SyncPruneConflictError(message, unpushedConflicts, options.limit);
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
const results = [];
|
|
116
125
|
let updated = 0;
|
|
117
126
|
let skipped = 0;
|
|
127
|
+
let preserved = 0;
|
|
128
|
+
let quarantined = 0;
|
|
118
129
|
const concurrency = options.concurrency || 8;
|
|
119
130
|
let index = 0;
|
|
120
131
|
const worker = async () => {
|
|
@@ -138,6 +149,10 @@ export async function pullBatch(options) {
|
|
|
138
149
|
skipped++;
|
|
139
150
|
else
|
|
140
151
|
updated++;
|
|
152
|
+
if (res.localEditsPreserved)
|
|
153
|
+
preserved++;
|
|
154
|
+
if (res.quarantined)
|
|
155
|
+
quarantined += res.quarantined.length;
|
|
141
156
|
if (options.onProgress) {
|
|
142
157
|
options.onProgress({
|
|
143
158
|
current: results.length,
|
|
@@ -153,13 +168,19 @@ export async function pullBatch(options) {
|
|
|
153
168
|
let deleted = 0;
|
|
154
169
|
if (shouldPrune) {
|
|
155
170
|
for (const candidate of candidatesToPrune) {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
171
|
+
const pathsToRemove = new Set([
|
|
172
|
+
candidate.localFilePath,
|
|
173
|
+
...findLocalFilesByUlid(options.workspaceRoot, options.collection, candidate.id),
|
|
174
|
+
]);
|
|
175
|
+
for (const relToRemove of pathsToRemove) {
|
|
176
|
+
const fullPath = path.join(options.workspaceRoot, relToRemove);
|
|
177
|
+
if (fs.existsSync(fullPath)) {
|
|
178
|
+
try {
|
|
179
|
+
fs.unlinkSync(fullPath);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// ignore
|
|
183
|
+
}
|
|
163
184
|
}
|
|
164
185
|
}
|
|
165
186
|
options.cache.deleteEntry(candidate.id);
|
|
@@ -187,16 +208,19 @@ export async function pullBatch(options) {
|
|
|
187
208
|
updated,
|
|
188
209
|
skipped,
|
|
189
210
|
deleted,
|
|
211
|
+
preserved,
|
|
212
|
+
quarantined,
|
|
190
213
|
items: results,
|
|
191
214
|
};
|
|
192
215
|
}
|
|
193
216
|
/**
|
|
194
217
|
* Orchestrates pushing all modified/untracked files in the workspace.
|
|
218
|
+
* Excludes synced and invalid (YAML parse error) files so invalid files do not crash batch push.
|
|
195
219
|
* Reusable across CLI and MCP servers.
|
|
196
220
|
*/
|
|
197
221
|
export async function pushAll(options) {
|
|
198
222
|
const status = getWorkspaceStatus(options.workspaceRoot, options.cache, options.collection);
|
|
199
|
-
const toPush = status.items.filter((i) => i.syncStatus
|
|
223
|
+
const toPush = status.items.filter((i) => i.syncStatus === 'modified' || i.syncStatus === 'untracked');
|
|
200
224
|
const results = [];
|
|
201
225
|
let pushed = 0;
|
|
202
226
|
for (const item of toPush) {
|
|
@@ -216,6 +240,7 @@ export async function pushAll(options) {
|
|
|
216
240
|
total: toPush.length,
|
|
217
241
|
pushed,
|
|
218
242
|
skipped: status.items.length - toPush.length,
|
|
243
|
+
invalid: status.summary.invalid,
|
|
219
244
|
results,
|
|
220
245
|
};
|
|
221
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/sync/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,aAAa,
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/sync/orchestrator.ts"],"names":[],"mappings":"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"}
|
package/dist/sync/preflight.d.ts
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Frontmatter, type ParsedMarkdown } from '../utils/frontmatter.js';
|
|
2
|
+
import type { CacheDatabase } from '../db/cache.js';
|
|
2
3
|
export interface PreflightOptions {
|
|
3
4
|
allowPublish?: boolean;
|
|
4
5
|
knownTaxonomies?: Record<string, string[]>;
|
|
5
6
|
baseMarkdown?: string;
|
|
6
7
|
previousStatus?: 'draft' | 'published';
|
|
8
|
+
workspaceRoot?: string;
|
|
9
|
+
cache?: CacheDatabase;
|
|
10
|
+
}
|
|
11
|
+
export interface PromotedMediaMatch {
|
|
12
|
+
mediaId: string;
|
|
13
|
+
storageKey: string;
|
|
14
|
+
url: string;
|
|
15
|
+
promotedRelPath: string;
|
|
16
|
+
}
|
|
17
|
+
export interface DraftImageReference {
|
|
18
|
+
/** Exact standalone Markdown line matched in body */
|
|
19
|
+
line: string;
|
|
20
|
+
/** Alt text inside `` */
|
|
21
|
+
alt: string;
|
|
22
|
+
/** Raw path string written in Markdown `` */
|
|
23
|
+
rawPath: string;
|
|
24
|
+
/** Basename of the draft image file under `media/drafts/` */
|
|
25
|
+
filename: string;
|
|
26
|
+
/** Resolved absolute path on disk (when `workspaceRoot` is known) */
|
|
27
|
+
resolvedAbsPath: string;
|
|
28
|
+
/**
|
|
29
|
+
* Present when `media/drafts/<filename>` was already promoted to `media/<yyyyMMdd>_<id>-<name>`
|
|
30
|
+
* by an earlier article push (P1 shared draft image reuse across articles).
|
|
31
|
+
*/
|
|
32
|
+
alreadyPromoted?: PromotedMediaMatch;
|
|
7
33
|
}
|
|
8
34
|
export interface PreflightResult {
|
|
9
35
|
valid: boolean;
|
|
@@ -11,6 +37,8 @@ export interface PreflightResult {
|
|
|
11
37
|
frontmatter: Frontmatter;
|
|
12
38
|
errors: PreflightError[];
|
|
13
39
|
warnings: string[];
|
|
40
|
+
/** G11: Validated standalone local draft images queued for automatic upload on push */
|
|
41
|
+
draftImages: DraftImageReference[];
|
|
14
42
|
}
|
|
15
43
|
export interface PreflightError {
|
|
16
44
|
code: string;
|
|
@@ -18,7 +46,7 @@ export interface PreflightError {
|
|
|
18
46
|
suggestion?: string;
|
|
19
47
|
}
|
|
20
48
|
/**
|
|
21
|
-
* Runs Preflight Guards G2 through
|
|
49
|
+
* Runs Preflight Guards G2 through G11 against the article to prevent AI misbehavior.
|
|
22
50
|
* (G1 is enforced at the MCP / CLI invocation layer).
|
|
23
51
|
*/
|
|
24
52
|
export declare function runPreflightChecks(filePath: string, parsed: ParsedMarkdown, options?: PreflightOptions): PreflightResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/sync/preflight.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/sync/preflight.ts"],"names":[],"mappings":"AAqCA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uFAAuF;IACvF,WAAW,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAgKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,eAAe,CA0RjB"}
|
package/dist/sync/preflight.js
CHANGED
|
@@ -19,18 +19,149 @@
|
|
|
19
19
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
20
|
* SOFTWARE.
|
|
21
21
|
*/
|
|
22
|
+
import fs from 'node:fs';
|
|
22
23
|
import path from 'node:path';
|
|
24
|
+
import yaml from 'js-yaml';
|
|
23
25
|
import { extractUlidFromFilename } from '../utils/naming.js';
|
|
26
|
+
import { extractMediaUlid } from '../client/mapper.js';
|
|
27
|
+
import { MAX_MEDIA_UPLOAD_BYTES, resolveImageMimeType, toRootRelativeMediaUrl, } from '../client/media.js';
|
|
24
28
|
import { stripCodeBlocks, verifyOpaqueBlocksUntampered, detectUnsupportedMarkdownSyntax, } from '../client/portable-text.js';
|
|
29
|
+
import { sanitizeTitleForFilename, } from '../utils/frontmatter.js';
|
|
25
30
|
const CONFLICT_MARKER_REGEX = /^<{7}\s|^={7}$|^>{7}\s/m;
|
|
26
|
-
const
|
|
31
|
+
const OPAQUE_FENCE_LINE_REGEX = /^<!--ec:block .+ -->$/;
|
|
32
|
+
const STANDALONE_IMAGE_LINE_REGEX = /^!\[([^\]]*)\]\(([^)]+)\)$/;
|
|
33
|
+
const REMOTE_OR_DATA_URL_REGEX = /^(?:https?:\/\/|data:|\/_emdash\/api\/media\/file\/)/i;
|
|
34
|
+
const ANY_LOCAL_IMAGE_REGEX = /!\[([^\]]*)\]\((?!https?:\/\/|data:|\/_emdash\/api\/media\/file\/)([^)]+)\)/g;
|
|
35
|
+
// Canonical ULID shape (Crockford base32: 26 chars, excludes I and O). Casing is
|
|
36
|
+
// case-insensitive here because parseMarkdown() normalizes local frontmatter to uppercase.
|
|
37
|
+
const CANONICAL_ULID_REGEX = /^[0-9A-HJ-NP-Z]{26}$/i;
|
|
38
|
+
function resolveDraftImagePath(articleFilePath, rawImagePath, workspaceRoot) {
|
|
39
|
+
const root = workspaceRoot ? path.resolve(workspaceRoot) : '/__emit_virtual_workspace__';
|
|
40
|
+
const articleAbs = path.isAbsolute(articleFilePath)
|
|
41
|
+
? articleFilePath
|
|
42
|
+
: path.resolve(root, articleFilePath);
|
|
43
|
+
const articleDir = path.dirname(articleAbs);
|
|
44
|
+
const trimmed = rawImagePath.trim();
|
|
45
|
+
if (path.isAbsolute(trimmed)) {
|
|
46
|
+
return {
|
|
47
|
+
isInsideDraftsDir: false,
|
|
48
|
+
isInsideMediaDir: false,
|
|
49
|
+
candidateAbs: trimmed,
|
|
50
|
+
filename: path.basename(trimmed),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const normalized = trimmed.replace(/\\/g, '/');
|
|
54
|
+
const candidateAbs = normalized.startsWith('media/') || normalized.startsWith('./media/')
|
|
55
|
+
? path.resolve(root, normalized)
|
|
56
|
+
: path.resolve(articleDir, normalized);
|
|
57
|
+
const draftsDirAbs = path.resolve(root, 'media', 'drafts');
|
|
58
|
+
const mediaDirAbs = path.resolve(root, 'media');
|
|
59
|
+
const isInsideDraftsDir = path.dirname(candidateAbs) === draftsDirAbs && path.basename(candidateAbs).length > 0;
|
|
60
|
+
const isInsideMediaDir = candidateAbs.startsWith(mediaDirAbs + path.sep) && path.basename(candidateAbs).length > 0;
|
|
61
|
+
return {
|
|
62
|
+
isInsideDraftsDir,
|
|
63
|
+
isInsideMediaDir,
|
|
64
|
+
candidateAbs,
|
|
65
|
+
filename: path.basename(candidateAbs),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Searches `media_state` and `media/*.yaml` to see whether a draft image filename
|
|
70
|
+
* (or a direct `media/<yyyyMMdd>_<id>-<name>.<ext>` reference) has already been promoted
|
|
71
|
+
* into `media/` by a previous push (P1 shared draft image reuse across multiple articles).
|
|
72
|
+
*/
|
|
73
|
+
function findAlreadyPromotedMedia(filename, workspaceRoot, cache) {
|
|
74
|
+
const ext = path.extname(filename);
|
|
75
|
+
const baseWithoutExt = path.basename(filename, ext);
|
|
76
|
+
const sanitizedTarget = `${sanitizeTitleForFilename(baseWithoutExt)}${ext}`.toLowerCase();
|
|
77
|
+
const directUlidMatch = filename.replace(/^\d{8}_/, '').match(/^([0-9A-HJ-NP-Z]{26})-/i);
|
|
78
|
+
const directUlid = directUlidMatch ? directUlidMatch[1].toUpperCase() : null;
|
|
79
|
+
// 1. Check media_state records first
|
|
80
|
+
if (cache) {
|
|
81
|
+
const states = cache.listMediaStates();
|
|
82
|
+
for (const st of states) {
|
|
83
|
+
if (st.status !== 'ready' && st.status !== 'uploaded')
|
|
84
|
+
continue;
|
|
85
|
+
if (!st.mediaId || !st.storageKey || !st.url)
|
|
86
|
+
continue;
|
|
87
|
+
if (directUlid && st.mediaId.toUpperCase() === directUlid) {
|
|
88
|
+
return {
|
|
89
|
+
mediaId: st.mediaId,
|
|
90
|
+
storageKey: st.storageKey,
|
|
91
|
+
url: st.url,
|
|
92
|
+
promotedRelPath: st.workspacePath || `media/${filename}`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (st.workspacePath) {
|
|
96
|
+
const promotedBase = path.basename(st.workspacePath);
|
|
97
|
+
const suffix = promotedBase.replace(/^(?:\d{8}_)?[0-9A-HJ-NP-Z]{26}-/i, '').toLowerCase();
|
|
98
|
+
if (suffix === sanitizedTarget || suffix === filename.toLowerCase()) {
|
|
99
|
+
return {
|
|
100
|
+
mediaId: st.mediaId,
|
|
101
|
+
storageKey: st.storageKey,
|
|
102
|
+
url: st.url,
|
|
103
|
+
promotedRelPath: st.workspacePath,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// 2. Scan companion YAML files in media/
|
|
110
|
+
const mediaDir = path.join(workspaceRoot, 'media');
|
|
111
|
+
if (!fs.existsSync(mediaDir))
|
|
112
|
+
return null;
|
|
113
|
+
const files = fs.readdirSync(mediaDir);
|
|
114
|
+
for (const file of files) {
|
|
115
|
+
if (!file.endsWith('.yaml'))
|
|
116
|
+
continue;
|
|
117
|
+
if (directUlid && !file.toUpperCase().includes(directUlid))
|
|
118
|
+
continue;
|
|
119
|
+
try {
|
|
120
|
+
const meta = yaml.load(fs.readFileSync(path.join(mediaDir, file), 'utf8'));
|
|
121
|
+
if (!meta || typeof meta.id !== 'string')
|
|
122
|
+
continue;
|
|
123
|
+
const metaFilename = typeof meta.filename === 'string' ? meta.filename : '';
|
|
124
|
+
const fileSuffix = file
|
|
125
|
+
.replace(/\.yaml$/, '')
|
|
126
|
+
.replace(/^(?:\d{8}_)?[0-9A-HJ-NP-Z]{26}-/i, '')
|
|
127
|
+
.toLowerCase();
|
|
128
|
+
const matchesFilename = (directUlid !== null && meta.id.toUpperCase() === directUlid) ||
|
|
129
|
+
metaFilename === filename ||
|
|
130
|
+
metaFilename.toLowerCase() === filename.toLowerCase() ||
|
|
131
|
+
`${fileSuffix}${ext.toLowerCase()}` === sanitizedTarget;
|
|
132
|
+
if (!matchesFilename)
|
|
133
|
+
continue;
|
|
134
|
+
const storageKey = typeof meta.storageKey === 'string' ? meta.storageKey : '';
|
|
135
|
+
const rawUrl = typeof meta.url === 'string' ? meta.url : '';
|
|
136
|
+
const canonicalUrl = rawUrl
|
|
137
|
+
? toRootRelativeMediaUrl(rawUrl, storageKey, 'https://example.com')
|
|
138
|
+
: storageKey
|
|
139
|
+
? `/_emdash/api/media/file/${storageKey}`
|
|
140
|
+
: '';
|
|
141
|
+
if (!canonicalUrl)
|
|
142
|
+
continue;
|
|
143
|
+
const binaryName = `${file.replace(/\.yaml$/, '')}${ext || path.extname(metaFilename) || '.jpg'}`;
|
|
144
|
+
return {
|
|
145
|
+
mediaId: meta.id,
|
|
146
|
+
storageKey: storageKey || path.basename(canonicalUrl),
|
|
147
|
+
url: canonicalUrl,
|
|
148
|
+
promotedRelPath: path.posix.join('media', binaryName),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// Ignore unreadable YAML
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
27
157
|
/**
|
|
28
|
-
* Runs Preflight Guards G2 through
|
|
158
|
+
* Runs Preflight Guards G2 through G11 against the article to prevent AI misbehavior.
|
|
29
159
|
* (G1 is enforced at the MCP / CLI invocation layer).
|
|
30
160
|
*/
|
|
31
161
|
export function runPreflightChecks(filePath, parsed, options) {
|
|
32
162
|
const errors = [];
|
|
33
163
|
const warnings = [];
|
|
164
|
+
const draftImages = [];
|
|
34
165
|
let cleanedBody = parsed.body;
|
|
35
166
|
const { frontmatter } = parsed;
|
|
36
167
|
// G2: ID (ULID) immutability check
|
|
@@ -79,15 +210,147 @@ export function runPreflightChecks(filePath, parsed, options) {
|
|
|
79
210
|
}
|
|
80
211
|
}
|
|
81
212
|
}
|
|
82
|
-
// G5: Local image path
|
|
213
|
+
// G5 & G11: Local image path inspection & offline draft media auto-upload resolution
|
|
214
|
+
// Code blocks and opaque fences (<!--ec:block ... -->) are excluded from scanning.
|
|
83
215
|
const bodyWithoutCode = stripCodeBlocks(cleanedBody);
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
216
|
+
const bodyLines = bodyWithoutCode.split('\n');
|
|
217
|
+
for (const rawLine of bodyLines) {
|
|
218
|
+
const trimmedLine = rawLine.replace(/\r$/, '').trim();
|
|
219
|
+
if (!trimmedLine)
|
|
220
|
+
continue;
|
|
221
|
+
// Opaque fences are managed by G9 and must never be touched by image replacement
|
|
222
|
+
if (OPAQUE_FENCE_LINE_REGEX.test(trimmedLine)) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const standaloneMatch = trimmedLine.match(STANDALONE_IMAGE_LINE_REGEX);
|
|
226
|
+
if (standaloneMatch) {
|
|
227
|
+
const alt = standaloneMatch[1];
|
|
228
|
+
const rawPath = standaloneMatch[2].trim();
|
|
229
|
+
if (REMOTE_OR_DATA_URL_REGEX.test(rawPath)) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const resolved = resolveDraftImagePath(filePath, rawPath, options?.workspaceRoot);
|
|
233
|
+
if (!resolved.isInsideDraftsDir) {
|
|
234
|
+
// Also allow reusing an already-promoted file directly under media/<yyyyMMdd>_<id>-<name>
|
|
235
|
+
if (resolved.isInsideMediaDir && options?.workspaceRoot) {
|
|
236
|
+
const promotedMatch = findAlreadyPromotedMedia(resolved.filename, options.workspaceRoot, options.cache);
|
|
237
|
+
if (promotedMatch) {
|
|
238
|
+
draftImages.push({
|
|
239
|
+
line: trimmedLine,
|
|
240
|
+
alt,
|
|
241
|
+
rawPath: standaloneMatch[2],
|
|
242
|
+
filename: resolved.filename,
|
|
243
|
+
resolvedAbsPath: resolved.candidateAbs,
|
|
244
|
+
alreadyPromoted: promotedMatch,
|
|
245
|
+
});
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
errors.push({
|
|
250
|
+
code: 'LOCAL_IMAGE_DETECTED',
|
|
251
|
+
message: `Local image path detected in markdown body: '${trimmedLine}'. Only images placed directly under "media/drafts/" can be automatically uploaded.`,
|
|
252
|
+
suggestion: 'Place the image in "media/drafts/<filename>" and reference it on a standalone line (e.g. ), or upload first using EmDash MCP "media_upload" and replace with /_emdash/api/media/file/<storageKey>.',
|
|
253
|
+
});
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// G11: Standalone image referencing media/drafts/<filename>
|
|
257
|
+
if (options?.workspaceRoot) {
|
|
258
|
+
if (!fs.existsSync(resolved.candidateAbs)) {
|
|
259
|
+
// P1: Check whether an earlier article push already promoted this draft image into media/
|
|
260
|
+
const promotedMatch = findAlreadyPromotedMedia(resolved.filename, options.workspaceRoot, options.cache);
|
|
261
|
+
if (promotedMatch) {
|
|
262
|
+
draftImages.push({
|
|
263
|
+
line: trimmedLine,
|
|
264
|
+
alt,
|
|
265
|
+
rawPath: standaloneMatch[2],
|
|
266
|
+
filename: resolved.filename,
|
|
267
|
+
resolvedAbsPath: resolved.candidateAbs,
|
|
268
|
+
alreadyPromoted: promotedMatch,
|
|
269
|
+
});
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
errors.push({
|
|
273
|
+
code: 'MISSING_LOCAL_IMAGE_FILE',
|
|
274
|
+
message: `Draft image file not found on disk: '${rawPath}' (resolved to '${resolved.candidateAbs}', and no promoted asset matching '${resolved.filename}' was found in media/).`,
|
|
275
|
+
suggestion: `Place "${resolved.filename}" inside "media/drafts/", or if it was already promoted, check "media/<yyyyMMdd>_<id>-${resolved.filename}".`,
|
|
276
|
+
});
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const stat = fs.statSync(resolved.candidateAbs);
|
|
280
|
+
if (!stat.isFile()) {
|
|
281
|
+
errors.push({
|
|
282
|
+
code: 'MISSING_LOCAL_IMAGE_FILE',
|
|
283
|
+
message: `Draft image path is not a regular file: '${rawPath}'.`,
|
|
284
|
+
suggestion: `Ensure "${resolved.filename}" is a valid image file inside "media/drafts/".`,
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (!resolveImageMimeType(resolved.filename)) {
|
|
289
|
+
errors.push({
|
|
290
|
+
code: 'INVALID_LOCAL_IMAGE_TYPE',
|
|
291
|
+
message: `Unsupported image file extension for draft image: '${resolved.filename}'.`,
|
|
292
|
+
suggestion: 'Use a supported image format (.jpg, .jpeg, .png, .webp, .gif, .avif, .svg).',
|
|
293
|
+
});
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (stat.size > MAX_MEDIA_UPLOAD_BYTES) {
|
|
297
|
+
errors.push({
|
|
298
|
+
code: 'LOCAL_IMAGE_SIZE_EXCEEDED',
|
|
299
|
+
message: `Draft image '${resolved.filename}' (${stat.size} bytes) exceeds the maximum allowed upload size of ${MAX_MEDIA_UPLOAD_BYTES} bytes (50 MiB).`,
|
|
300
|
+
suggestion: 'Compress or resize the image below 50 MiB before pushing.',
|
|
301
|
+
});
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
draftImages.push({
|
|
306
|
+
line: trimmedLine,
|
|
307
|
+
alt,
|
|
308
|
+
rawPath: standaloneMatch[2],
|
|
309
|
+
filename: resolved.filename,
|
|
310
|
+
resolvedAbsPath: resolved.candidateAbs,
|
|
311
|
+
});
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
// Non-standalone line: check if any inline local image is embedded within paragraph text
|
|
315
|
+
const inlineMatches = [...rawLine.matchAll(ANY_LOCAL_IMAGE_REGEX)];
|
|
316
|
+
for (const match of inlineMatches) {
|
|
317
|
+
const fullImgSyntax = match[0];
|
|
318
|
+
const rawPath = match[2].trim();
|
|
319
|
+
const resolved = resolveDraftImagePath(filePath, rawPath, options?.workspaceRoot);
|
|
320
|
+
if (resolved.isInsideDraftsDir || resolved.isInsideMediaDir) {
|
|
321
|
+
errors.push({
|
|
322
|
+
code: 'INLINE_LOCAL_IMAGE_NOT_SUPPORTED',
|
|
323
|
+
message: `Inline local image detected inside paragraph: '${fullImgSyntax}'. EmDash Portable Text only supports block-level standalone images for automatic sync.`,
|
|
324
|
+
suggestion: 'Move the image onto its own standalone line at the beginning of the line (e.g. ).',
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
errors.push({
|
|
329
|
+
code: 'LOCAL_IMAGE_DETECTED',
|
|
330
|
+
message: `Local image path detected in markdown body: '${fullImgSyntax}'.`,
|
|
331
|
+
suggestion: 'Upload the image first using emdash official MCP "media_upload", and replace the local path with the returned remote URL (e.g. /_emdash/api/media/file/<id>.<ext>), or place it in "media/drafts/" on a standalone line.',
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// G10: featuredImage must reference a canonical 26-character media ULID (or null).
|
|
337
|
+
// A root-relative or absolute media URL that unambiguously contains a media ULID is
|
|
338
|
+
// accepted with a warning, because Emit resolves it to the canonical ULID on push.
|
|
339
|
+
if (frontmatter.featuredImage !== undefined && frontmatter.featuredImage !== null) {
|
|
340
|
+
const rawFeaturedImage = frontmatter.featuredImage.trim();
|
|
341
|
+
if (!CANONICAL_ULID_REGEX.test(rawFeaturedImage)) {
|
|
342
|
+
const resolved = extractMediaUlid(rawFeaturedImage);
|
|
343
|
+
if (resolved) {
|
|
344
|
+
warnings.push(`featuredImage '${rawFeaturedImage}' was resolved to the canonical media ULID '${resolved}'. Prefer writing the bare 26-character ULID in frontmatter.`);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
errors.push({
|
|
348
|
+
code: 'INVALID_FEATURED_IMAGE',
|
|
349
|
+
message: `Invalid featuredImage in frontmatter: '${frontmatter.featuredImage}'. It must be a valid 26-character Crockford media ULID or null.`,
|
|
350
|
+
suggestion: 'Upload the image first using EmDash Admin or MCP "media_upload", then specify the returned 26-character ULID (e.g. 01M67P0MBMJQQXH2K95HHCYRYB). To remove the featured image, set featuredImage: null. Local file paths are never allowed.',
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
91
354
|
}
|
|
92
355
|
// G6: Unresolved conflict markers check
|
|
93
356
|
if (CONFLICT_MARKER_REGEX.test(cleanedBody)) {
|
|
@@ -131,6 +394,7 @@ export function runPreflightChecks(filePath, parsed, options) {
|
|
|
131
394
|
frontmatter,
|
|
132
395
|
errors,
|
|
133
396
|
warnings,
|
|
397
|
+
draftImages,
|
|
134
398
|
};
|
|
135
399
|
}
|
|
136
400
|
//# sourceMappingURL=preflight.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/sync/preflight.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/sync/preflight.ts"],"names":[],"mappings":"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"}
|