@portel/photon 1.0.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/LICENSE +21 -0
- package/README.md +952 -0
- package/dist/base.d.ts +58 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +92 -0
- package/dist/base.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1441 -0
- package/dist/cli.js.map +1 -0
- package/dist/dependency-manager.d.ts +49 -0
- package/dist/dependency-manager.d.ts.map +1 -0
- package/dist/dependency-manager.js +165 -0
- package/dist/dependency-manager.js.map +1 -0
- package/dist/loader.d.ts +86 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +612 -0
- package/dist/loader.js.map +1 -0
- package/dist/marketplace-manager.d.ts +261 -0
- package/dist/marketplace-manager.d.ts.map +1 -0
- package/dist/marketplace-manager.js +767 -0
- package/dist/marketplace-manager.js.map +1 -0
- package/dist/path-resolver.d.ts +21 -0
- package/dist/path-resolver.d.ts.map +1 -0
- package/dist/path-resolver.js +71 -0
- package/dist/path-resolver.js.map +1 -0
- package/dist/photon-doc-extractor.d.ts +89 -0
- package/dist/photon-doc-extractor.d.ts.map +1 -0
- package/dist/photon-doc-extractor.js +228 -0
- package/dist/photon-doc-extractor.js.map +1 -0
- package/dist/readme-syncer.d.ts +33 -0
- package/dist/readme-syncer.d.ts.map +1 -0
- package/dist/readme-syncer.js +93 -0
- package/dist/readme-syncer.js.map +1 -0
- package/dist/registry-manager.d.ts +76 -0
- package/dist/registry-manager.d.ts.map +1 -0
- package/dist/registry-manager.js +220 -0
- package/dist/registry-manager.js.map +1 -0
- package/dist/schema-extractor.d.ts +83 -0
- package/dist/schema-extractor.d.ts.map +1 -0
- package/dist/schema-extractor.js +396 -0
- package/dist/schema-extractor.js.map +1 -0
- package/dist/security-scanner.d.ts +52 -0
- package/dist/security-scanner.d.ts.map +1 -0
- package/dist/security-scanner.js +172 -0
- package/dist/security-scanner.js.map +1 -0
- package/dist/server.d.ts +73 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +474 -0
- package/dist/server.js.map +1 -0
- package/dist/template-manager.d.ts +56 -0
- package/dist/template-manager.d.ts.map +1 -0
- package/dist/template-manager.js +509 -0
- package/dist/template-manager.js.map +1 -0
- package/dist/test-client.d.ts +52 -0
- package/dist/test-client.d.ts.map +1 -0
- package/dist/test-client.js +168 -0
- package/dist/test-client.js.map +1 -0
- package/dist/test-marketplace-sources.d.ts +5 -0
- package/dist/test-marketplace-sources.d.ts.map +1 -0
- package/dist/test-marketplace-sources.js +53 -0
- package/dist/test-marketplace-sources.js.map +1 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/version-checker.d.ts +48 -0
- package/dist/version-checker.d.ts.map +1 -0
- package/dist/version-checker.js +128 -0
- package/dist/version-checker.js.map +1 -0
- package/dist/watcher.d.ts +26 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +72 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +79 -0
- package/templates/photon.template.ts +55 -0
package/dist/watcher.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Watcher for Dev Mode
|
|
3
|
+
*
|
|
4
|
+
* Watches .photon.ts file for changes and triggers hot reload
|
|
5
|
+
*/
|
|
6
|
+
import chokidar from 'chokidar';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
export class FileWatcher {
|
|
9
|
+
watcher = null;
|
|
10
|
+
server;
|
|
11
|
+
filePath;
|
|
12
|
+
reloadTimeout = null;
|
|
13
|
+
constructor(server, filePath) {
|
|
14
|
+
this.server = server;
|
|
15
|
+
this.filePath = path.resolve(filePath);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Start watching the file
|
|
19
|
+
*/
|
|
20
|
+
start() {
|
|
21
|
+
console.error(`Watching ${path.basename(this.filePath)} for changes...`);
|
|
22
|
+
this.watcher = chokidar.watch(this.filePath, {
|
|
23
|
+
persistent: true,
|
|
24
|
+
ignoreInitial: true,
|
|
25
|
+
awaitWriteFinish: {
|
|
26
|
+
stabilityThreshold: 100,
|
|
27
|
+
pollInterval: 50,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
this.watcher.on('change', (changedPath) => {
|
|
31
|
+
this.handleFileChange(changedPath);
|
|
32
|
+
});
|
|
33
|
+
this.watcher.on('error', (error) => {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
console.error(`Watcher error: ${message}`);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Handle file change event
|
|
40
|
+
*/
|
|
41
|
+
handleFileChange(changedPath) {
|
|
42
|
+
console.error(`♻️ File changed: ${path.basename(changedPath)}`);
|
|
43
|
+
// Debounce rapid changes
|
|
44
|
+
if (this.reloadTimeout) {
|
|
45
|
+
clearTimeout(this.reloadTimeout);
|
|
46
|
+
}
|
|
47
|
+
this.reloadTimeout = setTimeout(async () => {
|
|
48
|
+
try {
|
|
49
|
+
await this.server.reload();
|
|
50
|
+
console.error('✅ Hot reload complete');
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error(`❌ Hot reload failed: ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
}, 200);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stop watching
|
|
59
|
+
*/
|
|
60
|
+
async stop() {
|
|
61
|
+
if (this.watcher) {
|
|
62
|
+
await this.watcher.close();
|
|
63
|
+
this.watcher = null;
|
|
64
|
+
}
|
|
65
|
+
if (this.reloadTimeout) {
|
|
66
|
+
clearTimeout(this.reloadTimeout);
|
|
67
|
+
this.reloadTimeout = null;
|
|
68
|
+
}
|
|
69
|
+
console.error('File watcher stopped');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,QAA4B,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,OAAO,WAAW;IACd,OAAO,GAAqB,IAAI,CAAC;IACjC,MAAM,CAAe;IACrB,QAAQ,CAAS;IACjB,aAAa,GAA0B,IAAI,CAAC;IAEpD,YAAY,MAAoB,EAAE,QAAgB;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;QAEzE,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC3C,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,gBAAgB,EAAE;gBAChB,kBAAkB,EAAE,GAAG;gBACvB,YAAY,EAAE,EAAE;aACjB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,WAAmB,EAAE,EAAE;YAChD,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAc,EAAE,EAAE;YAC1C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,WAAmB;QAC1C,OAAO,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAEjE,yBAAyB;QACzB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACzC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC3B,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzD,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACxC,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@portel/photon",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "You focus on the business logic. We'll enable the rest. Build MCP servers in a single TypeScript file.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"photon": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"templates"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"prepublishOnly": "npm run build",
|
|
18
|
+
"test": "npm run test:all",
|
|
19
|
+
"test:all": "npm run build && npm run test:schema && npm run test:marketplace && npm run test:loader && npm run test:server && npm run test:integration && npm run test:readme",
|
|
20
|
+
"test:readme": "bash tests/readme-validation.sh",
|
|
21
|
+
"test:schema": "npx tsx tests/schema-extractor.test.ts",
|
|
22
|
+
"test:marketplace": "npx tsx tests/marketplace-manager.test.ts",
|
|
23
|
+
"test:loader": "npx tsx tests/loader.test.ts",
|
|
24
|
+
"test:server": "npx tsx tests/server.test.ts",
|
|
25
|
+
"test:integration": "npx tsx tests/integration.test.ts",
|
|
26
|
+
"test:load": "npm run build && node --expose-gc --max-old-space-size=4096 node_modules/.bin/tsx tests/load-test.ts",
|
|
27
|
+
"test:sqlite": "npm run build && npx tsx tests/sqlite.test.ts",
|
|
28
|
+
"test:github": "npm run build && npx tsx tests/github-issues.test.ts",
|
|
29
|
+
"release": "release-it",
|
|
30
|
+
"release:minor": "release-it minor",
|
|
31
|
+
"release:major": "release-it major",
|
|
32
|
+
"release:patch": "release-it patch",
|
|
33
|
+
"release:dry": "release-it --dry-run"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"mcp",
|
|
37
|
+
"model-context-protocol",
|
|
38
|
+
"photon",
|
|
39
|
+
"typescript",
|
|
40
|
+
"cli",
|
|
41
|
+
"single-file",
|
|
42
|
+
"business-logic",
|
|
43
|
+
"convention-over-configuration",
|
|
44
|
+
"claude",
|
|
45
|
+
"claude-desktop",
|
|
46
|
+
"hot-reload",
|
|
47
|
+
"marketplace",
|
|
48
|
+
"enterprise"
|
|
49
|
+
],
|
|
50
|
+
"author": "Portel Dev",
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
54
|
+
"chokidar": "^4.0.3",
|
|
55
|
+
"commander": "^12.1.0",
|
|
56
|
+
"esbuild": "^0.24.2",
|
|
57
|
+
"typescript": "^5.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
61
|
+
"@types/node": "^22.10.2",
|
|
62
|
+
"autocannon": "^8.0.0",
|
|
63
|
+
"clinic": "^13.0.0",
|
|
64
|
+
"release-it": "^19.0.6",
|
|
65
|
+
"tsx": "^4.20.6",
|
|
66
|
+
"typescript": "^5.7.3"
|
|
67
|
+
},
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=18.0.0"
|
|
70
|
+
},
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "https://github.com/portel-dev/photon.git"
|
|
74
|
+
},
|
|
75
|
+
"bugs": {
|
|
76
|
+
"url": "https://github.com/portel-dev/photon/issues"
|
|
77
|
+
},
|
|
78
|
+
"homepage": "https://github.com/portel-dev/photon#readme"
|
|
79
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TemplateName Photon MCP
|
|
3
|
+
*
|
|
4
|
+
* Single-file MCP server using Photon
|
|
5
|
+
* Run with: npx photon template-name.photon.ts --dev
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export default class TemplateName {
|
|
9
|
+
/**
|
|
10
|
+
* Optional initialization hook
|
|
11
|
+
* Called once when the MCP is loaded
|
|
12
|
+
*/
|
|
13
|
+
async onInitialize?() {
|
|
14
|
+
console.error('[template-name] Initialized');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Optional shutdown hook
|
|
19
|
+
* Called when the MCP is shutting down
|
|
20
|
+
*/
|
|
21
|
+
async onShutdown?() {
|
|
22
|
+
console.error('[template-name] Shutting down');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Example echo tool
|
|
27
|
+
* @param message Message to echo back
|
|
28
|
+
*/
|
|
29
|
+
async echo(params: { message: string }) {
|
|
30
|
+
return `Echo: ${params.message}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Add two numbers together
|
|
35
|
+
* @param a First number
|
|
36
|
+
* @param b Second number
|
|
37
|
+
*/
|
|
38
|
+
async add(params: { a: number; b: number }) {
|
|
39
|
+
return {
|
|
40
|
+
success: true,
|
|
41
|
+
content: `${params.a} + ${params.b} = ${params.a + params.b}`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get current timestamp
|
|
47
|
+
*/
|
|
48
|
+
async getCurrentTime(params: {}) {
|
|
49
|
+
const now = new Date();
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
content: `Current time: ${now.toISOString()}`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|