@portel/photon 1.8.3 → 1.9.0
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/dist/auto-ui/beam.d.ts.map +1 -1
- package/dist/auto-ui/beam.js +129 -17
- package/dist/auto-ui/beam.js.map +1 -1
- package/dist/auto-ui/types.d.ts.map +1 -1
- package/dist/auto-ui/types.js +3 -0
- package/dist/auto-ui/types.js.map +1 -1
- package/dist/beam.bundle.js +1062 -606
- package/dist/beam.bundle.js.map +4 -4
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/daemon/server.js +1 -1
- package/dist/daemon/server.js.map +1 -1
- package/dist/marketplace-manager.d.ts +9 -1
- package/dist/marketplace-manager.d.ts.map +1 -1
- package/dist/marketplace-manager.js +53 -5
- package/dist/marketplace-manager.js.map +1 -1
- package/dist/photon-doc-extractor.d.ts.map +1 -1
- package/dist/photon-doc-extractor.js +29 -7
- package/dist/photon-doc-extractor.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beam.d.ts","sourceRoot":"","sources":["../../src/auto-ui/beam.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiyBH,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"beam.d.ts","sourceRoot":"","sources":["../../src/auto-ui/beam.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiyBH,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAysFlF;AAiYD;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB9C"}
|
package/dist/auto-ui/beam.js
CHANGED
|
@@ -588,6 +588,9 @@ function extractCspFromSource(source) {
|
|
|
588
588
|
}
|
|
589
589
|
export async function startBeam(rawWorkingDir, port) {
|
|
590
590
|
const workingDir = path.resolve(rawWorkingDir);
|
|
591
|
+
// Show version banner immediately
|
|
592
|
+
const { PHOTON_VERSION } = await import('../version.js');
|
|
593
|
+
console.log(`\n⚡ Photon Beam v${PHOTON_VERSION}\n`);
|
|
591
594
|
// Initialize marketplace manager for photon discovery and installation
|
|
592
595
|
const marketplace = new MarketplaceManager();
|
|
593
596
|
await marketplace.initialize();
|
|
@@ -598,6 +601,16 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
598
601
|
catch (error) {
|
|
599
602
|
logger.warn(`Failed to update marketplace caches: ${getErrorMessage(error)}`);
|
|
600
603
|
}
|
|
604
|
+
// Repair missing assets from photons installed before the asset-download fix
|
|
605
|
+
try {
|
|
606
|
+
const repaired = await marketplace.repairMissingAssets(workingDir);
|
|
607
|
+
if (repaired > 0) {
|
|
608
|
+
logger.info(`Repaired assets for ${repaired} photon(s)`);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
catch (error) {
|
|
612
|
+
logger.warn(`Asset repair check failed: ${getErrorMessage(error)}`);
|
|
613
|
+
}
|
|
601
614
|
// Discover all photons (user photons + bundled photons)
|
|
602
615
|
const userPhotonList = await listPhotonMCPs(workingDir);
|
|
603
616
|
// Add bundled photons with their paths
|
|
@@ -1824,9 +1837,30 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
1824
1837
|
if (url.pathname === '/api/marketplace/list') {
|
|
1825
1838
|
res.setHeader('Content-Type', 'application/json');
|
|
1826
1839
|
try {
|
|
1840
|
+
// Auto-refresh caches older than 5 minutes so updates are detected without manual Sync
|
|
1841
|
+
await marketplace.autoUpdateStaleCaches(5 * 60 * 1000);
|
|
1842
|
+
const { readLocalMetadata } = await import('../marketplace-manager.js');
|
|
1827
1843
|
const allPhotons = await marketplace.getAllPhotons();
|
|
1844
|
+
const localMetadata = await readLocalMetadata();
|
|
1828
1845
|
const photonList = [];
|
|
1829
1846
|
for (const [name, { metadata, marketplace: mp }] of allPhotons) {
|
|
1847
|
+
const installed = photonMCPs.has(name);
|
|
1848
|
+
let hasUpdate = false;
|
|
1849
|
+
let latestVersion = '';
|
|
1850
|
+
if (installed) {
|
|
1851
|
+
const installMeta = localMetadata.photons[`${name}.photon.ts`];
|
|
1852
|
+
if (installMeta && metadata.hash) {
|
|
1853
|
+
// Primary: hash comparison (catches code changes without version bump)
|
|
1854
|
+
hasUpdate = installMeta.originalHash !== metadata.hash;
|
|
1855
|
+
}
|
|
1856
|
+
else if (installMeta && metadata.version) {
|
|
1857
|
+
// Fallback: version comparison
|
|
1858
|
+
hasUpdate = installMeta.version !== metadata.version;
|
|
1859
|
+
}
|
|
1860
|
+
if (hasUpdate) {
|
|
1861
|
+
latestVersion = metadata.version || '';
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1830
1864
|
photonList.push({
|
|
1831
1865
|
name,
|
|
1832
1866
|
description: metadata.description || '',
|
|
@@ -1836,7 +1870,9 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
1836
1870
|
marketplace: mp.name,
|
|
1837
1871
|
icon: metadata.icon,
|
|
1838
1872
|
internal: metadata.internal,
|
|
1839
|
-
installed
|
|
1873
|
+
installed,
|
|
1874
|
+
hasUpdate,
|
|
1875
|
+
latestVersion,
|
|
1840
1876
|
});
|
|
1841
1877
|
}
|
|
1842
1878
|
res.writeHead(200);
|
|
@@ -1878,6 +1914,9 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
1878
1914
|
const hash = (await import('../marketplace-manager.js')).calculateHash(result.content);
|
|
1879
1915
|
await marketplace.savePhotonMetadata(`${name}.photon.ts`, result.marketplace, result.metadata, hash);
|
|
1880
1916
|
}
|
|
1917
|
+
// Trigger immediate load so the photon appears in the sidebar right away
|
|
1918
|
+
// (don't wait for the file watcher which has debounce delay)
|
|
1919
|
+
handleFileChange(name);
|
|
1881
1920
|
res.writeHead(200);
|
|
1882
1921
|
res.end(JSON.stringify({
|
|
1883
1922
|
success: true,
|
|
@@ -1885,8 +1924,6 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
1885
1924
|
path: targetPath,
|
|
1886
1925
|
version: result.metadata?.version,
|
|
1887
1926
|
}));
|
|
1888
|
-
// Broadcast to connected clients to reload photon list
|
|
1889
|
-
broadcastPhotonChange();
|
|
1890
1927
|
}
|
|
1891
1928
|
catch {
|
|
1892
1929
|
res.writeHead(500);
|
|
@@ -1895,6 +1932,55 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
1895
1932
|
});
|
|
1896
1933
|
return;
|
|
1897
1934
|
}
|
|
1935
|
+
// Marketplace API: Remove/uninstall a photon
|
|
1936
|
+
if (url.pathname === '/api/marketplace/remove' && req.method === 'POST') {
|
|
1937
|
+
res.setHeader('Content-Type', 'application/json');
|
|
1938
|
+
const body = await readBody(req);
|
|
1939
|
+
try {
|
|
1940
|
+
const { name } = JSON.parse(body);
|
|
1941
|
+
if (!name) {
|
|
1942
|
+
res.writeHead(400);
|
|
1943
|
+
res.end(JSON.stringify({ error: 'Missing photon name' }));
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
const filePath = path.join(workingDir, `${name}.photon.ts`);
|
|
1947
|
+
if (!existsSync(filePath)) {
|
|
1948
|
+
res.writeHead(404);
|
|
1949
|
+
res.end(JSON.stringify({ error: `Photon '${name}' not found` }));
|
|
1950
|
+
return;
|
|
1951
|
+
}
|
|
1952
|
+
// Remove the .photon.ts file
|
|
1953
|
+
await fs.unlink(filePath);
|
|
1954
|
+
// Remove UI assets directory if it exists
|
|
1955
|
+
const assetsDir = path.join(workingDir, name);
|
|
1956
|
+
if (existsSync(assetsDir) && lstatSync(assetsDir).isDirectory()) {
|
|
1957
|
+
await fs.rm(assetsDir, { recursive: true });
|
|
1958
|
+
}
|
|
1959
|
+
// Clear compiled cache
|
|
1960
|
+
const cacheDir = path.join(os.homedir(), '.cache', 'photon-mcp', 'compiled');
|
|
1961
|
+
for (const ext of ['.js', '.js.map']) {
|
|
1962
|
+
try {
|
|
1963
|
+
await fs.unlink(path.join(cacheDir, `${name}${ext}`));
|
|
1964
|
+
}
|
|
1965
|
+
catch {
|
|
1966
|
+
/* ignore */
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
// Remove from loaded photons
|
|
1970
|
+
const idx = photons.findIndex((p) => p.name === name);
|
|
1971
|
+
if (idx !== -1)
|
|
1972
|
+
photons.splice(idx, 1);
|
|
1973
|
+
photonMCPs.delete(name);
|
|
1974
|
+
res.writeHead(200);
|
|
1975
|
+
res.end(JSON.stringify({ success: true, name }));
|
|
1976
|
+
broadcastPhotonChange();
|
|
1977
|
+
}
|
|
1978
|
+
catch {
|
|
1979
|
+
res.writeHead(500);
|
|
1980
|
+
res.end(JSON.stringify({ error: 'Failed to remove photon' }));
|
|
1981
|
+
}
|
|
1982
|
+
return;
|
|
1983
|
+
}
|
|
1898
1984
|
// Marketplace API: Get all marketplace sources
|
|
1899
1985
|
if (url.pathname === '/api/marketplace/sources') {
|
|
1900
1986
|
res.setHeader('Content-Type', 'application/json');
|
|
@@ -2058,18 +2144,24 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2058
2144
|
const { readLocalMetadata } = await import('../marketplace-manager.js');
|
|
2059
2145
|
const localMetadata = await readLocalMetadata();
|
|
2060
2146
|
const updates = [];
|
|
2061
|
-
// Check each installed photon for updates
|
|
2147
|
+
// Check each installed photon for updates (hash-based primary, version fallback)
|
|
2062
2148
|
for (const [fileName, installMeta] of Object.entries(localMetadata.photons)) {
|
|
2063
2149
|
const photonName = fileName.replace(/\.photon\.ts$/, '');
|
|
2064
2150
|
const latestInfo = await marketplace.getPhotonMetadata(photonName);
|
|
2065
|
-
if (latestInfo
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2151
|
+
if (latestInfo) {
|
|
2152
|
+
const hashChanged = latestInfo.metadata.hash
|
|
2153
|
+
? installMeta.originalHash !== latestInfo.metadata.hash
|
|
2154
|
+
: false;
|
|
2155
|
+
const versionChanged = latestInfo.metadata.version !== installMeta.version;
|
|
2156
|
+
if (hashChanged || versionChanged) {
|
|
2157
|
+
updates.push({
|
|
2158
|
+
name: photonName,
|
|
2159
|
+
fileName,
|
|
2160
|
+
currentVersion: installMeta.version,
|
|
2161
|
+
latestVersion: latestInfo.metadata.version,
|
|
2162
|
+
marketplace: latestInfo.marketplace.name,
|
|
2163
|
+
});
|
|
2164
|
+
}
|
|
2073
2165
|
}
|
|
2074
2166
|
}
|
|
2075
2167
|
res.writeHead(200);
|
|
@@ -2543,15 +2635,28 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2543
2635
|
socket.connect(p, '127.0.0.1');
|
|
2544
2636
|
});
|
|
2545
2637
|
};
|
|
2546
|
-
// Find an available port
|
|
2638
|
+
// Find an available port (compact status line output)
|
|
2639
|
+
const isTTY = process.stderr.isTTY;
|
|
2547
2640
|
while (currentPort < port + maxPortAttempts) {
|
|
2548
2641
|
const available = await isPortAvailable(currentPort);
|
|
2549
|
-
if (available)
|
|
2642
|
+
if (available) {
|
|
2643
|
+
// Clear the status line if we printed any
|
|
2644
|
+
if (currentPort > port && isTTY) {
|
|
2645
|
+
process.stderr.write('\r\x1b[K');
|
|
2646
|
+
}
|
|
2550
2647
|
break;
|
|
2551
|
-
|
|
2648
|
+
}
|
|
2649
|
+
if (isTTY) {
|
|
2650
|
+
process.stderr.write(`\r\x1b[K⚠️ Port ${currentPort} in use, trying ${currentPort + 1}...`);
|
|
2651
|
+
}
|
|
2652
|
+
else {
|
|
2653
|
+
console.error(`⚠️ Port ${currentPort} is in use, trying ${currentPort + 1}...`);
|
|
2654
|
+
}
|
|
2552
2655
|
currentPort++;
|
|
2553
2656
|
}
|
|
2554
2657
|
if (currentPort >= port + maxPortAttempts) {
|
|
2658
|
+
if (isTTY)
|
|
2659
|
+
process.stderr.write('\n');
|
|
2555
2660
|
console.error(`\n❌ No available port found (tried ${port}-${currentPort - 1}). Exiting.\n`);
|
|
2556
2661
|
process.exit(1);
|
|
2557
2662
|
}
|
|
@@ -2560,7 +2665,12 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2560
2665
|
server.once('error', (err) => {
|
|
2561
2666
|
if (err.code === 'EADDRINUSE' && currentPort < port + maxPortAttempts) {
|
|
2562
2667
|
currentPort++;
|
|
2563
|
-
|
|
2668
|
+
if (isTTY) {
|
|
2669
|
+
process.stderr.write(`\r\x1b[K⚠️ Port ${currentPort - 1} in use, trying ${currentPort}...`);
|
|
2670
|
+
}
|
|
2671
|
+
else {
|
|
2672
|
+
console.error(`⚠️ Port ${currentPort - 1} is in use, trying ${currentPort}...`);
|
|
2673
|
+
}
|
|
2564
2674
|
tryListen();
|
|
2565
2675
|
}
|
|
2566
2676
|
else if (err.code === 'EADDRINUSE') {
|
|
@@ -2577,7 +2687,9 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2577
2687
|
server.listen(currentPort, bindAddress, () => {
|
|
2578
2688
|
process.env.BEAM_PORT = String(currentPort);
|
|
2579
2689
|
const url = `http://localhost:${currentPort}`;
|
|
2580
|
-
|
|
2690
|
+
if (isTTY)
|
|
2691
|
+
process.stderr.write('\r\x1b[K'); // Clear any port status line
|
|
2692
|
+
console.log(`⚡ Photon Beam → ${url} (loading photons...)\n`);
|
|
2581
2693
|
resolve();
|
|
2582
2694
|
});
|
|
2583
2695
|
// Configure server and socket timeouts to prevent premature disconnections
|