@biznetgio/neo-app 0.4.47 → 0.4.49
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/package.json +1 -1
- package/src/deploySource.js +21 -3
- package/src/mcp/tools.js +3 -1
package/package.json
CHANGED
package/src/deploySource.js
CHANGED
|
@@ -54,7 +54,9 @@ function collectExcludes(dir) {
|
|
|
54
54
|
for (let line of readFileSync(p, 'utf8').split(/\r?\n/)) {
|
|
55
55
|
line = line.trim();
|
|
56
56
|
if (!line || line.startsWith('#') || line.startsWith('!')) continue;
|
|
57
|
-
|
|
57
|
+
// Keep a leading slash: a gitignore anchor like `/themes` matches ONLY the root
|
|
58
|
+
// entry, not every nested `themes/` segment (JNG #116). Trailing slash is dropped.
|
|
59
|
+
excludes.add(line.replace(/\/+$/, ''));
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
return excludes;
|
|
@@ -67,6 +69,13 @@ function matchesExclude(rel, excludes) {
|
|
|
67
69
|
const parts = rel.split('/');
|
|
68
70
|
const base = parts[parts.length - 1];
|
|
69
71
|
for (const pat of excludes) {
|
|
72
|
+
if (pat.startsWith('/')) {
|
|
73
|
+
// Anchored (gitignore `/themes`): matches only at the repo root — the entry itself
|
|
74
|
+
// or something directly under it — NOT every nested `themes/` segment (JNG #116).
|
|
75
|
+
const a = pat.slice(1);
|
|
76
|
+
if (rel === a || rel.startsWith(a + '/')) return true;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
70
79
|
if (pat === base || pat === rel || parts.includes(pat)) return true;
|
|
71
80
|
if (pat.startsWith('*.') && base.endsWith(pat.slice(1))) return true;
|
|
72
81
|
}
|
|
@@ -84,6 +93,9 @@ function collectIncludedFiles(dir) {
|
|
|
84
93
|
let entries;
|
|
85
94
|
try { entries = readdirSync(d, { withFileTypes: true }); } catch { return; }
|
|
86
95
|
for (const e of entries) {
|
|
96
|
+
// Skip macOS cruft: AppleDouble resource forks (._*) and .DS_Store break Linux
|
|
97
|
+
// builds and are never part of the app (JNG #115).
|
|
98
|
+
if (e.name === '.DS_Store' || e.name.startsWith('._')) continue;
|
|
87
99
|
const r = rel ? `${rel}/${e.name}` : e.name;
|
|
88
100
|
if (matchesExclude(r, excludes) || isSecretPath(r)) continue;
|
|
89
101
|
if (e.isDirectory()) walk(join(d, e.name), r);
|
|
@@ -267,7 +279,10 @@ export async function deploySource(api, { projectId, src, name, port, build, ser
|
|
|
267
279
|
if (src.repo && app.repoUrl !== src.repo) patch.repoUrl = src.repo;
|
|
268
280
|
if (src.branch && app.branch !== src.branch) patch.branch = src.branch;
|
|
269
281
|
}
|
|
270
|
-
|
|
282
|
+
// Only change an existing service's build-type when EXPLICITLY asked (--build/build),
|
|
283
|
+
// never from an auto-detected buildType (e.g. a Dockerfile that appeared in the repo):
|
|
284
|
+
// a silent build-type switch on redeploy surprised users (JNG #131).
|
|
285
|
+
if (build && app.buildType && app.buildType !== buildType) patch.buildType = buildType;
|
|
271
286
|
if (Object.keys(patch).length) {
|
|
272
287
|
plan.push(`update "${svc}": ${Object.keys(patch).join(', ')}`);
|
|
273
288
|
if (!previewOnly) {
|
|
@@ -337,7 +352,10 @@ export async function deploySource(api, { projectId, src, name, port, build, ser
|
|
|
337
352
|
const listFile = join(tmpdir(), `neo-files-${app.id}-${Date.now()}.txt`);
|
|
338
353
|
writeFileSync(listFile, files.join('\n') + '\n');
|
|
339
354
|
try {
|
|
340
|
-
|
|
355
|
+
// COPYFILE_DISABLE=1 stops macOS bsdtar from SYNTHESIZING AppleDouble (._*)
|
|
356
|
+
// entries for files that carry extended attributes — those break Linux glob
|
|
357
|
+
// builds even though they aren't on disk (JNG #115).
|
|
358
|
+
execFileSync('tar', ['czf', archive, '-C', src.dir, '-T', listFile], { stdio: 'ignore', env: { ...process.env, COPYFILE_DISABLE: '1' } });
|
|
341
359
|
} finally {
|
|
342
360
|
rmSync(listFile, { force: true });
|
|
343
361
|
}
|
package/src/mcp/tools.js
CHANGED
|
@@ -1293,7 +1293,9 @@ export const TOOLS = [
|
|
|
1293
1293
|
required: ['planId', 'planHash', 'confirmationId'],
|
|
1294
1294
|
},
|
|
1295
1295
|
async call(api, args) {
|
|
1296
|
-
|
|
1296
|
+
// Always send an idempotency key (reuse the same one on a retry to dedup/resume).
|
|
1297
|
+
const idempotencyKey = args.idempotencyKey || `idem-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
1298
|
+
const { status, data } = await api.post(`/api/v1/plans/${args.planId}/apply`, { planHash: args.planHash, confirmationId: args.confirmationId, idempotencyKey });
|
|
1297
1299
|
return redactSecrets(result(status, data));
|
|
1298
1300
|
},
|
|
1299
1301
|
},
|