nothumanallowed 16.0.47 → 16.0.48
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/constants.mjs +1 -1
- package/src/server/routes/webcraft.mjs +41 -30
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.48",
|
|
4
4
|
"description": "Local AI assistant: 80 tools (Gmail, Calendar, Drive, GitHub, Slack, browser, code, files), 38 agents, visual workflows (Studio, AWF, WebCraft). Install with `npm i -g nothumanallowed`, run with `nha ui`. Free tier built-in (Liara), no API key required. Your data stays on your PC — OAuth tokens local, no cloud. Open-source MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '16.0.
|
|
8
|
+
export const VERSION = '16.0.48';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -3146,48 +3146,59 @@ export function register(router) {
|
|
|
3146
3146
|
}
|
|
3147
3147
|
|
|
3148
3148
|
router.post('/api/studio/webcraft/lint', async (req, res) => {
|
|
3149
|
+
// ROBUST lint endpoint — NEVER returns 500. If any linter crashes,
|
|
3150
|
+
// returns 200 with empty diagnostics + the error logged. A failed lint
|
|
3151
|
+
// must not break the IDE streaming flow.
|
|
3149
3152
|
try {
|
|
3150
3153
|
const { projectName, path: relPath } = await parseBody(req);
|
|
3151
3154
|
if (!projectName || !relPath) return sendError(res, 400, 'projectName and path required');
|
|
3152
|
-
|
|
3153
|
-
|
|
3155
|
+
let content;
|
|
3156
|
+
try { content = ProjectStore.readFile(projectName, relPath); }
|
|
3157
|
+
catch { content = null; }
|
|
3158
|
+
if (content === null || content === undefined) return sendJSON(res, 200, { diagnostics: [] });
|
|
3154
3159
|
|
|
3155
3160
|
const ext = (relPath.split('.').pop() || '').toLowerCase();
|
|
3156
3161
|
let diagnostics = [];
|
|
3157
3162
|
|
|
3158
|
-
//
|
|
3163
|
+
// Each linter wrapped individually — a crash in one doesn't kill the others
|
|
3159
3164
|
if (['js', 'mjs', 'jsx', 'cjs'].includes(ext)) {
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
try { JSON.parse(content); } catch (e) {
|
|
3168
|
-
const posMatch = e.message.match(/position (\d+)/i);
|
|
3169
|
-
const pos = posMatch ? parseInt(posMatch[1]) : 0;
|
|
3170
|
-
const before = content.slice(0, pos).split('\n');
|
|
3171
|
-
diagnostics.push({
|
|
3172
|
-
from: { line: before.length, col: (before[before.length - 1] || '').length },
|
|
3173
|
-
severity: 'error',
|
|
3174
|
-
message: e.message,
|
|
3175
|
-
});
|
|
3165
|
+
try {
|
|
3166
|
+
const projectDir = ProjectStore.dir(projectName);
|
|
3167
|
+
const tsDiags = await lintJSWithTypeScript(projectDir, relPath).catch(() => null);
|
|
3168
|
+
diagnostics = tsDiags || lintJS(content, relPath, projectName) || [];
|
|
3169
|
+
} catch (e) {
|
|
3170
|
+
console.error('[lint] JS linter crashed for', relPath, ':', e.message);
|
|
3171
|
+
diagnostics = [];
|
|
3176
3172
|
}
|
|
3177
|
-
}
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3173
|
+
} else if (ext === 'json') {
|
|
3174
|
+
try {
|
|
3175
|
+
JSON.parse(content);
|
|
3176
|
+
} catch (e) {
|
|
3177
|
+
try {
|
|
3178
|
+
const posMatch = e.message.match(/position (\d+)/i);
|
|
3179
|
+
const pos = posMatch ? parseInt(posMatch[1]) : 0;
|
|
3180
|
+
const before = content.slice(0, pos).split('\n');
|
|
3181
|
+
diagnostics.push({
|
|
3182
|
+
from: { line: before.length, col: (before[before.length - 1] || '').length },
|
|
3183
|
+
severity: 'error',
|
|
3184
|
+
message: e.message,
|
|
3185
|
+
});
|
|
3186
|
+
} catch {}
|
|
3187
|
+
}
|
|
3188
|
+
} else if (ext === 'css') {
|
|
3189
|
+
try { diagnostics = lintCSS(content) || []; }
|
|
3190
|
+
catch (e) { console.error('[lint] CSS linter crashed:', e.message); diagnostics = []; }
|
|
3191
|
+
} else if (ext === 'html' || ext === 'htm') {
|
|
3192
|
+
try { diagnostics = lintHTML(content, relPath, projectName) || []; }
|
|
3193
|
+
catch (e) { console.error('[lint] HTML linter crashed:', e.message); diagnostics = []; }
|
|
3187
3194
|
}
|
|
3188
3195
|
|
|
3189
3196
|
sendJSON(res, 200, { diagnostics });
|
|
3190
|
-
} catch (e) {
|
|
3197
|
+
} catch (e) {
|
|
3198
|
+
// Even the outer catch returns 200 — lint failures must not break the IDE
|
|
3199
|
+
console.error('[lint] outer error:', e.message);
|
|
3200
|
+
sendJSON(res, 200, { diagnostics: [], error: e.message });
|
|
3201
|
+
}
|
|
3191
3202
|
});
|
|
3192
3203
|
|
|
3193
3204
|
// ── File write (from IDE editor) ──────────────────────────────────────────
|