nothumanallowed 14.5.1 → 14.5.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "14.5.1",
3
+ "version": "14.5.2",
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.1';
8
+ export const VERSION = '14.5.2';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -1624,6 +1624,56 @@ Continue from here:`;
1624
1624
  }
1625
1625
  }
1626
1626
 
1627
+ // ── Cross-reference check: verify HTML src/href point to existing files ────
1628
+ if (!abortSignal?.aborted) {
1629
+ const allFileNames = new Set(generatedFiles.map((f) => f.name));
1630
+ let refsFixed = 0;
1631
+ for (const f of generatedFiles) {
1632
+ if (!f.name.endsWith('.html')) continue;
1633
+ let modified = false;
1634
+ let html = f.content;
1635
+
1636
+ // Find all src="..." and href="..." references to local files
1637
+ const refRegex = /(?:src|href)=["']([^"']*?\.(?:js|css|mjs))["']/gi;
1638
+ let match;
1639
+ while ((match = refRegex.exec(html)) !== null) {
1640
+ const ref = match[1];
1641
+ if (ref.startsWith('http') || ref.startsWith('//') || ref.startsWith('data:')) continue;
1642
+
1643
+ // Resolve relative path from HTML file location
1644
+ const htmlDir = path.dirname(f.name);
1645
+ const refPath = ref.startsWith('/') ? ref.slice(1) : path.join(htmlDir, ref).replace(/\\/g, '/');
1646
+ const publicRef = refPath.startsWith('public/') ? refPath : `public/${refPath}`;
1647
+
1648
+ // Check if file exists in generated files
1649
+ if (!allFileNames.has(refPath) && !allFileNames.has(publicRef) && !allFileNames.has(ref)) {
1650
+ // Try to find the actual file by name
1651
+ const baseName = path.basename(ref);
1652
+ const actualFile = generatedFiles.find((g) => g.name.endsWith('/' + baseName) || g.name === baseName);
1653
+ if (actualFile) {
1654
+ // Fix the reference
1655
+ const correctRef = actualFile.name.startsWith('public/') ? actualFile.name.slice(7) : actualFile.name;
1656
+ html = html.replace(match[0], match[0].replace(ref, correctRef));
1657
+ modified = true;
1658
+ refsFixed++;
1659
+ emit({ type: 'status', msg: `Fixed reference: ${ref} → ${correctRef} in ${f.name}` });
1660
+ } else {
1661
+ emit({ type: 'status', msg: `Warning: ${f.name} references missing file: ${ref}` });
1662
+ }
1663
+ }
1664
+ }
1665
+
1666
+ if (modified) {
1667
+ f.content = html;
1668
+ const abs = path.join(projectDir, f.name);
1669
+ fs.writeFileSync(abs, html, 'utf-8');
1670
+ }
1671
+ }
1672
+ if (refsFixed > 0) {
1673
+ emit({ type: 'status', msg: `Auto-fixed ${refsFixed} broken file reference(s)` });
1674
+ }
1675
+ }
1676
+
1627
1677
  // Save project metadata
1628
1678
  const meta = {
1629
1679
  description,
@@ -1894,6 +1944,28 @@ export function register(router) {
1894
1944
  message: 'Missing </html> closing tag',
1895
1945
  });
1896
1946
  }
1947
+ // Check references to local files
1948
+ const refRegex = /(?:src|href)=["']([^"']*?\.(?:js|css|mjs))["']/gi;
1949
+ let refMatch;
1950
+ const lines = content.split('\n');
1951
+ while ((refMatch = refRegex.exec(content)) !== null) {
1952
+ const ref = refMatch[1];
1953
+ if (ref.startsWith('http') || ref.startsWith('//') || ref.startsWith('data:')) continue;
1954
+ const htmlDir = path.dirname(relPath);
1955
+ const refPath = ref.startsWith('/') ? ref.slice(1) : path.join(htmlDir, ref).replace(/\\/g, '/');
1956
+ const publicRef = refPath.startsWith('public/') ? refPath : `public/${refPath}`;
1957
+ const fileExists = ProjectStore.readFile(projectName, refPath) !== null
1958
+ || ProjectStore.readFile(projectName, publicRef) !== null
1959
+ || ProjectStore.readFile(projectName, ref) !== null;
1960
+ if (!fileExists) {
1961
+ const lineNum = content.slice(0, refMatch.index).split('\n').length;
1962
+ diagnostics.push({
1963
+ from: { line: lineNum, col: 0 },
1964
+ severity: 'error',
1965
+ message: `Referenced file not found: ${ref}`,
1966
+ });
1967
+ }
1968
+ }
1897
1969
  }
1898
1970
 
1899
1971
  sendJSON(res, 200, { diagnostics });