@portel/photon 1.4.1 → 1.5.1
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/README.md +287 -1160
- package/dist/auto-ui/beam.d.ts +9 -0
- package/dist/auto-ui/beam.d.ts.map +1 -0
- package/dist/auto-ui/beam.js +2381 -0
- package/dist/auto-ui/beam.js.map +1 -0
- package/dist/auto-ui/components/card.d.ts +13 -0
- package/dist/auto-ui/components/card.d.ts.map +1 -0
- package/dist/auto-ui/components/card.js +64 -0
- package/dist/auto-ui/components/card.js.map +1 -0
- package/dist/auto-ui/components/form.d.ts +15 -0
- package/dist/auto-ui/components/form.d.ts.map +1 -0
- package/dist/auto-ui/components/form.js +72 -0
- package/dist/auto-ui/components/form.js.map +1 -0
- package/dist/auto-ui/components/list.d.ts +13 -0
- package/dist/auto-ui/components/list.d.ts.map +1 -0
- package/dist/auto-ui/components/list.js +58 -0
- package/dist/auto-ui/components/list.js.map +1 -0
- package/dist/auto-ui/components/progress.d.ts +18 -0
- package/dist/auto-ui/components/progress.d.ts.map +1 -0
- package/dist/auto-ui/components/progress.js +125 -0
- package/dist/auto-ui/components/progress.js.map +1 -0
- package/dist/auto-ui/components/table.d.ts +13 -0
- package/dist/auto-ui/components/table.d.ts.map +1 -0
- package/dist/auto-ui/components/table.js +82 -0
- package/dist/auto-ui/components/table.js.map +1 -0
- package/dist/auto-ui/components/tree.d.ts +13 -0
- package/dist/auto-ui/components/tree.d.ts.map +1 -0
- package/dist/auto-ui/components/tree.js +61 -0
- package/dist/auto-ui/components/tree.js.map +1 -0
- package/dist/auto-ui/daemon-tools.d.ts +45 -0
- package/dist/auto-ui/daemon-tools.d.ts.map +1 -0
- package/dist/auto-ui/daemon-tools.js +580 -0
- package/dist/auto-ui/daemon-tools.js.map +1 -0
- package/dist/auto-ui/design-system/index.d.ts +21 -0
- package/dist/auto-ui/design-system/index.d.ts.map +1 -0
- package/dist/auto-ui/design-system/index.js +27 -0
- package/dist/auto-ui/design-system/index.js.map +1 -0
- package/dist/auto-ui/design-system/tokens.d.ts +9 -0
- package/dist/auto-ui/design-system/tokens.d.ts.map +1 -0
- package/dist/auto-ui/design-system/tokens.js +27 -0
- package/dist/auto-ui/design-system/tokens.js.map +1 -0
- package/dist/auto-ui/design-system/transaction-ui.d.ts +70 -0
- package/dist/auto-ui/design-system/transaction-ui.d.ts.map +1 -0
- package/dist/auto-ui/design-system/transaction-ui.js +982 -0
- package/dist/auto-ui/design-system/transaction-ui.js.map +1 -0
- package/dist/auto-ui/frontend/index.html +84 -0
- package/dist/auto-ui/index.d.ts +21 -0
- package/dist/auto-ui/index.d.ts.map +1 -0
- package/dist/auto-ui/index.js +25 -0
- package/dist/auto-ui/index.js.map +1 -0
- package/dist/auto-ui/openapi-generator.d.ts +71 -0
- package/dist/auto-ui/openapi-generator.d.ts.map +1 -0
- package/dist/auto-ui/openapi-generator.js +223 -0
- package/dist/auto-ui/openapi-generator.js.map +1 -0
- package/dist/auto-ui/photon-bridge.d.ts +159 -0
- package/dist/auto-ui/photon-bridge.d.ts.map +1 -0
- package/dist/auto-ui/photon-bridge.js +262 -0
- package/dist/auto-ui/photon-bridge.js.map +1 -0
- package/dist/auto-ui/photon-host.d.ts +113 -0
- package/dist/auto-ui/photon-host.d.ts.map +1 -0
- package/dist/auto-ui/photon-host.js +284 -0
- package/dist/auto-ui/photon-host.js.map +1 -0
- package/dist/auto-ui/platform-compat.d.ts +71 -0
- package/dist/auto-ui/platform-compat.d.ts.map +1 -0
- package/dist/auto-ui/platform-compat.js +574 -0
- package/dist/auto-ui/platform-compat.js.map +1 -0
- package/dist/auto-ui/playground-html.d.ts +15 -0
- package/dist/auto-ui/playground-html.d.ts.map +1 -0
- package/dist/auto-ui/playground-html.js +1113 -0
- package/dist/auto-ui/playground-html.js.map +1 -0
- package/dist/auto-ui/playground-server.d.ts +7 -0
- package/dist/auto-ui/playground-server.d.ts.map +1 -0
- package/dist/auto-ui/playground-server.js +840 -0
- package/dist/auto-ui/playground-server.js.map +1 -0
- package/dist/auto-ui/registry.d.ts +13 -0
- package/dist/auto-ui/registry.d.ts.map +1 -0
- package/dist/auto-ui/registry.js +62 -0
- package/dist/auto-ui/registry.js.map +1 -0
- package/dist/auto-ui/renderer.d.ts +14 -0
- package/dist/auto-ui/renderer.d.ts.map +1 -0
- package/dist/auto-ui/renderer.js +88 -0
- package/dist/auto-ui/renderer.js.map +1 -0
- package/dist/auto-ui/rendering/components.d.ts +29 -0
- package/dist/auto-ui/rendering/components.d.ts.map +1 -0
- package/dist/auto-ui/rendering/components.js +773 -0
- package/dist/auto-ui/rendering/components.js.map +1 -0
- package/dist/auto-ui/rendering/field-analyzer.d.ts +48 -0
- package/dist/auto-ui/rendering/field-analyzer.d.ts.map +1 -0
- package/dist/auto-ui/rendering/field-analyzer.js +270 -0
- package/dist/auto-ui/rendering/field-analyzer.js.map +1 -0
- package/dist/auto-ui/rendering/field-renderers.d.ts +64 -0
- package/dist/auto-ui/rendering/field-renderers.d.ts.map +1 -0
- package/dist/auto-ui/rendering/field-renderers.js +317 -0
- package/dist/auto-ui/rendering/field-renderers.js.map +1 -0
- package/dist/auto-ui/rendering/index.d.ts +28 -0
- package/dist/auto-ui/rendering/index.d.ts.map +1 -0
- package/dist/auto-ui/rendering/index.js +60 -0
- package/dist/auto-ui/rendering/index.js.map +1 -0
- package/dist/auto-ui/rendering/layout-selector.d.ts +48 -0
- package/dist/auto-ui/rendering/layout-selector.d.ts.map +1 -0
- package/dist/auto-ui/rendering/layout-selector.js +352 -0
- package/dist/auto-ui/rendering/layout-selector.js.map +1 -0
- package/dist/auto-ui/rendering/template-engine.d.ts +41 -0
- package/dist/auto-ui/rendering/template-engine.d.ts.map +1 -0
- package/dist/auto-ui/rendering/template-engine.js +238 -0
- package/dist/auto-ui/rendering/template-engine.js.map +1 -0
- package/dist/auto-ui/streamable-http-transport.d.ts +79 -0
- package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -0
- package/dist/auto-ui/streamable-http-transport.js +1314 -0
- package/dist/auto-ui/streamable-http-transport.js.map +1 -0
- package/dist/auto-ui/types.d.ts +310 -0
- package/dist/auto-ui/types.d.ts.map +1 -0
- package/dist/auto-ui/types.js +71 -0
- package/dist/auto-ui/types.js.map +1 -0
- package/dist/beam.bundle.js +13506 -0
- package/dist/beam.bundle.js.map +7 -0
- package/dist/claude-code-plugin.d.ts.map +1 -1
- package/dist/claude-code-plugin.js +30 -30
- package/dist/claude-code-plugin.js.map +1 -1
- package/dist/cli/commands/info.d.ts +11 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +313 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/marketplace.d.ts +11 -0
- package/dist/cli/commands/marketplace.d.ts.map +1 -0
- package/dist/cli/commands/marketplace.js +198 -0
- package/dist/cli/commands/marketplace.js.map +1 -0
- package/dist/cli/commands/package-app.d.ts +9 -0
- package/dist/cli/commands/package-app.d.ts.map +1 -0
- package/dist/cli/commands/package-app.js +191 -0
- package/dist/cli/commands/package-app.js.map +1 -0
- package/dist/cli/commands/package.d.ts +11 -0
- package/dist/cli/commands/package.d.ts.map +1 -0
- package/dist/cli/commands/package.js +573 -0
- package/dist/cli/commands/package.js.map +1 -0
- package/dist/cli-alias.d.ts.map +1 -1
- package/dist/cli-alias.js +30 -28
- package/dist/cli-alias.js.map +1 -1
- package/dist/cli-formatter.d.ts +8 -24
- package/dist/cli-formatter.d.ts.map +1 -1
- package/dist/cli-formatter.js +8 -325
- package/dist/cli-formatter.js.map +1 -1
- package/dist/cli.d.ts +15 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1157 -1132
- package/dist/cli.js.map +1 -1
- package/dist/daemon/client.d.ts +79 -0
- package/dist/daemon/client.d.ts.map +1 -1
- package/dist/daemon/client.js +532 -8
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/manager.d.ts +46 -12
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/manager.js +102 -61
- package/dist/daemon/manager.js.map +1 -1
- package/dist/daemon/protocol.d.ts +62 -6
- package/dist/daemon/protocol.d.ts.map +1 -1
- package/dist/daemon/protocol.js +76 -1
- package/dist/daemon/protocol.js.map +1 -1
- package/dist/daemon/server.d.ts +6 -6
- package/dist/daemon/server.js +743 -133
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/session-manager.d.ts +8 -1
- package/dist/daemon/session-manager.d.ts.map +1 -1
- package/dist/daemon/session-manager.js +32 -9
- package/dist/daemon/session-manager.js.map +1 -1
- package/dist/deploy/cloudflare.d.ts +12 -0
- package/dist/deploy/cloudflare.d.ts.map +1 -0
- package/dist/deploy/cloudflare.js +216 -0
- package/dist/deploy/cloudflare.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +168 -21
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +1120 -318
- package/dist/loader.js.map +1 -1
- package/dist/markdown-utils.d.ts +8 -0
- package/dist/markdown-utils.d.ts.map +1 -0
- package/dist/markdown-utils.js +63 -0
- package/dist/markdown-utils.js.map +1 -0
- package/dist/marketplace-manager.d.ts +10 -0
- package/dist/marketplace-manager.d.ts.map +1 -1
- package/dist/marketplace-manager.js +112 -28
- package/dist/marketplace-manager.js.map +1 -1
- package/dist/mcp-client.d.ts +9 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +11 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp-elicitation.d.ts +32 -0
- package/dist/mcp-elicitation.d.ts.map +1 -0
- package/dist/mcp-elicitation.js +26 -0
- package/dist/mcp-elicitation.js.map +1 -0
- package/dist/path-resolver.d.ts +9 -12
- package/dist/path-resolver.d.ts.map +1 -1
- package/dist/path-resolver.js +13 -43
- package/dist/path-resolver.js.map +1 -1
- package/dist/photon-cli-runner.d.ts.map +1 -1
- package/dist/photon-cli-runner.js +202 -77
- package/dist/photon-cli-runner.js.map +1 -1
- package/dist/photon-doc-extractor.d.ts +88 -0
- package/dist/photon-doc-extractor.d.ts.map +1 -1
- package/dist/photon-doc-extractor.js +536 -27
- package/dist/photon-doc-extractor.js.map +1 -1
- package/dist/photons/maker.photon.d.ts +182 -0
- package/dist/photons/maker.photon.d.ts.map +1 -0
- package/dist/photons/maker.photon.js +504 -0
- package/dist/photons/maker.photon.js.map +1 -0
- package/dist/photons/maker.photon.ts +626 -0
- package/dist/photons/marketplace.photon.d.ts +110 -0
- package/dist/photons/marketplace.photon.d.ts.map +1 -0
- package/dist/photons/marketplace.photon.js +260 -0
- package/dist/photons/marketplace.photon.js.map +1 -0
- package/dist/photons/marketplace.photon.ts +378 -0
- package/dist/photons/tunnel.photon.d.ts +80 -0
- package/dist/photons/tunnel.photon.d.ts.map +1 -0
- package/dist/photons/tunnel.photon.js +269 -0
- package/dist/photons/tunnel.photon.js.map +1 -0
- package/dist/photons/tunnel.photon.ts +345 -0
- package/dist/security-scanner.d.ts.map +1 -1
- package/dist/security-scanner.js +18 -15
- package/dist/security-scanner.js.map +1 -1
- package/dist/serv/auth/jwt.d.ts +89 -0
- package/dist/serv/auth/jwt.d.ts.map +1 -0
- package/dist/serv/auth/jwt.js +239 -0
- package/dist/serv/auth/jwt.js.map +1 -0
- package/dist/serv/auth/oauth.d.ts +117 -0
- package/dist/serv/auth/oauth.d.ts.map +1 -0
- package/dist/serv/auth/oauth.js +395 -0
- package/dist/serv/auth/oauth.js.map +1 -0
- package/dist/serv/auth/well-known.d.ts +60 -0
- package/dist/serv/auth/well-known.d.ts.map +1 -0
- package/dist/serv/auth/well-known.js +154 -0
- package/dist/serv/auth/well-known.js.map +1 -0
- package/dist/serv/db/d1-client.d.ts +65 -0
- package/dist/serv/db/d1-client.d.ts.map +1 -0
- package/dist/serv/db/d1-client.js +137 -0
- package/dist/serv/db/d1-client.js.map +1 -0
- package/dist/serv/db/d1-stores.d.ts +62 -0
- package/dist/serv/db/d1-stores.d.ts.map +1 -0
- package/dist/serv/db/d1-stores.js +307 -0
- package/dist/serv/db/d1-stores.js.map +1 -0
- package/dist/serv/index.d.ts +114 -0
- package/dist/serv/index.d.ts.map +1 -0
- package/dist/serv/index.js +172 -0
- package/dist/serv/index.js.map +1 -0
- package/dist/serv/local.d.ts +118 -0
- package/dist/serv/local.d.ts.map +1 -0
- package/dist/serv/local.js +392 -0
- package/dist/serv/local.js.map +1 -0
- package/dist/serv/middleware/auth.d.ts +66 -0
- package/dist/serv/middleware/auth.d.ts.map +1 -0
- package/dist/serv/middleware/auth.js +178 -0
- package/dist/serv/middleware/auth.js.map +1 -0
- package/dist/serv/middleware/tenant.d.ts +94 -0
- package/dist/serv/middleware/tenant.d.ts.map +1 -0
- package/dist/serv/middleware/tenant.js +152 -0
- package/dist/serv/middleware/tenant.js.map +1 -0
- package/dist/serv/runtime/executor.d.ts +76 -0
- package/dist/serv/runtime/executor.d.ts.map +1 -0
- package/dist/serv/runtime/executor.js +105 -0
- package/dist/serv/runtime/executor.js.map +1 -0
- package/dist/serv/runtime/index.d.ts +8 -0
- package/dist/serv/runtime/index.d.ts.map +1 -0
- package/dist/serv/runtime/index.js +10 -0
- package/dist/serv/runtime/index.js.map +1 -0
- package/dist/serv/runtime/oauth-context.d.ts +121 -0
- package/dist/serv/runtime/oauth-context.d.ts.map +1 -0
- package/dist/serv/runtime/oauth-context.js +153 -0
- package/dist/serv/runtime/oauth-context.js.map +1 -0
- package/dist/serv/session/kv-store.d.ts +54 -0
- package/dist/serv/session/kv-store.d.ts.map +1 -0
- package/dist/serv/session/kv-store.js +149 -0
- package/dist/serv/session/kv-store.js.map +1 -0
- package/dist/serv/session/store.d.ts +113 -0
- package/dist/serv/session/store.d.ts.map +1 -0
- package/dist/serv/session/store.js +284 -0
- package/dist/serv/session/store.js.map +1 -0
- package/dist/serv/types/index.d.ts +147 -0
- package/dist/serv/types/index.d.ts.map +1 -0
- package/dist/serv/types/index.js +8 -0
- package/dist/serv/types/index.js.map +1 -0
- package/dist/serv/vault/token-vault.d.ts +102 -0
- package/dist/serv/vault/token-vault.d.ts.map +1 -0
- package/dist/serv/vault/token-vault.js +177 -0
- package/dist/serv/vault/token-vault.js.map +1 -0
- package/dist/server.d.ts +173 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1622 -86
- package/dist/server.js.map +1 -1
- package/dist/shared/cli-sections.d.ts +6 -0
- package/dist/shared/cli-sections.d.ts.map +1 -0
- package/dist/shared/cli-sections.js +16 -0
- package/dist/shared/cli-sections.js.map +1 -0
- package/dist/shared/cli-utils.d.ts +81 -0
- package/dist/shared/cli-utils.d.ts.map +1 -0
- package/dist/shared/cli-utils.js +174 -0
- package/dist/shared/cli-utils.js.map +1 -0
- package/dist/shared/config-docs.d.ts +6 -0
- package/dist/shared/config-docs.d.ts.map +1 -0
- package/dist/shared/config-docs.js +6 -0
- package/dist/shared/config-docs.js.map +1 -0
- package/dist/shared/error-handler.d.ts +128 -0
- package/dist/shared/error-handler.d.ts.map +1 -0
- package/dist/shared/error-handler.js +342 -0
- package/dist/shared/error-handler.js.map +1 -0
- package/dist/shared/logger.d.ts +42 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +123 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/performance.d.ts +65 -0
- package/dist/shared/performance.d.ts.map +1 -0
- package/dist/shared/performance.js +136 -0
- package/dist/shared/performance.js.map +1 -0
- package/dist/shared/task-runner.d.ts +2 -0
- package/dist/shared/task-runner.d.ts.map +1 -0
- package/dist/shared/task-runner.js +16 -0
- package/dist/shared/task-runner.js.map +1 -0
- package/dist/shared/validation.d.ts +6 -0
- package/dist/shared/validation.d.ts.map +1 -0
- package/dist/shared/validation.js +6 -0
- package/dist/shared/validation.js.map +1 -0
- package/dist/shared-utils.d.ts +63 -0
- package/dist/shared-utils.d.ts.map +1 -0
- package/dist/shared-utils.js +123 -0
- package/dist/shared-utils.js.map +1 -0
- package/dist/template-manager.d.ts +23 -2
- package/dist/template-manager.d.ts.map +1 -1
- package/dist/template-manager.js +175 -86
- package/dist/template-manager.js.map +1 -1
- package/dist/test-client.d.ts.map +1 -1
- package/dist/test-client.js +10 -8
- package/dist/test-client.js.map +1 -1
- package/dist/test-runner.d.ts +52 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +785 -0
- package/dist/test-runner.js.map +1 -0
- package/dist/testing.d.ts +103 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +163 -0
- package/dist/testing.js.map +1 -0
- package/dist/version-checker.d.ts.map +1 -1
- package/dist/version-checker.js +2 -2
- package/dist/version-checker.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/dist/watcher.d.ts +6 -3
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +49 -10
- package/dist/watcher.js.map +1 -1
- package/package.json +47 -7
- package/templates/cloudflare/worker.ts.template +381 -0
- package/templates/cloudflare/wrangler.toml.template +9 -0
- package/dist/base.d.ts +0 -58
- package/dist/base.d.ts.map +0 -1
- package/dist/base.js +0 -92
- package/dist/base.js.map +0 -1
- package/dist/dependency-manager.d.ts +0 -49
- package/dist/dependency-manager.d.ts.map +0 -1
- package/dist/dependency-manager.js +0 -165
- package/dist/dependency-manager.js.map +0 -1
- package/dist/registry-manager.d.ts +0 -76
- package/dist/registry-manager.d.ts.map +0 -1
- package/dist/registry-manager.js +0 -220
- package/dist/registry-manager.js.map +0 -1
- package/dist/schema-extractor.d.ts +0 -110
- package/dist/schema-extractor.d.ts.map +0 -1
- package/dist/schema-extractor.js +0 -727
- package/dist/schema-extractor.js.map +0 -1
- package/dist/test-marketplace-sources.d.ts +0 -5
- package/dist/test-marketplace-sources.d.ts.map +0 -1
- package/dist/test-marketplace-sources.js +0 -53
- package/dist/test-marketplace-sources.js.map +0 -1
- package/dist/types.d.ts +0 -109
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -12
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Photon Maker - Create and manage photons
|
|
3
|
+
* @description System photon for scaffolding and managing photons
|
|
4
|
+
* @internal
|
|
5
|
+
*
|
|
6
|
+
* ## Method Types
|
|
7
|
+
*
|
|
8
|
+
* This photon demonstrates two patterns for organizing methods:
|
|
9
|
+
*
|
|
10
|
+
* ### Static Methods (Global Actions)
|
|
11
|
+
* - Called on the class itself, no instance needed
|
|
12
|
+
* - In Beam UI: Appear in the Marketplace dropdown menu
|
|
13
|
+
* - In CLI: `photon cli maker <method>`
|
|
14
|
+
* - In MCP: Available as tools without instance context
|
|
15
|
+
* - Use for: Creating new photons, syncing marketplace, validating
|
|
16
|
+
*
|
|
17
|
+
* ### Instance Methods (Contextual Actions)
|
|
18
|
+
* - Called on a specific photon instance
|
|
19
|
+
* - In Beam UI: Appear in the per-photon gear menu
|
|
20
|
+
* - In CLI: Require photon context (future: `photon cli maker rename --photon serum`)
|
|
21
|
+
* - Use for: Renaming, describing, adding methods to a specific photon
|
|
22
|
+
*
|
|
23
|
+
* ### Generator Functions (Progress Streaming)
|
|
24
|
+
* - Use `async *method()` syntax for step-by-step progress
|
|
25
|
+
* - Yield `{ step, message }` objects for UI updates
|
|
26
|
+
* - Final yield should include `{ step: 'done', result }` or `{ type: 'done', result }`
|
|
27
|
+
*
|
|
28
|
+
* ### Wizard Pattern (Multi-Step UI)
|
|
29
|
+
* - Mark with `@wizard` JSDoc tag
|
|
30
|
+
* - Yield step definitions, receive user input via `yield`
|
|
31
|
+
* - Steps: input, select, multi-input, progress, done
|
|
32
|
+
*
|
|
33
|
+
* ## Decorators
|
|
34
|
+
*
|
|
35
|
+
* - `@internal` - Bundled with runtime, special UI treatment
|
|
36
|
+
* - `@wizard` - Renders as multi-step wizard instead of form
|
|
37
|
+
* - `@template` - Returns a prompt string (for MCP prompts)
|
|
38
|
+
* - `@resource` - Exposes as MCP resource with URI
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import * as fs from 'fs/promises';
|
|
42
|
+
import * as path from 'path';
|
|
43
|
+
import * as os from 'os';
|
|
44
|
+
import { exec } from 'child_process';
|
|
45
|
+
import { promisify } from 'util';
|
|
46
|
+
|
|
47
|
+
const execAsync = promisify(exec);
|
|
48
|
+
|
|
49
|
+
/** Wizard step types using standard ask/emit protocol */
|
|
50
|
+
type WizardStep =
|
|
51
|
+
| { ask: 'text'; id: string; message: string; label?: string; placeholder?: string; hint?: string; required?: boolean }
|
|
52
|
+
| { ask: 'select'; id: string; message: string; options: Array<{ value: string; label: string }>; multi?: boolean }
|
|
53
|
+
| { emit: 'status'; message: string }
|
|
54
|
+
| { emit: 'result'; data: any };
|
|
55
|
+
|
|
56
|
+
export default class Maker {
|
|
57
|
+
private photonPath: string;
|
|
58
|
+
private photonName: string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Instance is created with target photon context for per-photon operations
|
|
62
|
+
*/
|
|
63
|
+
constructor(photonPath?: string) {
|
|
64
|
+
this.photonPath = photonPath || '';
|
|
65
|
+
this.photonName = photonPath ? path.basename(photonPath, '.photon.ts') : '';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ============================================
|
|
69
|
+
// Static Methods → Marketplace Menu
|
|
70
|
+
// ============================================
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create a new photon
|
|
74
|
+
* @param name Name for the new photon (kebab-case recommended)
|
|
75
|
+
* @param methods Tool method names to scaffold (optional)
|
|
76
|
+
* @param prompts Prompt template names to scaffold (optional)
|
|
77
|
+
* @param resources Resource method names to scaffold (optional)
|
|
78
|
+
*/
|
|
79
|
+
static async *new({
|
|
80
|
+
name,
|
|
81
|
+
methods = [],
|
|
82
|
+
prompts = [],
|
|
83
|
+
resources = [],
|
|
84
|
+
}: {
|
|
85
|
+
/** Name for the new photon */
|
|
86
|
+
name: string;
|
|
87
|
+
/** Tool method names (optional) */
|
|
88
|
+
methods?: string[];
|
|
89
|
+
/** Prompt template names (optional) */
|
|
90
|
+
prompts?: string[];
|
|
91
|
+
/** Resource method names (optional) */
|
|
92
|
+
resources?: string[];
|
|
93
|
+
}): AsyncGenerator<{ step: string; message?: string; path?: string; code?: string }> {
|
|
94
|
+
const workingDir = process.env.PHOTON_DIR || path.join(os.homedir(), '.photon');
|
|
95
|
+
const fileName = `${name}.photon.ts`;
|
|
96
|
+
const filePath = path.join(workingDir, fileName);
|
|
97
|
+
|
|
98
|
+
yield { step: 'checking', message: `Checking if ${fileName} exists...` };
|
|
99
|
+
|
|
100
|
+
// Check if exists
|
|
101
|
+
try {
|
|
102
|
+
await fs.access(filePath);
|
|
103
|
+
throw new Error(`Photon already exists: ${filePath}`);
|
|
104
|
+
} catch (e: any) {
|
|
105
|
+
if (e.code !== 'ENOENT') throw e;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
yield { step: 'generating', message: 'Generating scaffold...' };
|
|
109
|
+
|
|
110
|
+
// Generate class name from kebab-case
|
|
111
|
+
const className = name
|
|
112
|
+
.split(/[-_]/)
|
|
113
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
114
|
+
.join('');
|
|
115
|
+
|
|
116
|
+
// Helper to normalize input (handles string or array)
|
|
117
|
+
const toArray = (input: string | string[] | undefined): string[] => {
|
|
118
|
+
if (!input) return [];
|
|
119
|
+
if (Array.isArray(input)) return input.filter(Boolean);
|
|
120
|
+
return input
|
|
121
|
+
.split(',')
|
|
122
|
+
.map((s) => s.trim())
|
|
123
|
+
.filter(Boolean);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Generate all stubs
|
|
127
|
+
const allStubs: string[] = [];
|
|
128
|
+
const methodList = toArray(methods);
|
|
129
|
+
const promptList = toArray(prompts);
|
|
130
|
+
const resourceList = toArray(resources);
|
|
131
|
+
|
|
132
|
+
// Tools
|
|
133
|
+
if (methodList.length > 0) {
|
|
134
|
+
allStubs.push(...methodList.map((m) => Maker.generateMethodStub(m, 'tool')));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Prompts (templates)
|
|
138
|
+
if (promptList.length > 0) {
|
|
139
|
+
allStubs.push(...promptList.map((p) => Maker.generateMethodStub(p, 'prompt')));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Resources
|
|
143
|
+
if (resourceList.length > 0) {
|
|
144
|
+
allStubs.push(...resourceList.map((r) => Maker.generateMethodStub(r, 'resource')));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Default if nothing specified
|
|
148
|
+
if (allStubs.length === 0) {
|
|
149
|
+
allStubs.push(Maker.generateMethodStub('example', 'tool'));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const code = `/**
|
|
153
|
+
* ${className}
|
|
154
|
+
* @description [Add description]
|
|
155
|
+
*/
|
|
156
|
+
export default class ${className} {
|
|
157
|
+
${allStubs.join('\n\n')}
|
|
158
|
+
}
|
|
159
|
+
`;
|
|
160
|
+
|
|
161
|
+
yield { step: 'writing', message: `Writing ${fileName}...` };
|
|
162
|
+
|
|
163
|
+
await fs.writeFile(filePath, code, 'utf-8');
|
|
164
|
+
|
|
165
|
+
yield { step: 'done', message: `Created ${fileName}`, path: filePath, code };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Validate all photons in the current directory
|
|
170
|
+
*/
|
|
171
|
+
static async *validate(): AsyncGenerator<{
|
|
172
|
+
step: string;
|
|
173
|
+
photon?: string;
|
|
174
|
+
status?: 'valid' | 'error';
|
|
175
|
+
error?: string;
|
|
176
|
+
summary?: { valid: number; errors: number };
|
|
177
|
+
}> {
|
|
178
|
+
const workingDir = process.env.PHOTON_DIR || process.cwd();
|
|
179
|
+
|
|
180
|
+
yield { step: 'scanning', photon: undefined };
|
|
181
|
+
|
|
182
|
+
const files = await fs.readdir(workingDir);
|
|
183
|
+
const photonFiles = files.filter((f) => f.endsWith('.photon.ts'));
|
|
184
|
+
|
|
185
|
+
let validCount = 0;
|
|
186
|
+
let errorCount = 0;
|
|
187
|
+
|
|
188
|
+
for (const file of photonFiles) {
|
|
189
|
+
try {
|
|
190
|
+
const content = await fs.readFile(path.join(workingDir, file), 'utf-8');
|
|
191
|
+
if (content.includes('export default class')) {
|
|
192
|
+
validCount++;
|
|
193
|
+
yield { step: 'validating', photon: file, status: 'valid' };
|
|
194
|
+
} else {
|
|
195
|
+
errorCount++;
|
|
196
|
+
yield {
|
|
197
|
+
step: 'validating',
|
|
198
|
+
photon: file,
|
|
199
|
+
status: 'error',
|
|
200
|
+
error: 'Missing default class export',
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
} catch (e: any) {
|
|
204
|
+
errorCount++;
|
|
205
|
+
yield { step: 'validating', photon: file, status: 'error', error: e.message };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
yield { step: 'done', summary: { valid: validCount, errors: errorCount } };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Guided wizard to create a new photon
|
|
214
|
+
* @wizard
|
|
215
|
+
* @param name Photon name in kebab-case (e.g., my-tools, api-wrapper)
|
|
216
|
+
* @returns {@label Create}
|
|
217
|
+
*/
|
|
218
|
+
static async *wizard({ name }: { name: string }): AsyncGenerator<WizardStep, void, any> {
|
|
219
|
+
if (!name) return;
|
|
220
|
+
|
|
221
|
+
// Step 1: Description
|
|
222
|
+
const descriptionRaw = yield {
|
|
223
|
+
ask: 'text' as const,
|
|
224
|
+
id: 'description',
|
|
225
|
+
message: 'What does this photon do?',
|
|
226
|
+
label: 'Description',
|
|
227
|
+
placeholder: 'e.g. Fetches and parses web pages',
|
|
228
|
+
hint: 'A short description of what this photon does',
|
|
229
|
+
required: true,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Step 2: Icon
|
|
233
|
+
const iconRaw = yield {
|
|
234
|
+
ask: 'text' as const,
|
|
235
|
+
id: 'icon',
|
|
236
|
+
message: 'Pick an emoji icon',
|
|
237
|
+
label: 'Icon',
|
|
238
|
+
placeholder: '⚡',
|
|
239
|
+
hint: 'An emoji icon for your photon (default: ⚡)',
|
|
240
|
+
required: false,
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Step 3: Methods
|
|
244
|
+
const methodsRaw = yield {
|
|
245
|
+
ask: 'text' as const,
|
|
246
|
+
id: 'methods',
|
|
247
|
+
message: 'Name your tool methods',
|
|
248
|
+
label: 'Methods',
|
|
249
|
+
placeholder: 'e.g. search, fetch, analyze',
|
|
250
|
+
hint: 'Comma-separated method names (default: example)',
|
|
251
|
+
required: false,
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// Step 4: Dependencies
|
|
255
|
+
const depsRaw = yield {
|
|
256
|
+
ask: 'text' as const,
|
|
257
|
+
id: 'dependencies',
|
|
258
|
+
message: 'npm packages to use',
|
|
259
|
+
label: 'Dependencies',
|
|
260
|
+
placeholder: 'e.g. axios, cheerio',
|
|
261
|
+
hint: 'Comma-separated npm package names (optional)',
|
|
262
|
+
required: false,
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// Progress
|
|
266
|
+
yield { emit: 'status' as const, message: 'Creating photon...' };
|
|
267
|
+
|
|
268
|
+
const nameStr = String(name);
|
|
269
|
+
const description = typeof descriptionRaw === 'string' && descriptionRaw.trim()
|
|
270
|
+
? descriptionRaw.trim()
|
|
271
|
+
: '[Add description]';
|
|
272
|
+
const icon = typeof iconRaw === 'string' && iconRaw.trim() ? iconRaw.trim() : '⚡';
|
|
273
|
+
const workingDir = process.env.PHOTON_DIR || path.join(os.homedir(), '.photon');
|
|
274
|
+
const fileName = `${nameStr}.photon.ts`;
|
|
275
|
+
const filePath = path.join(workingDir, fileName);
|
|
276
|
+
|
|
277
|
+
// Generate class name
|
|
278
|
+
const className = nameStr
|
|
279
|
+
.split(/[-_]/)
|
|
280
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
281
|
+
.join('');
|
|
282
|
+
|
|
283
|
+
// Parse comma-separated lists
|
|
284
|
+
const parseCsv = (val: any): string[] =>
|
|
285
|
+
typeof val === 'string' && val.trim()
|
|
286
|
+
? val.split(',').map((s) => s.trim()).filter(Boolean)
|
|
287
|
+
: Array.isArray(val) ? val : [];
|
|
288
|
+
|
|
289
|
+
const methodList = parseCsv(methodsRaw);
|
|
290
|
+
if (methodList.length === 0) methodList.push('example');
|
|
291
|
+
|
|
292
|
+
// Validate npm dependencies
|
|
293
|
+
const depsList = parseCsv(depsRaw);
|
|
294
|
+
const validDeps: Array<{ name: string; version: string }> = [];
|
|
295
|
+
|
|
296
|
+
for (const pkg of depsList) {
|
|
297
|
+
yield { emit: 'status' as const, message: `Checking ${pkg}...` };
|
|
298
|
+
const result = await Maker.validateNpmPackage(pkg);
|
|
299
|
+
if (result.valid && result.version) {
|
|
300
|
+
validDeps.push({ name: pkg, version: result.version });
|
|
301
|
+
yield { emit: 'status' as const, message: `✓ ${pkg}@${result.version}` };
|
|
302
|
+
} else {
|
|
303
|
+
yield { emit: 'status' as const, message: `✗ ${pkg} — not found, skipped` };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
yield { emit: 'status' as const, message: 'Generating scaffold...' };
|
|
308
|
+
|
|
309
|
+
// Build imports from valid deps
|
|
310
|
+
const importLines = validDeps.map((d) => Maker.importForPackage(d.name));
|
|
311
|
+
|
|
312
|
+
// Build @dependencies tag value
|
|
313
|
+
const depsTag = validDeps.map((d) => `${d.name}@^${d.version}`).join(', ');
|
|
314
|
+
|
|
315
|
+
// Generate method stubs
|
|
316
|
+
const allStubs = methodList.map((m) => Maker.generateMethodStub(m, 'tool'));
|
|
317
|
+
|
|
318
|
+
// Assemble JSDoc
|
|
319
|
+
const jsdocLines = [
|
|
320
|
+
'/**',
|
|
321
|
+
` * ${className} - ${description}`,
|
|
322
|
+
` * @description ${description}`,
|
|
323
|
+
` * @icon ${icon}`,
|
|
324
|
+
];
|
|
325
|
+
if (depsTag) {
|
|
326
|
+
jsdocLines.push(` * @dependencies ${depsTag}`);
|
|
327
|
+
}
|
|
328
|
+
jsdocLines.push(' */');
|
|
329
|
+
|
|
330
|
+
// Final code assembly: imports first, then JSDoc + class
|
|
331
|
+
const codeParts: string[] = [];
|
|
332
|
+
if (importLines.length > 0) {
|
|
333
|
+
codeParts.push(importLines.join('\n'));
|
|
334
|
+
codeParts.push('');
|
|
335
|
+
}
|
|
336
|
+
codeParts.push(jsdocLines.join('\n'));
|
|
337
|
+
codeParts.push(`export default class ${className} {`);
|
|
338
|
+
codeParts.push(allStubs.join('\n\n'));
|
|
339
|
+
codeParts.push('}');
|
|
340
|
+
codeParts.push('');
|
|
341
|
+
|
|
342
|
+
const code = codeParts.join('\n');
|
|
343
|
+
|
|
344
|
+
await fs.writeFile(filePath, code, 'utf-8');
|
|
345
|
+
|
|
346
|
+
// Done
|
|
347
|
+
yield {
|
|
348
|
+
emit: 'result' as const,
|
|
349
|
+
data: { message: `Created ${fileName}`, path: filePath, code },
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// ============================================
|
|
354
|
+
// Instance Methods → Per-Photon Gear Menu
|
|
355
|
+
// ============================================
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Rename this photon
|
|
359
|
+
* @param name New name for the photon
|
|
360
|
+
* @param photonPath Path to the photon file (optional, uses instance context if not provided)
|
|
361
|
+
*/
|
|
362
|
+
async rename({
|
|
363
|
+
name,
|
|
364
|
+
photonPath,
|
|
365
|
+
}: {
|
|
366
|
+
name: string;
|
|
367
|
+
photonPath?: string;
|
|
368
|
+
}): Promise<{ oldPath: string; newPath: string }> {
|
|
369
|
+
const targetPath = photonPath || this.photonPath;
|
|
370
|
+
if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
|
|
371
|
+
|
|
372
|
+
const dir = path.dirname(targetPath);
|
|
373
|
+
const newPath = path.join(dir, `${name}.photon.ts`);
|
|
374
|
+
|
|
375
|
+
// Read content and update class name
|
|
376
|
+
let content = await fs.readFile(targetPath, 'utf-8');
|
|
377
|
+
|
|
378
|
+
const newClassName = name
|
|
379
|
+
.split(/[-_]/)
|
|
380
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
381
|
+
.join('');
|
|
382
|
+
|
|
383
|
+
const oldPhotonName = path.basename(targetPath, '.photon.ts');
|
|
384
|
+
const oldClassName = oldPhotonName
|
|
385
|
+
.split(/[-_]/)
|
|
386
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
387
|
+
.join('');
|
|
388
|
+
|
|
389
|
+
content = content.replace(new RegExp(`class ${oldClassName}`, 'g'), `class ${newClassName}`);
|
|
390
|
+
|
|
391
|
+
// Write to new path
|
|
392
|
+
await fs.writeFile(newPath, content, 'utf-8');
|
|
393
|
+
|
|
394
|
+
// Remove old file
|
|
395
|
+
await fs.unlink(targetPath);
|
|
396
|
+
|
|
397
|
+
return { oldPath: targetPath, newPath };
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Update photon description
|
|
402
|
+
* @param description New description
|
|
403
|
+
* @param photonPath Path to the photon file (optional, uses instance context if not provided)
|
|
404
|
+
*/
|
|
405
|
+
async describe({
|
|
406
|
+
description,
|
|
407
|
+
photonPath,
|
|
408
|
+
}: {
|
|
409
|
+
description: string;
|
|
410
|
+
photonPath?: string;
|
|
411
|
+
}): Promise<{ updated: boolean }> {
|
|
412
|
+
const targetPath = photonPath || this.photonPath;
|
|
413
|
+
if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
|
|
414
|
+
|
|
415
|
+
let content = await fs.readFile(targetPath, 'utf-8');
|
|
416
|
+
|
|
417
|
+
// Update @description in JSDoc
|
|
418
|
+
if (content.includes('@description')) {
|
|
419
|
+
content = content.replace(/@description\s+.*/, `@description ${description}`);
|
|
420
|
+
} else {
|
|
421
|
+
// Add description to class JSDoc
|
|
422
|
+
content = content.replace(
|
|
423
|
+
/(\/\*\*[\s\S]*?)(\s*\*\/\s*export default class)/,
|
|
424
|
+
`$1\n * @description ${description}$2`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
await fs.writeFile(targetPath, content, 'utf-8');
|
|
429
|
+
|
|
430
|
+
return { updated: true };
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Add a new method to this photon
|
|
435
|
+
* @param name Method name
|
|
436
|
+
* @param type Method type
|
|
437
|
+
* @param photonPath Path to the photon file (optional, uses instance context if not provided)
|
|
438
|
+
*/
|
|
439
|
+
async addmethod({
|
|
440
|
+
name,
|
|
441
|
+
type = 'tool',
|
|
442
|
+
photonPath,
|
|
443
|
+
}: {
|
|
444
|
+
/** Method name */
|
|
445
|
+
name: string;
|
|
446
|
+
/** Method type */
|
|
447
|
+
type?: 'tool' | 'prompt' | 'resource';
|
|
448
|
+
/** Path to the photon file */
|
|
449
|
+
photonPath?: string;
|
|
450
|
+
}): Promise<{ added: string; type: string }> {
|
|
451
|
+
const targetPath = photonPath || this.photonPath;
|
|
452
|
+
if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
|
|
453
|
+
|
|
454
|
+
let content = await fs.readFile(targetPath, 'utf-8');
|
|
455
|
+
|
|
456
|
+
const methodCode = Maker.generateMethodStub(name, type);
|
|
457
|
+
|
|
458
|
+
// Insert before the closing brace of the class
|
|
459
|
+
const lastBraceIndex = content.lastIndexOf('}');
|
|
460
|
+
content =
|
|
461
|
+
content.slice(0, lastBraceIndex) + '\n' + methodCode + '\n' + content.slice(lastBraceIndex);
|
|
462
|
+
|
|
463
|
+
await fs.writeFile(targetPath, content, 'utf-8');
|
|
464
|
+
|
|
465
|
+
return { added: name, type };
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Delete this photon
|
|
470
|
+
* @param photonPath Path to the photon file (optional, uses instance context if not provided)
|
|
471
|
+
*/
|
|
472
|
+
async delete({ photonPath }: { photonPath?: string } = {}): Promise<{ deleted: string }> {
|
|
473
|
+
const targetPath = photonPath || this.photonPath;
|
|
474
|
+
if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
|
|
475
|
+
|
|
476
|
+
await fs.unlink(targetPath);
|
|
477
|
+
|
|
478
|
+
return { deleted: targetPath };
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* View source code of this photon
|
|
483
|
+
* @param photonPath Path to the photon file (optional, uses instance context if not provided)
|
|
484
|
+
*/
|
|
485
|
+
async source({ photonPath }: { photonPath?: string } = {}): Promise<{
|
|
486
|
+
path: string;
|
|
487
|
+
code: string;
|
|
488
|
+
}> {
|
|
489
|
+
const targetPath = photonPath || this.photonPath;
|
|
490
|
+
if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
|
|
491
|
+
|
|
492
|
+
const code = await fs.readFile(targetPath, 'utf-8');
|
|
493
|
+
|
|
494
|
+
return { path: targetPath, code };
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ============================================
|
|
498
|
+
// Helper Methods
|
|
499
|
+
// ============================================
|
|
500
|
+
|
|
501
|
+
private static async validateNpmPackage(name: string): Promise<{ valid: boolean; version?: string }> {
|
|
502
|
+
try {
|
|
503
|
+
const { stdout } = await execAsync(`npm view ${name} version --json`, { timeout: 10000 });
|
|
504
|
+
const version = JSON.parse(stdout.trim());
|
|
505
|
+
if (typeof version === 'string') return { valid: true, version };
|
|
506
|
+
return { valid: false };
|
|
507
|
+
} catch {
|
|
508
|
+
return { valid: false };
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private static importForPackage(pkg: string): string {
|
|
513
|
+
const knownImports: Record<string, string> = {
|
|
514
|
+
axios: `import axios from 'axios';`,
|
|
515
|
+
cheerio: `import * as cheerio from 'cheerio';`,
|
|
516
|
+
lodash: `import _ from 'lodash';`,
|
|
517
|
+
'node-fetch': `import fetch from 'node-fetch';`,
|
|
518
|
+
chalk: `import chalk from 'chalk';`,
|
|
519
|
+
dayjs: `import dayjs from 'dayjs';`,
|
|
520
|
+
zod: `import { z } from 'zod';`,
|
|
521
|
+
uuid: `import { v4 as uuid } from 'uuid';`,
|
|
522
|
+
};
|
|
523
|
+
if (knownImports[pkg]) return knownImports[pkg];
|
|
524
|
+
// Sanitize package name to valid JS identifier
|
|
525
|
+
const alias = pkg.replace(/^@/, '').replace(/[^a-zA-Z0-9]/g, '_');
|
|
526
|
+
return `import * as ${alias} from '${pkg}';`;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
private static paramNameForMethod(method: string): string {
|
|
530
|
+
const map: Record<string, string> = {
|
|
531
|
+
search: 'query',
|
|
532
|
+
fetch: 'url',
|
|
533
|
+
analyze: 'content',
|
|
534
|
+
parse: 'content',
|
|
535
|
+
get: 'url',
|
|
536
|
+
post: 'url',
|
|
537
|
+
create: 'name',
|
|
538
|
+
delete: 'id',
|
|
539
|
+
update: 'id',
|
|
540
|
+
send: 'message',
|
|
541
|
+
read: 'path',
|
|
542
|
+
write: 'path',
|
|
543
|
+
download: 'url',
|
|
544
|
+
upload: 'file',
|
|
545
|
+
translate: 'text',
|
|
546
|
+
summarize: 'text',
|
|
547
|
+
convert: 'input',
|
|
548
|
+
validate: 'input',
|
|
549
|
+
format: 'input',
|
|
550
|
+
};
|
|
551
|
+
return map[method] || 'input';
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
private static paramDescForMethod(method: string): string {
|
|
555
|
+
const map: Record<string, string> = {
|
|
556
|
+
search: 'Search query',
|
|
557
|
+
fetch: 'URL to fetch',
|
|
558
|
+
analyze: 'Content to analyze',
|
|
559
|
+
parse: 'Content to parse',
|
|
560
|
+
get: 'URL to request',
|
|
561
|
+
post: 'URL to post to',
|
|
562
|
+
create: 'Name to create',
|
|
563
|
+
delete: 'ID to delete',
|
|
564
|
+
update: 'ID to update',
|
|
565
|
+
send: 'Message to send',
|
|
566
|
+
read: 'File path to read',
|
|
567
|
+
write: 'File path to write',
|
|
568
|
+
download: 'URL to download',
|
|
569
|
+
upload: 'File to upload',
|
|
570
|
+
translate: 'Text to translate',
|
|
571
|
+
summarize: 'Text to summarize',
|
|
572
|
+
convert: 'Input to convert',
|
|
573
|
+
validate: 'Input to validate',
|
|
574
|
+
format: 'Input to format',
|
|
575
|
+
};
|
|
576
|
+
return map[method] || 'Input value';
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
private static generateMethodStub(name: string, type: string): string {
|
|
580
|
+
const indent = ' ';
|
|
581
|
+
|
|
582
|
+
if (type === 'prompt' || type === 'prompts') {
|
|
583
|
+
return `${indent}/**
|
|
584
|
+
${indent} * ${name}
|
|
585
|
+
${indent} * @template
|
|
586
|
+
${indent} */
|
|
587
|
+
${indent}async ${name}({
|
|
588
|
+
${indent} topic
|
|
589
|
+
${indent}}: {
|
|
590
|
+
${indent} /** Topic or subject */
|
|
591
|
+
${indent} topic: string;
|
|
592
|
+
${indent}}): Promise<string> {
|
|
593
|
+
${indent} return \`Prompt about: \${topic}\`;
|
|
594
|
+
${indent}}`;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (type === 'resource') {
|
|
598
|
+
return `${indent}/**
|
|
599
|
+
${indent} * ${name}
|
|
600
|
+
${indent} * @resource
|
|
601
|
+
${indent} * @uri ${name}://default
|
|
602
|
+
${indent} * @mimetype text/plain
|
|
603
|
+
${indent} */
|
|
604
|
+
${indent}async ${name}(): Promise<string> {
|
|
605
|
+
${indent} // Replace with your resource content
|
|
606
|
+
${indent} return 'Resource content here';
|
|
607
|
+
${indent}}`;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// Default: tool
|
|
611
|
+
const paramName = Maker.paramNameForMethod(name);
|
|
612
|
+
const paramDesc = Maker.paramDescForMethod(name);
|
|
613
|
+
|
|
614
|
+
return `${indent}/**
|
|
615
|
+
${indent} * ${name}
|
|
616
|
+
${indent} * @param ${paramName} ${paramDesc}
|
|
617
|
+
${indent} */
|
|
618
|
+
${indent}async ${name}({ ${paramName} }: {
|
|
619
|
+
${indent} /** ${paramDesc} */
|
|
620
|
+
${indent} ${paramName}: string;
|
|
621
|
+
${indent}}): Promise<{ result: string }> {
|
|
622
|
+
${indent} // Replace with your logic
|
|
623
|
+
${indent} return { result: ${paramName} };
|
|
624
|
+
${indent}}`;
|
|
625
|
+
}
|
|
626
|
+
}
|