nothumanallowed 14.5.2 → 14.5.4
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 +77 -6
- package/src/ui-dist/assets/{index-1hoj2kvN.css → index-CIozt-VX.css} +1 -1
- package/src/ui-dist/assets/index-DFiodghc.js +793 -0
- package/src/ui-dist/index.html +2 -2
- package/src/ui-dist/assets/index-ZLG7Juqo.js +0 -792
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "14.5.
|
|
3
|
+
"version": "14.5.4",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
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 = '14.5.
|
|
8
|
+
export const VERSION = '14.5.4';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -2100,6 +2100,73 @@ export function register(router) {
|
|
|
2100
2100
|
} catch (e) { sendError(res, 500, e.message); }
|
|
2101
2101
|
});
|
|
2102
2102
|
|
|
2103
|
+
// ── Full project scan — lint ALL files at once ───────────────────────────
|
|
2104
|
+
router.post('/api/studio/webcraft/scan', async (req, res) => {
|
|
2105
|
+
try {
|
|
2106
|
+
const { projectName } = await parseBody(req);
|
|
2107
|
+
if (!projectName) return sendError(res, 400, 'projectName required');
|
|
2108
|
+
const dir = ProjectStore.dir(projectName);
|
|
2109
|
+
if (!fs.existsSync(dir)) return sendJSON(res, 200, { issues: [] });
|
|
2110
|
+
|
|
2111
|
+
const files = _listProjectFiles(dir);
|
|
2112
|
+
const issues = [];
|
|
2113
|
+
const allFileNames = new Set(files);
|
|
2114
|
+
|
|
2115
|
+
for (const relPath of files) {
|
|
2116
|
+
const content = ProjectStore.readFile(projectName, relPath);
|
|
2117
|
+
if (!content) continue;
|
|
2118
|
+
const ext = relPath.split('.').pop()?.toLowerCase();
|
|
2119
|
+
|
|
2120
|
+
// JS syntax check
|
|
2121
|
+
if (ext === 'js' || ext === 'mjs') {
|
|
2122
|
+
try { new Function(content); } catch (e) {
|
|
2123
|
+
issues.push({ file: relPath, severity: 'error', message: `Syntax: ${e.message.replace(/\n.*/s, '')}` });
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
// JSON parse check
|
|
2128
|
+
if (ext === 'json') {
|
|
2129
|
+
try { JSON.parse(content); } catch (e) {
|
|
2130
|
+
issues.push({ file: relPath, severity: 'error', message: `JSON: ${e.message}` });
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
// CSS brace balance
|
|
2135
|
+
if (ext === 'css') {
|
|
2136
|
+
const o = (content.match(/\{/g) || []).length, c = (content.match(/\}/g) || []).length;
|
|
2137
|
+
if (o !== c) issues.push({ file: relPath, severity: 'warning', message: `Unbalanced braces: ${o} open, ${c} close` });
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
// HTML closing tag + reference check
|
|
2141
|
+
if (ext === 'html' || ext === 'htm') {
|
|
2142
|
+
if (!content.includes('</html>')) {
|
|
2143
|
+
issues.push({ file: relPath, severity: 'warning', message: 'Missing </html>' });
|
|
2144
|
+
}
|
|
2145
|
+
// Check file references
|
|
2146
|
+
const refRegex = /(?:src|href)=["']([^"']*?\.(?:js|css|mjs))["']/gi;
|
|
2147
|
+
let m;
|
|
2148
|
+
while ((m = refRegex.exec(content)) !== null) {
|
|
2149
|
+
const ref = m[1];
|
|
2150
|
+
if (ref.startsWith('http') || ref.startsWith('//') || ref.startsWith('data:')) continue;
|
|
2151
|
+
const htmlDir = path.dirname(relPath);
|
|
2152
|
+
const refPath = ref.startsWith('/') ? ref.slice(1) : path.join(htmlDir, ref).replace(/\\/g, '/');
|
|
2153
|
+
const publicRef = refPath.startsWith('public/') ? refPath : `public/${refPath}`;
|
|
2154
|
+
if (!allFileNames.has(refPath) && !allFileNames.has(publicRef) && !allFileNames.has(ref)) {
|
|
2155
|
+
issues.push({ file: relPath, severity: 'error', message: `Missing file: ${ref}` });
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
// Truncation check
|
|
2161
|
+
if (isFileTruncated(content, relPath)) {
|
|
2162
|
+
issues.push({ file: relPath, severity: 'warning', message: 'File appears truncated' });
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
sendJSON(res, 200, { issues, scanned: files.length });
|
|
2167
|
+
} catch (e) { sendError(res, 500, e.message); }
|
|
2168
|
+
});
|
|
2169
|
+
|
|
2103
2170
|
// ── Syntax check ──────────────────────────────────────────────────────────
|
|
2104
2171
|
router.post('/api/studio/webcraft/syntax-check', async (req, res) => {
|
|
2105
2172
|
try {
|
|
@@ -2177,13 +2244,17 @@ function _patchEntry(projectDir, entryFile, shimDir, port) {
|
|
|
2177
2244
|
`const _nhaErrScript = require('fs').readFileSync('${path.join(shimDir, 'error-reporter.html').replace(/\\/g, '/')}', 'utf-8');`,
|
|
2178
2245
|
`const _origWrite = require('http').ServerResponse.prototype.write;`,
|
|
2179
2246
|
`const _origEnd = require('http').ServerResponse.prototype.end;`,
|
|
2180
|
-
`function _inject(chunk) {`,
|
|
2181
|
-
` if (typeof chunk === 'string' && chunk.includes('</head>')) return chunk.replace('</head>', _nhaErrScript + '</head>');`,
|
|
2182
|
-
` if (Buffer.isBuffer(chunk)) { var s = chunk.toString(); if (s.includes('</head>')) return Buffer.from(s.replace('</head>', _nhaErrScript + '</head>')); }`,
|
|
2183
|
-
` return chunk;`,
|
|
2184
|
-
`}`,
|
|
2185
2247
|
`require('http').ServerResponse.prototype.end = function(chunk, enc, cb) {`,
|
|
2186
|
-
`
|
|
2248
|
+
` try {`,
|
|
2249
|
+
` if (chunk && this.getHeader && (this.getHeader('content-type')||'').includes('html')) {`,
|
|
2250
|
+
` var s = typeof chunk === 'string' ? chunk : Buffer.isBuffer(chunk) ? chunk.toString() : null;`,
|
|
2251
|
+
` if (s && s.includes('</head>')) {`,
|
|
2252
|
+
` var patched = s.replace('</head>', _nhaErrScript + '</head>');`,
|
|
2253
|
+
` try { this.removeHeader('content-length'); } catch(e) {}`,
|
|
2254
|
+
` return _origEnd.call(this, patched, enc, cb);`,
|
|
2255
|
+
` }`,
|
|
2256
|
+
` }`,
|
|
2257
|
+
` } catch(e) {}`,
|
|
2187
2258
|
` return _origEnd.apply(this, arguments);`,
|
|
2188
2259
|
`};`,
|
|
2189
2260
|
`require('${entryAbs}');`,
|