@agimon-ai/po 0.0.0-alpha.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 +755 -0
- package/assets/banner.png +0 -0
- package/assets/banner.svg +25 -0
- package/assets/favicon.svg +15 -0
- package/assets/logo-light.png +0 -0
- package/assets/logo-light.svg +25 -0
- package/assets/logo.png +0 -0
- package/assets/logo.svg +25 -0
- package/assets/mascot.png +0 -0
- package/assets/mascot.svg +25 -0
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/antigravity.cjs +5 -0
- package/dist/antigravity.d.mts +2 -0
- package/dist/antigravity.mjs +2 -0
- package/dist/apiContracts.cjs +11 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +52 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +7 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/baseCommand.cjs +3 -0
- package/dist/baseCommand.d.mts +2 -0
- package/dist/baseCommand.mjs +2 -0
- package/dist/bin/cli.cjs +24 -0
- package/dist/bin/cli.cjs.map +1 -0
- package/dist/bin/cli.d.mts +1 -0
- package/dist/bin/cli.mjs +25 -0
- package/dist/bin/cli.mjs.map +1 -0
- package/dist/bin/doomRunner.cjs +33 -0
- package/dist/bin/doomRunner.cjs.map +1 -0
- package/dist/bin/doomRunner.d.mts +4 -0
- package/dist/bin/doomRunner.d.mts.map +1 -0
- package/dist/bin/doomRunner.mjs +32 -0
- package/dist/bin/doomRunner.mjs.map +1 -0
- package/dist/bin/serve.cjs +30 -0
- package/dist/bin/serve.cjs.map +1 -0
- package/dist/bin/serve.d.mts +1 -0
- package/dist/bin/serve.mjs +31 -0
- package/dist/bin/serve.mjs.map +1 -0
- package/dist/builders/cli/extensionAssembler/index.cjs +342 -0
- package/dist/builders/cli/extensionAssembler/index.cjs.map +1 -0
- package/dist/builders/cli/extensionAssembler/index.d.mts +85 -0
- package/dist/builders/cli/extensionAssembler/index.d.mts.map +1 -0
- package/dist/builders/cli/extensionAssembler/index.mjs +335 -0
- package/dist/builders/cli/extensionAssembler/index.mjs.map +1 -0
- package/dist/catalog/index.json +430 -0
- package/dist/cli.cjs +28 -0
- package/dist/cli.d.mts +11 -0
- package/dist/cli.mjs +11 -0
- package/dist/cliApp.cjs +6 -0
- package/dist/cliApp.d.mts +2 -0
- package/dist/cliApp.mjs +2 -0
- package/dist/codex.cjs +8 -0
- package/dist/codex.d.mts +2 -0
- package/dist/codex.mjs +2 -0
- package/dist/commands.cjs +18 -0
- package/dist/commands.d.mts +9 -0
- package/dist/commands.mjs +9 -0
- package/dist/compatibility.cjs +27 -0
- package/dist/compatibility.d.mts +6 -0
- package/dist/compatibility.mjs +6 -0
- package/dist/compatibilityCommand.cjs +4 -0
- package/dist/compatibilityCommand.d.mts +2 -0
- package/dist/compatibilityCommand.mjs +2 -0
- package/dist/compatibilityContext.cjs +3 -0
- package/dist/compatibilityContext.d.mts +2 -0
- package/dist/compatibilityContext.mjs +2 -0
- package/dist/compatibilityOptions.cjs +5 -0
- package/dist/compatibilityOptions.d.mts +2 -0
- package/dist/compatibilityOptions.mjs +2 -0
- package/dist/config.cjs +163 -0
- package/dist/config.d.mts +7 -0
- package/dist/config.mjs +7 -0
- package/dist/doctorCommand.cjs +5 -0
- package/dist/doctorCommand.d.mts +2 -0
- package/dist/doctorCommand.mjs +2 -0
- package/dist/emitMcpCommand.cjs +4 -0
- package/dist/emitMcpCommand.d.mts +2 -0
- package/dist/emitMcpCommand.mjs +2 -0
- package/dist/explainCommand.cjs +5 -0
- package/dist/explainCommand.d.mts +2 -0
- package/dist/explainCommand.mjs +2 -0
- package/dist/extensions/server.cjs +39 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +34 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/harnessContext.cjs +5 -0
- package/dist/harnessContext.d.mts +2 -0
- package/dist/harnessContext.mjs +2 -0
- package/dist/harnessState.cjs +19 -0
- package/dist/harnessState.d.mts +2 -0
- package/dist/harnessState.mjs +2 -0
- package/dist/help.cjs +12 -0
- package/dist/help.d.mts +6 -0
- package/dist/help.mjs +6 -0
- package/dist/index.cjs +306 -0
- package/dist/index.d.mts +40 -0
- package/dist/index.mjs +37 -0
- package/dist/initCommand.cjs +4 -0
- package/dist/initCommand.d.mts +2 -0
- package/dist/initCommand.mjs +2 -0
- package/dist/matrixOptions.cjs +28 -0
- package/dist/matrixOptions.d.mts +2 -0
- package/dist/matrixOptions.mjs +2 -0
- package/dist/matrixSwitcher.cjs +11 -0
- package/dist/matrixSwitcher.d.mts +3 -0
- package/dist/matrixSwitcher.mjs +3 -0
- package/dist/mcpFilter.cjs +9 -0
- package/dist/mcpFilter.d.mts +1 -0
- package/dist/mcpFilter.mjs +2 -0
- package/dist/options.cjs +3 -0
- package/dist/options.d.mts +2 -0
- package/dist/options.mjs +2 -0
- package/dist/process.cjs +12 -0
- package/dist/process.d.mts +2 -0
- package/dist/process.mjs +2 -0
- package/dist/projectTrust.cjs +6 -0
- package/dist/projectTrust.d.mts +2 -0
- package/dist/projectTrust.mjs +2 -0
- package/dist/repository.cjs +5 -0
- package/dist/repository.d.mts +2 -0
- package/dist/repository.mjs +2 -0
- package/dist/resourceCollector.cjs +9 -0
- package/dist/resourceCollector.d.mts +1 -0
- package/dist/resourceCollector.mjs +2 -0
- package/dist/router.cjs +6 -0
- package/dist/router.d.mts +2 -0
- package/dist/router.mjs +2 -0
- package/dist/services.cjs +97 -0
- package/dist/services.d.mts +12 -0
- package/dist/services.mjs +12 -0
- package/dist/shared.cjs +18 -0
- package/dist/shared.d.mts +2 -0
- package/dist/shared.mjs +2 -0
- package/dist/src/bin/agentDirectory.cjs +27 -0
- package/dist/src/bin/agentDirectory.cjs.map +1 -0
- package/dist/src/bin/agentDirectory.mjs +26 -0
- package/dist/src/bin/agentDirectory.mjs.map +1 -0
- package/dist/src/builders/apiContractExport/index.cjs +126 -0
- package/dist/src/builders/apiContractExport/index.cjs.map +1 -0
- package/dist/src/builders/apiContractExport/index.mjs +123 -0
- package/dist/src/builders/apiContractExport/index.mjs.map +1 -0
- package/dist/src/builders/cli/entryResolution.cjs +39 -0
- package/dist/src/builders/cli/entryResolution.cjs.map +1 -0
- package/dist/src/builders/cli/entryResolution.mjs +35 -0
- package/dist/src/builders/cli/entryResolution.mjs.map +1 -0
- package/dist/src/builders/cli/harnessContext.cjs +175 -0
- package/dist/src/builders/cli/harnessContext.cjs.map +1 -0
- package/dist/src/builders/cli/harnessContext.d.mts +48 -0
- package/dist/src/builders/cli/harnessContext.d.mts.map +1 -0
- package/dist/src/builders/cli/harnessContext.mjs +167 -0
- package/dist/src/builders/cli/harnessContext.mjs.map +1 -0
- package/dist/src/builders/cli/sessionComposition.cjs +27 -0
- package/dist/src/builders/cli/sessionComposition.cjs.map +1 -0
- package/dist/src/builders/cli/sessionComposition.mjs +26 -0
- package/dist/src/builders/cli/sessionComposition.mjs.map +1 -0
- package/dist/src/builders/hooks/index.cjs +238 -0
- package/dist/src/builders/hooks/index.cjs.map +1 -0
- package/dist/src/builders/hooks/index.mjs +231 -0
- package/dist/src/builders/hooks/index.mjs.map +1 -0
- package/dist/src/builders/native/index.cjs +176 -0
- package/dist/src/builders/native/index.cjs.map +1 -0
- package/dist/src/builders/native/index.d.mts +36 -0
- package/dist/src/builders/native/index.d.mts.map +1 -0
- package/dist/src/builders/native/index.mjs +170 -0
- package/dist/src/builders/native/index.mjs.map +1 -0
- package/dist/src/builders/server/backgroundSync.cjs +333 -0
- package/dist/src/builders/server/backgroundSync.cjs.map +1 -0
- package/dist/src/builders/server/backgroundSync.mjs +320 -0
- package/dist/src/builders/server/backgroundSync.mjs.map +1 -0
- package/dist/src/builders/server/computerUseBinding.cjs +273 -0
- package/dist/src/builders/server/computerUseBinding.cjs.map +1 -0
- package/dist/src/builders/server/computerUseBinding.mjs +269 -0
- package/dist/src/builders/server/computerUseBinding.mjs.map +1 -0
- package/dist/src/builders/server/computerUseRecordings.cjs +188 -0
- package/dist/src/builders/server/computerUseRecordings.cjs.map +1 -0
- package/dist/src/builders/server/computerUseRecordings.mjs +184 -0
- package/dist/src/builders/server/computerUseRecordings.mjs.map +1 -0
- package/dist/src/builders/server/defaultWorkspace.cjs +38 -0
- package/dist/src/builders/server/defaultWorkspace.cjs.map +1 -0
- package/dist/src/builders/server/defaultWorkspace.mjs +35 -0
- package/dist/src/builders/server/defaultWorkspace.mjs.map +1 -0
- package/dist/src/builders/server/idleRestart.cjs +149 -0
- package/dist/src/builders/server/idleRestart.cjs.map +1 -0
- package/dist/src/builders/server/idleRestart.mjs +136 -0
- package/dist/src/builders/server/idleRestart.mjs.map +1 -0
- package/dist/src/builders/server/index.cjs +63 -0
- package/dist/src/builders/server/index.cjs.map +1 -0
- package/dist/src/builders/server/index.mjs +60 -0
- package/dist/src/builders/server/index.mjs.map +1 -0
- package/dist/src/builders/server/logSink.cjs +57 -0
- package/dist/src/builders/server/logSink.cjs.map +1 -0
- package/dist/src/builders/server/logSink.mjs +57 -0
- package/dist/src/builders/server/logSink.mjs.map +1 -0
- package/dist/src/builders/server/mcpApp.cjs +152 -0
- package/dist/src/builders/server/mcpApp.cjs.map +1 -0
- package/dist/src/builders/server/mcpApp.d.mts +18 -0
- package/dist/src/builders/server/mcpApp.d.mts.map +1 -0
- package/dist/src/builders/server/mcpApp.mjs +147 -0
- package/dist/src/builders/server/mcpApp.mjs.map +1 -0
- package/dist/src/builders/server/mcpAppBuild.cjs +111 -0
- package/dist/src/builders/server/mcpAppBuild.cjs.map +1 -0
- package/dist/src/builders/server/mcpAppBuild.d.mts +24 -0
- package/dist/src/builders/server/mcpAppBuild.d.mts.map +1 -0
- package/dist/src/builders/server/mcpAppBuild.mjs +105 -0
- package/dist/src/builders/server/mcpAppBuild.mjs.map +1 -0
- package/dist/src/builders/server/mcpBundle.cjs +87 -0
- package/dist/src/builders/server/mcpBundle.cjs.map +1 -0
- package/dist/src/builders/server/mcpBundle.d.mts +23 -0
- package/dist/src/builders/server/mcpBundle.d.mts.map +1 -0
- package/dist/src/builders/server/mcpBundle.mjs +84 -0
- package/dist/src/builders/server/mcpBundle.mjs.map +1 -0
- package/dist/src/builders/server/packageReloadCheck.cjs +62 -0
- package/dist/src/builders/server/packageReloadCheck.cjs.map +1 -0
- package/dist/src/builders/server/packageReloadCheck.mjs +61 -0
- package/dist/src/builders/server/packageReloadCheck.mjs.map +1 -0
- package/dist/src/builders/server/packageUrl.cjs +210 -0
- package/dist/src/builders/server/packageUrl.cjs.map +1 -0
- package/dist/src/builders/server/packageUrl.mjs +203 -0
- package/dist/src/builders/server/packageUrl.mjs.map +1 -0
- package/dist/src/builders/server/runtime.cjs +1428 -0
- package/dist/src/builders/server/runtime.cjs.map +1 -0
- package/dist/src/builders/server/runtime.mjs +1420 -0
- package/dist/src/builders/server/runtime.mjs.map +1 -0
- package/dist/src/builders/server/runtimeResources.cjs +72 -0
- package/dist/src/builders/server/runtimeResources.cjs.map +1 -0
- package/dist/src/builders/server/runtimeResources.mjs +71 -0
- package/dist/src/builders/server/runtimeResources.mjs.map +1 -0
- package/dist/src/builders/server/selectionStatus.cjs +12 -0
- package/dist/src/builders/server/selectionStatus.cjs.map +1 -0
- package/dist/src/builders/server/selectionStatus.mjs +12 -0
- package/dist/src/builders/server/selectionStatus.mjs.map +1 -0
- package/dist/src/builders/server/sessionArguments.cjs +63 -0
- package/dist/src/builders/server/sessionArguments.cjs.map +1 -0
- package/dist/src/builders/server/sessionArguments.mjs +62 -0
- package/dist/src/builders/server/sessionArguments.mjs.map +1 -0
- package/dist/src/builders/server/shutdown.cjs +16 -0
- package/dist/src/builders/server/shutdown.cjs.map +1 -0
- package/dist/src/builders/server/shutdown.mjs +16 -0
- package/dist/src/builders/server/shutdown.mjs.map +1 -0
- package/dist/src/builders/server/webTemplateDecision.cjs +34 -0
- package/dist/src/builders/server/webTemplateDecision.cjs.map +1 -0
- package/dist/src/builders/server/webTemplateDecision.mjs +32 -0
- package/dist/src/builders/server/webTemplateDecision.mjs.map +1 -0
- package/dist/src/builders/server/workspaceCheckout.cjs +31 -0
- package/dist/src/builders/server/workspaceCheckout.cjs.map +1 -0
- package/dist/src/builders/server/workspaceCheckout.mjs +29 -0
- package/dist/src/builders/server/workspaceCheckout.mjs.map +1 -0
- package/dist/src/builders/web/bundle.cjs +225 -0
- package/dist/src/builders/web/bundle.cjs.map +1 -0
- package/dist/src/builders/web/bundle.d.mts +65 -0
- package/dist/src/builders/web/bundle.d.mts.map +1 -0
- package/dist/src/builders/web/bundle.mjs +221 -0
- package/dist/src/builders/web/bundle.mjs.map +1 -0
- package/dist/src/builders/web/bundleAssetPolicy.cjs +96 -0
- package/dist/src/builders/web/bundleAssetPolicy.cjs.map +1 -0
- package/dist/src/builders/web/bundleAssetPolicy.d.mts +22 -0
- package/dist/src/builders/web/bundleAssetPolicy.d.mts.map +1 -0
- package/dist/src/builders/web/bundleAssetPolicy.mjs +95 -0
- package/dist/src/builders/web/bundleAssetPolicy.mjs.map +1 -0
- package/dist/src/builders/web/index.cjs +361 -0
- package/dist/src/builders/web/index.cjs.map +1 -0
- package/dist/src/builders/web/index.d.mts +109 -0
- package/dist/src/builders/web/index.d.mts.map +1 -0
- package/dist/src/builders/web/index.mjs +342 -0
- package/dist/src/builders/web/index.mjs.map +1 -0
- package/dist/src/builders/web/webDevRoots.cjs +27 -0
- package/dist/src/builders/web/webDevRoots.cjs.map +1 -0
- package/dist/src/builders/web/webDevRoots.d.mts +22 -0
- package/dist/src/builders/web/webDevRoots.d.mts.map +1 -0
- package/dist/src/builders/web/webDevRoots.mjs +25 -0
- package/dist/src/builders/web/webDevRoots.mjs.map +1 -0
- package/dist/src/builders/web/webPluginGenerate.cjs +188 -0
- package/dist/src/builders/web/webPluginGenerate.cjs.map +1 -0
- package/dist/src/builders/web/webPluginGenerate.d.mts +56 -0
- package/dist/src/builders/web/webPluginGenerate.d.mts.map +1 -0
- package/dist/src/builders/web/webPluginGenerate.mjs +178 -0
- package/dist/src/builders/web/webPluginGenerate.mjs.map +1 -0
- package/dist/src/builders/web/webPluginManifest.cjs +128 -0
- package/dist/src/builders/web/webPluginManifest.cjs.map +1 -0
- package/dist/src/builders/web/webPluginManifest.d.mts +64 -0
- package/dist/src/builders/web/webPluginManifest.d.mts.map +1 -0
- package/dist/src/builders/web/webPluginManifest.mjs +118 -0
- package/dist/src/builders/web/webPluginManifest.mjs.map +1 -0
- package/dist/src/builders/web/webPluginScan.cjs +57 -0
- package/dist/src/builders/web/webPluginScan.cjs.map +1 -0
- package/dist/src/builders/web/webPluginScan.d.mts +19 -0
- package/dist/src/builders/web/webPluginScan.d.mts.map +1 -0
- package/dist/src/builders/web/webPluginScan.mjs +54 -0
- package/dist/src/builders/web/webPluginScan.mjs.map +1 -0
- package/dist/src/builders/web/webPluginVite.cjs +255 -0
- package/dist/src/builders/web/webPluginVite.cjs.map +1 -0
- package/dist/src/builders/web/webPluginVite.d.mts +64 -0
- package/dist/src/builders/web/webPluginVite.d.mts.map +1 -0
- package/dist/src/builders/web/webPluginVite.mjs +242 -0
- package/dist/src/builders/web/webPluginVite.mjs.map +1 -0
- package/dist/src/cli/cliApp.cjs +187 -0
- package/dist/src/cli/cliApp.cjs.map +1 -0
- package/dist/src/cli/cliApp.d.mts +32 -0
- package/dist/src/cli/cliApp.d.mts.map +1 -0
- package/dist/src/cli/cliApp.mjs +184 -0
- package/dist/src/cli/cliApp.mjs.map +1 -0
- package/dist/src/cli/commands/api-export/index.cjs +66 -0
- package/dist/src/cli/commands/api-export/index.cjs.map +1 -0
- package/dist/src/cli/commands/api-export/index.mjs +62 -0
- package/dist/src/cli/commands/api-export/index.mjs.map +1 -0
- package/dist/src/cli/commands/baseCommand.cjs +16 -0
- package/dist/src/cli/commands/baseCommand.cjs.map +1 -0
- package/dist/src/cli/commands/baseCommand.d.mts +24 -0
- package/dist/src/cli/commands/baseCommand.d.mts.map +1 -0
- package/dist/src/cli/commands/baseCommand.mjs +16 -0
- package/dist/src/cli/commands/baseCommand.mjs.map +1 -0
- package/dist/src/cli/commands/compat/context.cjs +115 -0
- package/dist/src/cli/commands/compat/context.cjs.map +1 -0
- package/dist/src/cli/commands/compat/context.d.mts +22 -0
- package/dist/src/cli/commands/compat/context.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/context.mjs +110 -0
- package/dist/src/cli/commands/compat/context.mjs.map +1 -0
- package/dist/src/cli/commands/compat/help.cjs +26 -0
- package/dist/src/cli/commands/compat/help.cjs.map +1 -0
- package/dist/src/cli/commands/compat/help.d.mts +4 -0
- package/dist/src/cli/commands/compat/help.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/help.mjs +25 -0
- package/dist/src/cli/commands/compat/help.mjs.map +1 -0
- package/dist/src/cli/commands/compat/index.cjs +73 -0
- package/dist/src/cli/commands/compat/index.cjs.map +1 -0
- package/dist/src/cli/commands/compat/index.d.mts +14 -0
- package/dist/src/cli/commands/compat/index.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/index.mjs +70 -0
- package/dist/src/cli/commands/compat/index.mjs.map +1 -0
- package/dist/src/cli/commands/compat/options.cjs +88 -0
- package/dist/src/cli/commands/compat/options.cjs.map +1 -0
- package/dist/src/cli/commands/compat/options.d.mts +15 -0
- package/dist/src/cli/commands/compat/options.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/options.mjs +86 -0
- package/dist/src/cli/commands/compat/options.mjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/antigravity.cjs +294 -0
- package/dist/src/cli/commands/compat/providers/antigravity.cjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/antigravity.d.mts +9 -0
- package/dist/src/cli/commands/compat/providers/antigravity.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/providers/antigravity.mjs +289 -0
- package/dist/src/cli/commands/compat/providers/antigravity.mjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/codex.cjs +178 -0
- package/dist/src/cli/commands/compat/providers/codex.cjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/codex.d.mts +17 -0
- package/dist/src/cli/commands/compat/providers/codex.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/providers/codex.mjs +170 -0
- package/dist/src/cli/commands/compat/providers/codex.mjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/index.cjs +65 -0
- package/dist/src/cli/commands/compat/providers/index.cjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/index.d.mts +15 -0
- package/dist/src/cli/commands/compat/providers/index.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/providers/index.mjs +45 -0
- package/dist/src/cli/commands/compat/providers/index.mjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/process.cjs +172 -0
- package/dist/src/cli/commands/compat/providers/process.cjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/process.d.mts +33 -0
- package/dist/src/cli/commands/compat/providers/process.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/providers/process.mjs +159 -0
- package/dist/src/cli/commands/compat/providers/process.mjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/shared.cjs +76 -0
- package/dist/src/cli/commands/compat/providers/shared.cjs.map +1 -0
- package/dist/src/cli/commands/compat/providers/shared.d.mts +40 -0
- package/dist/src/cli/commands/compat/providers/shared.d.mts.map +1 -0
- package/dist/src/cli/commands/compat/providers/shared.mjs +61 -0
- package/dist/src/cli/commands/compat/providers/shared.mjs.map +1 -0
- package/dist/src/cli/commands/compat/types.d.mts +31 -0
- package/dist/src/cli/commands/compat/types.d.mts.map +1 -0
- package/dist/src/cli/commands/doctor/help.cjs +19 -0
- package/dist/src/cli/commands/doctor/help.cjs.map +1 -0
- package/dist/src/cli/commands/doctor/help.d.mts +4 -0
- package/dist/src/cli/commands/doctor/help.d.mts.map +1 -0
- package/dist/src/cli/commands/doctor/help.mjs +19 -0
- package/dist/src/cli/commands/doctor/help.mjs.map +1 -0
- package/dist/src/cli/commands/doctor/index.cjs +118 -0
- package/dist/src/cli/commands/doctor/index.cjs.map +1 -0
- package/dist/src/cli/commands/doctor/index.d.mts +33 -0
- package/dist/src/cli/commands/doctor/index.d.mts.map +1 -0
- package/dist/src/cli/commands/doctor/index.mjs +113 -0
- package/dist/src/cli/commands/doctor/index.mjs.map +1 -0
- package/dist/src/cli/commands/emit-mcp/index.cjs +32 -0
- package/dist/src/cli/commands/emit-mcp/index.cjs.map +1 -0
- package/dist/src/cli/commands/emit-mcp/index.d.mts +19 -0
- package/dist/src/cli/commands/emit-mcp/index.d.mts.map +1 -0
- package/dist/src/cli/commands/emit-mcp/index.mjs +31 -0
- package/dist/src/cli/commands/emit-mcp/index.mjs.map +1 -0
- package/dist/src/cli/commands/explain/index.cjs +155 -0
- package/dist/src/cli/commands/explain/index.cjs.map +1 -0
- package/dist/src/cli/commands/explain/index.d.mts +57 -0
- package/dist/src/cli/commands/explain/index.d.mts.map +1 -0
- package/dist/src/cli/commands/explain/index.mjs +150 -0
- package/dist/src/cli/commands/explain/index.mjs.map +1 -0
- package/dist/src/cli/commands/init/constants.cjs +11 -0
- package/dist/src/cli/commands/init/constants.cjs.map +1 -0
- package/dist/src/cli/commands/init/constants.mjs +11 -0
- package/dist/src/cli/commands/init/constants.mjs.map +1 -0
- package/dist/src/cli/commands/init/help.cjs +17 -0
- package/dist/src/cli/commands/init/help.cjs.map +1 -0
- package/dist/src/cli/commands/init/help.d.mts +4 -0
- package/dist/src/cli/commands/init/help.d.mts.map +1 -0
- package/dist/src/cli/commands/init/help.mjs +17 -0
- package/dist/src/cli/commands/init/help.mjs.map +1 -0
- package/dist/src/cli/commands/init/index.cjs +67 -0
- package/dist/src/cli/commands/init/index.cjs.map +1 -0
- package/dist/src/cli/commands/init/index.d.mts +12 -0
- package/dist/src/cli/commands/init/index.d.mts.map +1 -0
- package/dist/src/cli/commands/init/index.mjs +63 -0
- package/dist/src/cli/commands/init/index.mjs.map +1 -0
- package/dist/src/cli/commands/init/presenter.cjs +140 -0
- package/dist/src/cli/commands/init/presenter.cjs.map +1 -0
- package/dist/src/cli/commands/init/presenter.d.mts +8 -0
- package/dist/src/cli/commands/init/presenter.d.mts.map +1 -0
- package/dist/src/cli/commands/init/presenter.mjs +140 -0
- package/dist/src/cli/commands/init/presenter.mjs.map +1 -0
- package/dist/src/cli/commands/sync/help.cjs +34 -0
- package/dist/src/cli/commands/sync/help.cjs.map +1 -0
- package/dist/src/cli/commands/sync/help.d.mts +4 -0
- package/dist/src/cli/commands/sync/help.d.mts.map +1 -0
- package/dist/src/cli/commands/sync/help.mjs +34 -0
- package/dist/src/cli/commands/sync/help.mjs.map +1 -0
- package/dist/src/cli/commands/sync/index.cjs +215 -0
- package/dist/src/cli/commands/sync/index.cjs.map +1 -0
- package/dist/src/cli/commands/sync/index.d.mts +20 -0
- package/dist/src/cli/commands/sync/index.d.mts.map +1 -0
- package/dist/src/cli/commands/sync/index.mjs +206 -0
- package/dist/src/cli/commands/sync/index.mjs.map +1 -0
- package/dist/src/cli/commands/sync/presenter.cjs +58 -0
- package/dist/src/cli/commands/sync/presenter.cjs.map +1 -0
- package/dist/src/cli/commands/sync/presenter.d.mts +16 -0
- package/dist/src/cli/commands/sync/presenter.d.mts.map +1 -0
- package/dist/src/cli/commands/sync/presenter.mjs +57 -0
- package/dist/src/cli/commands/sync/presenter.mjs.map +1 -0
- package/dist/src/cli/commands/sync/workflow.cjs +16 -0
- package/dist/src/cli/commands/sync/workflow.cjs.map +1 -0
- package/dist/src/cli/commands/sync/workflow.mjs +16 -0
- package/dist/src/cli/commands/sync/workflow.mjs.map +1 -0
- package/dist/src/cli/commands/web/index.cjs +88 -0
- package/dist/src/cli/commands/web/index.cjs.map +1 -0
- package/dist/src/cli/commands/web/index.mjs +85 -0
- package/dist/src/cli/commands/web/index.mjs.map +1 -0
- package/dist/src/cli/harnessOptions.cjs +70 -0
- package/dist/src/cli/harnessOptions.cjs.map +1 -0
- package/dist/src/cli/harnessOptions.d.mts +26 -0
- package/dist/src/cli/harnessOptions.d.mts.map +1 -0
- package/dist/src/cli/harnessOptions.mjs +66 -0
- package/dist/src/cli/harnessOptions.mjs.map +1 -0
- package/dist/src/cli/help.cjs +82 -0
- package/dist/src/cli/help.cjs.map +1 -0
- package/dist/src/cli/help.d.mts +10 -0
- package/dist/src/cli/help.d.mts.map +1 -0
- package/dist/src/cli/help.mjs +78 -0
- package/dist/src/cli/help.mjs.map +1 -0
- package/dist/src/cli/matrixOptions.cjs +178 -0
- package/dist/src/cli/matrixOptions.cjs.map +1 -0
- package/dist/src/cli/matrixOptions.d.mts +90 -0
- package/dist/src/cli/matrixOptions.d.mts.map +1 -0
- package/dist/src/cli/matrixOptions.mjs +151 -0
- package/dist/src/cli/matrixOptions.mjs.map +1 -0
- package/dist/src/cli/options.cjs +281 -0
- package/dist/src/cli/options.cjs.map +1 -0
- package/dist/src/cli/options.d.mts +5 -0
- package/dist/src/cli/options.d.mts.map +1 -0
- package/dist/src/cli/options.mjs +279 -0
- package/dist/src/cli/options.mjs.map +1 -0
- package/dist/src/cli/router.cjs +57 -0
- package/dist/src/cli/router.cjs.map +1 -0
- package/dist/src/cli/router.d.mts +32 -0
- package/dist/src/cli/router.d.mts.map +1 -0
- package/dist/src/cli/router.mjs +54 -0
- package/dist/src/cli/router.mjs.map +1 -0
- package/dist/src/cli/server/options.cjs +71 -0
- package/dist/src/cli/server/options.cjs.map +1 -0
- package/dist/src/cli/server/options.mjs +70 -0
- package/dist/src/cli/server/options.mjs.map +1 -0
- package/dist/src/cli/server/processGuards.cjs +83 -0
- package/dist/src/cli/server/processGuards.cjs.map +1 -0
- package/dist/src/cli/server/processGuards.mjs +79 -0
- package/dist/src/cli/server/processGuards.mjs.map +1 -0
- package/dist/src/cli/server/run.cjs +69 -0
- package/dist/src/cli/server/run.cjs.map +1 -0
- package/dist/src/cli/server/run.mjs +66 -0
- package/dist/src/cli/server/run.mjs.map +1 -0
- package/dist/src/composition/harnessState/index.cjs +48 -0
- package/dist/src/composition/harnessState/index.cjs.map +1 -0
- package/dist/src/composition/harnessState/index.d.mts +19 -0
- package/dist/src/composition/harnessState/index.d.mts.map +1 -0
- package/dist/src/composition/harnessState/index.mjs +34 -0
- package/dist/src/composition/harnessState/index.mjs.map +1 -0
- package/dist/src/composition/layerPackageInstaller/index.cjs +651 -0
- package/dist/src/composition/layerPackageInstaller/index.cjs.map +1 -0
- package/dist/src/composition/layerPackageInstaller/index.d.mts +74 -0
- package/dist/src/composition/layerPackageInstaller/index.d.mts.map +1 -0
- package/dist/src/composition/layerPackageInstaller/index.mjs +637 -0
- package/dist/src/composition/layerPackageInstaller/index.mjs.map +1 -0
- package/dist/src/composition/poHomeMigration/index.cjs +234 -0
- package/dist/src/composition/poHomeMigration/index.cjs.map +1 -0
- package/dist/src/composition/poHomeMigration/index.d.mts +12 -0
- package/dist/src/composition/poHomeMigration/index.d.mts.map +1 -0
- package/dist/src/composition/poHomeMigration/index.mjs +226 -0
- package/dist/src/composition/poHomeMigration/index.mjs.map +1 -0
- package/dist/src/composition/projectTrust/index.cjs +51 -0
- package/dist/src/composition/projectTrust/index.cjs.map +1 -0
- package/dist/src/composition/projectTrust/index.d.mts +22 -0
- package/dist/src/composition/projectTrust/index.d.mts.map +1 -0
- package/dist/src/composition/projectTrust/index.mjs +48 -0
- package/dist/src/composition/projectTrust/index.mjs.map +1 -0
- package/dist/src/composition/repository/index.cjs +68 -0
- package/dist/src/composition/repository/index.cjs.map +1 -0
- package/dist/src/composition/repository/index.d.mts +22 -0
- package/dist/src/composition/repository/index.d.mts.map +1 -0
- package/dist/src/composition/repository/index.mjs +63 -0
- package/dist/src/composition/repository/index.mjs.map +1 -0
- package/dist/src/composition/syncPrune/index.cjs +85 -0
- package/dist/src/composition/syncPrune/index.cjs.map +1 -0
- package/dist/src/composition/syncPrune/index.d.mts +33 -0
- package/dist/src/composition/syncPrune/index.d.mts.map +1 -0
- package/dist/src/composition/syncPrune/index.mjs +82 -0
- package/dist/src/composition/syncPrune/index.mjs.map +1 -0
- package/dist/src/composition/syncService/index.cjs +808 -0
- package/dist/src/composition/syncService/index.cjs.map +1 -0
- package/dist/src/composition/syncService/index.d.mts +65 -0
- package/dist/src/composition/syncService/index.d.mts.map +1 -0
- package/dist/src/composition/syncService/index.mjs +792 -0
- package/dist/src/composition/syncService/index.mjs.map +1 -0
- package/dist/src/composition/syncService/localBuilds.cjs +367 -0
- package/dist/src/composition/syncService/localBuilds.cjs.map +1 -0
- package/dist/src/composition/syncService/localBuilds.mjs +358 -0
- package/dist/src/composition/syncService/localBuilds.mjs.map +1 -0
- package/dist/src/composition/transitionLayers.cjs +17 -0
- package/dist/src/composition/transitionLayers.cjs.map +1 -0
- package/dist/src/composition/transitionLayers.d.mts +6 -0
- package/dist/src/composition/transitionLayers.d.mts.map +1 -0
- package/dist/src/composition/transitionLayers.mjs +16 -0
- package/dist/src/composition/transitionLayers.mjs.map +1 -0
- package/dist/src/composition/types/harness.d.mts +52 -0
- package/dist/src/composition/types/harness.d.mts.map +1 -0
- package/dist/src/extensions/setupDiagnostics.cjs +65 -0
- package/dist/src/extensions/setupDiagnostics.cjs.map +1 -0
- package/dist/src/extensions/setupDiagnostics.mjs +64 -0
- package/dist/src/extensions/setupDiagnostics.mjs.map +1 -0
- package/dist/utils.cjs +4 -0
- package/dist/utils.d.mts +2 -0
- package/dist/utils.mjs +2 -0
- package/dist/webBuilder.cjs +59 -0
- package/dist/webBuilder.d.mts +9 -0
- package/dist/webBuilder.mjs +9 -0
- package/docs/server/api-export.md +86 -0
- package/docs/server/api.md +144 -0
- package/docs/server/getting-started.md +114 -0
- package/docs/server/index.md +67 -0
- package/docs/server/ipc.md +97 -0
- package/docs/server/lifecycle.md +108 -0
- package/docs/server/security.md +101 -0
- package/llms.txt +12 -0
- package/package.json +295 -0
- package/src/prompts/po-author-extension/SKILL.md +35 -0
- package/src/prompts/po-author-extension/references/extension-contract.md +134 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
node_fs = require_runtime.__toESM(node_fs, 1);
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
node_path = require_runtime.__toESM(node_path, 1);
|
|
6
|
+
let _agimon_ai_po_core_runtimeJson = require("@agimon-ai/po-core/runtimeJson");
|
|
7
|
+
let node_module = require("node:module");
|
|
8
|
+
let node_url = require("node:url");
|
|
9
|
+
let _agimon_ai_po_core_moduleResolution = require("@agimon-ai/po-core/moduleResolution");
|
|
10
|
+
let node_crypto = require("node:crypto");
|
|
11
|
+
node_crypto = require_runtime.__toESM(node_crypto, 1);
|
|
12
|
+
let _agimon_ai_po_config_layeredConfig = require("@agimon-ai/po-config/layeredConfig");
|
|
13
|
+
let yaml = require("yaml");
|
|
14
|
+
//#region src/builders/hooks/index.ts
|
|
15
|
+
const HOOK_MODULES_FILE = "hook-modules.json";
|
|
16
|
+
/** Add checkout source names while retaining the admitted generation's artifact mappings. */
|
|
17
|
+
function checkoutHookDescriptor(descriptor, sourceRoot, repoRoot, directory) {
|
|
18
|
+
if (!descriptor || node_path.default.resolve(sourceRoot) === node_path.default.resolve(repoRoot)) return descriptor;
|
|
19
|
+
const value = JSON.parse(node_fs.default.readFileSync(descriptor.file, "utf8"));
|
|
20
|
+
if (!(0, _agimon_ai_po_core_runtimeJson.isRecord)(value) || value.version !== 1 || !Array.isArray(value.modules)) throw new Error("invalid hook module descriptor");
|
|
21
|
+
const sources = /* @__PURE__ */ new Set();
|
|
22
|
+
const modules = [];
|
|
23
|
+
for (const entry of value.modules) {
|
|
24
|
+
if (!(0, _agimon_ai_po_core_runtimeJson.isRecord)(entry) || typeof entry.source !== "string" || typeof entry.artifact !== "string" || !node_path.default.isAbsolute(entry.source) || !node_path.default.isAbsolute(entry.artifact) || ![
|
|
25
|
+
".mjs",
|
|
26
|
+
".js",
|
|
27
|
+
".cjs"
|
|
28
|
+
].includes(node_path.default.extname(entry.artifact)) || sources.has(entry.source)) throw new Error("invalid hook module artifact mapping");
|
|
29
|
+
sources.add(entry.source);
|
|
30
|
+
modules.push({
|
|
31
|
+
...entry,
|
|
32
|
+
source: entry.source,
|
|
33
|
+
artifact: entry.artifact
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const aliases = [];
|
|
37
|
+
for (const entry of modules) {
|
|
38
|
+
const relative = node_path.default.relative(sourceRoot, entry.source);
|
|
39
|
+
if (!relative || relative === ".." || relative.startsWith(`..${node_path.default.sep}`) || node_path.default.isAbsolute(relative)) continue;
|
|
40
|
+
const source = node_path.default.resolve(repoRoot, relative);
|
|
41
|
+
if (sources.has(source)) continue;
|
|
42
|
+
sources.add(source);
|
|
43
|
+
aliases.push({
|
|
44
|
+
...entry,
|
|
45
|
+
source
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (aliases.length === 0) return descriptor;
|
|
49
|
+
const file = node_path.default.join(directory, HOOK_MODULES_FILE);
|
|
50
|
+
node_fs.default.writeFileSync(file, `${JSON.stringify({
|
|
51
|
+
...value,
|
|
52
|
+
modules: [...modules, ...aliases]
|
|
53
|
+
}, null, 2)}\n`, { mode: 384 });
|
|
54
|
+
return { file };
|
|
55
|
+
}
|
|
56
|
+
async function hookParser(options) {
|
|
57
|
+
const hasModuleRows = (0, _agimon_ai_po_config_layeredConfig.doomConfigCandidates)("hooks.yaml", options.repoRoot, options.homeDirectory).some((candidate) => {
|
|
58
|
+
if (!node_fs.default.existsSync(candidate.filePath)) return false;
|
|
59
|
+
const document = (0, yaml.parse)(node_fs.default.readFileSync(candidate.filePath, "utf8"));
|
|
60
|
+
if (!(0, _agimon_ai_po_core_runtimeJson.isRecord)(document) || !(0, _agimon_ai_po_core_runtimeJson.isRecord)(document.groups)) return false;
|
|
61
|
+
return Object.values(document.groups).some((group) => (0, _agimon_ai_po_core_runtimeJson.isRecord)(group) && Array.isArray(group.hooks) && group.hooks.some((row) => (0, _agimon_ai_po_core_runtimeJson.isRecord)(row) && (0, _agimon_ai_po_core_runtimeJson.isRecord)(row.pi) && "module" in row.pi));
|
|
62
|
+
});
|
|
63
|
+
const parserEntry = (0, _agimon_ai_po_core_moduleResolution.optionalPackageEntry)("@agimon-ai/po-hook", (0, node_url.pathToFileURL)(node_path.default.join(options.repoRoot, "package.json")).href) ?? (options.configRoot && options.configRoot !== options.repoRoot ? (0, _agimon_ai_po_core_moduleResolution.optionalPackageEntry)("@agimon-ai/po-hook", (0, node_url.pathToFileURL)(node_path.default.join(options.configRoot, "package.json")).href) : void 0) ?? (0, _agimon_ai_po_core_moduleResolution.optionalPackageEntry)("@agimon-ai/po-hook", require("url").pathToFileURL(__filename).href);
|
|
64
|
+
if (hasModuleRows && !parserEntry) throw new Error("Hook module rows require @agimon-ai/po-hook. Install it in the repository or select a layer that provides it, then run po sync.");
|
|
65
|
+
return hasModuleRows && parserEntry ? await import((0, node_url.pathToFileURL)(parserEntry).href) : void 0;
|
|
66
|
+
}
|
|
67
|
+
/** Validate the selected compiled hooks without importing repository code. */
|
|
68
|
+
async function validateHookModules(options) {
|
|
69
|
+
const parser = await hookParser(options);
|
|
70
|
+
if (!parser) return false;
|
|
71
|
+
const read = await parser.createHookDocumentReader({
|
|
72
|
+
homeDirectory: options.homeDirectory,
|
|
73
|
+
warn: () => void 0
|
|
74
|
+
}).registry(options.repoRoot);
|
|
75
|
+
if (read.failure) throw new Error(read.failure.message);
|
|
76
|
+
const allowed = options.hookGroups === void 0 ? void 0 : new Set(options.hookGroups);
|
|
77
|
+
const rows = read.entries.filter((row) => row.core || !allowed || allowed.has(row.groupId)).filter((row) => !(options.isSubagent && row.skipInSubagent));
|
|
78
|
+
const modules = parser.createHookModules({ descriptor: options.descriptor });
|
|
79
|
+
try {
|
|
80
|
+
await modules.validate(rows);
|
|
81
|
+
return rows.some((row) => row.module !== void 0);
|
|
82
|
+
} finally {
|
|
83
|
+
await modules.dispose();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Built JavaScript loads in place or from a package snapshot; TypeScript is compiled first. */
|
|
87
|
+
const BUILT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
88
|
+
".mjs",
|
|
89
|
+
".js",
|
|
90
|
+
".cjs"
|
|
91
|
+
]);
|
|
92
|
+
const TYPESCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
93
|
+
".ts",
|
|
94
|
+
".mts",
|
|
95
|
+
".cts"
|
|
96
|
+
]);
|
|
97
|
+
/** Pi's shared runtime must resolve to the copy this harness runs, as the sync compiler pinned it. */
|
|
98
|
+
const HOSTED_PACKAGES = /* @__PURE__ */ new Set([
|
|
99
|
+
"@earendil-works/pi-coding-agent",
|
|
100
|
+
"@earendil-works/pi-tui",
|
|
101
|
+
"@earendil-works/pi-ai"
|
|
102
|
+
]);
|
|
103
|
+
/**
|
|
104
|
+
* Compiles a TypeScript hook into one ESM file named by the hash of its bytes.
|
|
105
|
+
*
|
|
106
|
+
* Relative imports are bundled, so editing any of them yields a new file and URL. Bare
|
|
107
|
+
* imports are left external as the absolute file their importer resolves, or Pi's copy
|
|
108
|
+
* for hosted packages, so the artifact's location does not change what they load. A bare
|
|
109
|
+
* import that resolves to TypeScript is bundled, because Node does not strip it under
|
|
110
|
+
* node_modules. `import.meta.url` keeps naming each original source file.
|
|
111
|
+
*/
|
|
112
|
+
async function compileHookSource(source, directory) {
|
|
113
|
+
const { rolldown } = await import("rolldown");
|
|
114
|
+
const build = await rolldown({
|
|
115
|
+
input: source,
|
|
116
|
+
platform: "node",
|
|
117
|
+
onLog(_level, log, handler) {
|
|
118
|
+
if (log.code === "UNRESOLVED_IMPORT") handler("error", log);
|
|
119
|
+
},
|
|
120
|
+
plugins: [{
|
|
121
|
+
name: "po-hook-externals",
|
|
122
|
+
async resolveId(specifier, importer, extra) {
|
|
123
|
+
if (!importer || specifier.startsWith(".") || node_path.default.isAbsolute(specifier)) return null;
|
|
124
|
+
if ((0, node_module.isBuiltin)(specifier)) return {
|
|
125
|
+
id: specifier,
|
|
126
|
+
external: true
|
|
127
|
+
};
|
|
128
|
+
const root = specifier.split("/", specifier.startsWith("@") ? 2 : 1).join("/");
|
|
129
|
+
const resolved = (HOSTED_PACKAGES.has(root) ? (0, _agimon_ai_po_core_moduleResolution.optionalPackageEntry)(specifier, require("url").pathToFileURL(__filename).href) : void 0) ?? (await this.resolve(specifier, importer, {
|
|
130
|
+
...extra,
|
|
131
|
+
skipSelf: true
|
|
132
|
+
}))?.id;
|
|
133
|
+
if (resolved === void 0 || !node_path.default.isAbsolute(resolved)) return null;
|
|
134
|
+
if (TYPESCRIPT_EXTENSIONS.has(node_path.default.extname(resolved))) return resolved;
|
|
135
|
+
return {
|
|
136
|
+
id: (0, node_url.pathToFileURL)(resolved).href,
|
|
137
|
+
external: true
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
transform(code, id) {
|
|
141
|
+
if (!node_path.default.isAbsolute(id) || !code.includes("import.meta.url")) return null;
|
|
142
|
+
return code.replaceAll(/\bimport\.meta\.url\b/gu, JSON.stringify((0, node_url.pathToFileURL)(id).href));
|
|
143
|
+
}
|
|
144
|
+
}]
|
|
145
|
+
});
|
|
146
|
+
let code;
|
|
147
|
+
try {
|
|
148
|
+
code = (await build.generate({
|
|
149
|
+
format: "esm",
|
|
150
|
+
sourcemap: false,
|
|
151
|
+
codeSplitting: false
|
|
152
|
+
})).output[0].code;
|
|
153
|
+
} finally {
|
|
154
|
+
await build.close();
|
|
155
|
+
}
|
|
156
|
+
await node_fs.default.promises.mkdir(directory, {
|
|
157
|
+
recursive: true,
|
|
158
|
+
mode: 448
|
|
159
|
+
});
|
|
160
|
+
const file = node_path.default.join(directory, `${node_crypto.default.createHash("sha256").update(code).digest("hex")}.mjs`);
|
|
161
|
+
if (!node_fs.default.existsSync(file)) {
|
|
162
|
+
const staging = `${file}.${String(process.pid)}.${node_crypto.default.randomUUID()}`;
|
|
163
|
+
await node_fs.default.promises.writeFile(staging, code, { mode: 384 });
|
|
164
|
+
await node_fs.default.promises.rename(staging, file);
|
|
165
|
+
}
|
|
166
|
+
return file;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Writes a hook module descriptor from the live registry.
|
|
170
|
+
*
|
|
171
|
+
* A built JavaScript source maps through `artifactFor` (the server's content-addressed
|
|
172
|
+
* package paths); a TypeScript source is compiled into `directory`. A source that cannot
|
|
173
|
+
* be prepared is left out with a notice naming its rows, so validation fails closed for
|
|
174
|
+
* them. The descriptor is named by its content, so equal registries share one file.
|
|
175
|
+
* Returns undefined when no registry row names a module.
|
|
176
|
+
*/
|
|
177
|
+
async function writeLiveHookModules(options) {
|
|
178
|
+
const parser = await hookParser(options);
|
|
179
|
+
if (!parser) return void 0;
|
|
180
|
+
const read = await parser.createHookDocumentReader({
|
|
181
|
+
homeDirectory: options.homeDirectory,
|
|
182
|
+
warn: () => void 0
|
|
183
|
+
}).registry(options.repoRoot);
|
|
184
|
+
if (read.failure) throw new Error(read.failure.message);
|
|
185
|
+
const sources = /* @__PURE__ */ new Map();
|
|
186
|
+
for (const row of read.entries) {
|
|
187
|
+
if (!row.module) continue;
|
|
188
|
+
const rows = sources.get(row.module) ?? [];
|
|
189
|
+
rows.push({
|
|
190
|
+
registry: row.registryId,
|
|
191
|
+
groupId: row.groupId,
|
|
192
|
+
rowId: row.rowId,
|
|
193
|
+
event: row.event
|
|
194
|
+
});
|
|
195
|
+
sources.set(row.module, rows);
|
|
196
|
+
}
|
|
197
|
+
if (sources.size === 0) return void 0;
|
|
198
|
+
const modules = [];
|
|
199
|
+
for (const [source, rows] of sources) {
|
|
200
|
+
const extension = node_path.default.extname(source);
|
|
201
|
+
try {
|
|
202
|
+
let artifact;
|
|
203
|
+
if (TYPESCRIPT_EXTENSIONS.has(extension)) artifact = await compileHookSource(source, options.directory);
|
|
204
|
+
else if (BUILT_EXTENSIONS.has(extension)) artifact = await options.artifactFor(source);
|
|
205
|
+
else throw new Error("a hook module must be TypeScript (.ts, .mts, .cts) or JavaScript (.mjs, .js, .cjs).");
|
|
206
|
+
modules.push({
|
|
207
|
+
source,
|
|
208
|
+
artifact,
|
|
209
|
+
rows
|
|
210
|
+
});
|
|
211
|
+
} catch (error) {
|
|
212
|
+
const attribution = rows.map((row) => `${row.registry}: group ${row.groupId}, row ${row.rowId}, event ${row.event}`).join("; ");
|
|
213
|
+
options.onNotice?.(`Hook module ${source} is unavailable (${attribution}): ${error instanceof Error ? error.message : String(error)}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const content = `${JSON.stringify({
|
|
217
|
+
version: 1,
|
|
218
|
+
modules
|
|
219
|
+
}, null, 2)}\n`;
|
|
220
|
+
await node_fs.default.promises.mkdir(options.directory, {
|
|
221
|
+
recursive: true,
|
|
222
|
+
mode: 448
|
|
223
|
+
});
|
|
224
|
+
const file = node_path.default.join(options.directory, `${node_crypto.default.createHash("sha256").update(content).digest("hex")}.json`);
|
|
225
|
+
if (!node_fs.default.existsSync(file)) {
|
|
226
|
+
const staging = `${file}.${String(process.pid)}.${node_crypto.default.randomUUID()}`;
|
|
227
|
+
await node_fs.default.promises.writeFile(staging, content, { mode: 384 });
|
|
228
|
+
await node_fs.default.promises.rename(staging, file);
|
|
229
|
+
}
|
|
230
|
+
return { file };
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
exports.HOOK_MODULES_FILE = HOOK_MODULES_FILE;
|
|
234
|
+
exports.checkoutHookDescriptor = checkoutHookDescriptor;
|
|
235
|
+
exports.validateHookModules = validateHookModules;
|
|
236
|
+
exports.writeLiveHookModules = writeLiveHookModules;
|
|
237
|
+
|
|
238
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["path","fs","isRecord","doomConfigCandidates","parseYaml","optionalPackageEntry","pathToFileURL","isBuiltin","crypto"],"sources":["../../../../src/builders/hooks/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport { isBuiltin } from 'node:module';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { doomConfigCandidates } from '@agimon-ai/po-config/layeredConfig';\nimport type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport { optionalPackageEntry } from '@agimon-ai/po-core/moduleResolution';\nimport { isRecord } from '@agimon-ai/po-core/runtimeJson';\nimport { parse as parseYaml } from 'yaml';\n\nexport const HOOK_MODULES_FILE = 'hook-modules.json';\n\n/** Add checkout source names while retaining the admitted generation's artifact mappings. */\nexport function checkoutHookDescriptor(\n descriptor: { file: string } | undefined,\n sourceRoot: string,\n repoRoot: string,\n directory: string,\n): { file: string } | undefined {\n if (!descriptor || path.resolve(sourceRoot) === path.resolve(repoRoot)) return descriptor;\n const value: unknown = JSON.parse(fs.readFileSync(descriptor.file, 'utf8'));\n if (!isRecord(value) || value.version !== 1 || !Array.isArray(value.modules))\n throw new Error('invalid hook module descriptor');\n const sources = new Set<string>();\n const modules: Array<Record<string, unknown> & { source: string; artifact: string }> = [];\n // Validate all originals first. Never repair an invalid descriptor by dropping entries.\n for (const entry of value.modules) {\n if (\n !isRecord(entry) ||\n typeof entry.source !== 'string' ||\n typeof entry.artifact !== 'string' ||\n !path.isAbsolute(entry.source) ||\n !path.isAbsolute(entry.artifact) ||\n !['.mjs', '.js', '.cjs'].includes(path.extname(entry.artifact)) ||\n sources.has(entry.source)\n )\n throw new Error('invalid hook module artifact mapping');\n sources.add(entry.source);\n modules.push({ ...entry, source: entry.source, artifact: entry.artifact });\n }\n const aliases = [];\n for (const entry of modules) {\n const relative = path.relative(sourceRoot, entry.source);\n if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) continue;\n const source = path.resolve(repoRoot, relative);\n if (sources.has(source)) continue;\n sources.add(source);\n aliases.push({ ...entry, source });\n }\n if (aliases.length === 0) return descriptor;\n const file = path.join(directory, HOOK_MODULES_FILE);\n fs.writeFileSync(file, `${JSON.stringify({ ...value, modules: [...modules, ...aliases] }, null, 2)}\\n`, {\n mode: 0o600,\n });\n return { file };\n}\n\ninterface HookRegistryRow {\n module?: string;\n core: boolean;\n skipInSubagent?: boolean;\n registryId: string;\n groupId: string;\n rowId: string;\n event: string;\n}\n\n/** The optional hook package owns parsing; the CLI only consumes this capability. */\ninterface HookParserModule {\n createHookModules(options: { descriptor?: { file: string } }): {\n validate(rows: readonly HookRegistryRow[]): Promise<void>;\n dispose(): Promise<void>;\n };\n createHookDocumentReader(options: { homeDirectory: string; warn: (message: string) => void }): {\n registry(repoRoot: string): Promise<{\n entries: HookRegistryRow[];\n failure?: { message: string };\n }>;\n };\n}\n\n/** Core plus the union of every mode's selection. An unset selection admits all. */\nexport function requiredHookGroups(config: MajorModesConfig): Set<string> | undefined {\n const groups = new Set<string>();\n for (const mode of Object.values(config.majorMode)) {\n const layers = mode.layers.map((name) => config.layers[name]);\n if (layers.length === 0 || layers.some((layer) => layer?.hookGroups === undefined)) return undefined;\n for (const layer of layers) for (const group of layer.hookGroups ?? []) groups.add(group);\n }\n return groups;\n}\n\nasync function hookParser(options: {\n repoRoot: string;\n configRoot?: string;\n homeDirectory: string;\n}): Promise<HookParserModule | undefined> {\n const candidates = doomConfigCandidates('hooks.yaml', options.repoRoot, options.homeDirectory);\n // Command-only registries predate module compilation and do not require the package.\n // This is discovery only. The public parser still owns validation and attribution.\n const hasModuleRows = candidates.some((candidate) => {\n if (!fs.existsSync(candidate.filePath)) return false;\n const document: unknown = parseYaml(fs.readFileSync(candidate.filePath, 'utf8'));\n if (!isRecord(document) || !isRecord(document.groups)) return false;\n return Object.values(document.groups).some(\n (group) =>\n isRecord(group) &&\n Array.isArray(group.hooks) &&\n group.hooks.some((row: unknown) => isRecord(row) && isRecord(row.pi) && 'module' in row.pi),\n );\n });\n const parserEntry =\n optionalPackageEntry('@agimon-ai/po-hook', pathToFileURL(path.join(options.repoRoot, 'package.json')).href) ??\n (options.configRoot && options.configRoot !== options.repoRoot\n ? optionalPackageEntry('@agimon-ai/po-hook', pathToFileURL(path.join(options.configRoot, 'package.json')).href)\n : undefined) ??\n optionalPackageEntry('@agimon-ai/po-hook', import.meta.url);\n if (hasModuleRows && !parserEntry)\n throw new Error(\n 'Hook module rows require @agimon-ai/po-hook. Install it in the repository or select a layer that provides it, then run po sync.',\n );\n return hasModuleRows && parserEntry\n ? ((await import(pathToFileURL(parserEntry).href)) as HookParserModule)\n : undefined;\n}\n\n/** Validate the selected compiled hooks without importing repository code. */\nexport async function validateHookModules(options: {\n repoRoot: string;\n configRoot?: string;\n homeDirectory: string;\n hookGroups?: readonly string[];\n descriptor?: { file: string };\n isSubagent?: boolean;\n}): Promise<boolean> {\n const parser = await hookParser(options);\n if (!parser) return false;\n const read = await parser\n .createHookDocumentReader({ homeDirectory: options.homeDirectory, warn: () => undefined })\n .registry(options.repoRoot);\n if (read.failure) throw new Error(read.failure.message);\n const allowed = options.hookGroups === undefined ? undefined : new Set(options.hookGroups);\n const rows = read.entries\n .filter((row) => row.core || !allowed || allowed.has(row.groupId))\n .filter((row) => !(options.isSubagent && row.skipInSubagent));\n const modules = parser.createHookModules({ descriptor: options.descriptor });\n try {\n await modules.validate(rows);\n return rows.some((row) => row.module !== undefined);\n } finally {\n await modules.dispose();\n }\n}\n\n/** Built JavaScript loads in place or from a package snapshot; TypeScript is compiled first. */\nconst BUILT_EXTENSIONS = new Set(['.mjs', '.js', '.cjs']);\nconst TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.mts', '.cts']);\n/** Pi's shared runtime must resolve to the copy this harness runs, as the sync compiler pinned it. */\nconst HOSTED_PACKAGES = new Set(['@earendil-works/pi-coding-agent', '@earendil-works/pi-tui', '@earendil-works/pi-ai']);\n\n/**\n * Compiles a TypeScript hook into one ESM file named by the hash of its bytes.\n *\n * Relative imports are bundled, so editing any of them yields a new file and URL. Bare\n * imports are left external as the absolute file their importer resolves, or Pi's copy\n * for hosted packages, so the artifact's location does not change what they load. A bare\n * import that resolves to TypeScript is bundled, because Node does not strip it under\n * node_modules. `import.meta.url` keeps naming each original source file.\n */\nasync function compileHookSource(source: string, directory: string): Promise<string> {\n const { rolldown } = await import('rolldown');\n const build = await rolldown({\n input: source,\n platform: 'node',\n onLog(_level, log, handler) {\n if (log.code === 'UNRESOLVED_IMPORT') handler('error', log);\n },\n plugins: [\n {\n name: 'po-hook-externals',\n async resolveId(specifier, importer, extra) {\n if (!importer || specifier.startsWith('.') || path.isAbsolute(specifier)) return null;\n if (isBuiltin(specifier)) return { id: specifier, external: true };\n const root = specifier.split('/', specifier.startsWith('@') ? 2 : 1).join('/');\n const hosted = HOSTED_PACKAGES.has(root) ? optionalPackageEntry(specifier, import.meta.url) : undefined;\n const resolved = hosted ?? (await this.resolve(specifier, importer, { ...extra, skipSelf: true }))?.id;\n if (resolved === undefined || !path.isAbsolute(resolved)) return null;\n if (TYPESCRIPT_EXTENSIONS.has(path.extname(resolved))) return resolved;\n return { id: pathToFileURL(resolved).href, external: true };\n },\n transform(code, id) {\n if (!path.isAbsolute(id) || !code.includes('import.meta.url')) return null;\n return code.replaceAll(/\\bimport\\.meta\\.url\\b/gu, JSON.stringify(pathToFileURL(id).href));\n },\n },\n ],\n });\n let code: string;\n try {\n const generated = await build.generate({ format: 'esm', sourcemap: false, codeSplitting: false });\n code = generated.output[0].code;\n } finally {\n await build.close();\n }\n await fs.promises.mkdir(directory, { recursive: true, mode: 0o700 });\n const file = path.join(directory, `${crypto.createHash('sha256').update(code).digest('hex')}.mjs`);\n if (!fs.existsSync(file)) {\n const staging = `${file}.${String(process.pid)}.${crypto.randomUUID()}`;\n await fs.promises.writeFile(staging, code, { mode: 0o600 });\n await fs.promises.rename(staging, file);\n }\n return file;\n}\n\n/**\n * Writes a hook module descriptor from the live registry.\n *\n * A built JavaScript source maps through `artifactFor` (the server's content-addressed\n * package paths); a TypeScript source is compiled into `directory`. A source that cannot\n * be prepared is left out with a notice naming its rows, so validation fails closed for\n * them. The descriptor is named by its content, so equal registries share one file.\n * Returns undefined when no registry row names a module.\n */\nexport async function writeLiveHookModules(options: {\n repoRoot: string;\n homeDirectory: string;\n directory: string;\n artifactFor: (source: string) => Promise<string>;\n onNotice?: (message: string) => void;\n}): Promise<{ file: string } | undefined> {\n const parser = await hookParser(options);\n if (!parser) return undefined;\n const read = await parser\n .createHookDocumentReader({ homeDirectory: options.homeDirectory, warn: () => undefined })\n .registry(options.repoRoot);\n if (read.failure) throw new Error(read.failure.message);\n const sources = new Map<string, Array<{ registry: string; groupId: string; rowId: string; event: string }>>();\n for (const row of read.entries) {\n if (!row.module) continue;\n const rows = sources.get(row.module) ?? [];\n rows.push({ registry: row.registryId, groupId: row.groupId, rowId: row.rowId, event: row.event });\n sources.set(row.module, rows);\n }\n if (sources.size === 0) return undefined;\n const modules = [];\n for (const [source, rows] of sources) {\n const extension = path.extname(source);\n try {\n let artifact: string;\n if (TYPESCRIPT_EXTENSIONS.has(extension)) artifact = await compileHookSource(source, options.directory);\n else if (BUILT_EXTENSIONS.has(extension)) artifact = await options.artifactFor(source);\n else throw new Error('a hook module must be TypeScript (.ts, .mts, .cts) or JavaScript (.mjs, .js, .cjs).');\n modules.push({ source, artifact, rows });\n } catch (error) {\n // Left out of the descriptor, so validation fails closed for its rows.\n const attribution = rows\n .map((row) => `${row.registry}: group ${row.groupId}, row ${row.rowId}, event ${row.event}`)\n .join('; ');\n options.onNotice?.(\n `Hook module ${source} is unavailable (${attribution}): ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n const content = `${JSON.stringify({ version: 1, modules }, null, 2)}\\n`;\n await fs.promises.mkdir(options.directory, { recursive: true, mode: 0o700 });\n const file = path.join(options.directory, `${crypto.createHash('sha256').update(content).digest('hex')}.json`);\n if (!fs.existsSync(file)) {\n const staging = `${file}.${String(process.pid)}.${crypto.randomUUID()}`;\n await fs.promises.writeFile(staging, content, { mode: 0o600 });\n await fs.promises.rename(staging, file);\n }\n return { file };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { isBuiltin } from "node:module";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { isRecord } from "@agimon-ai/po-core/runtimeJson";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { optionalPackageEntry } from "@agimon-ai/po-core/moduleResolution";
|
|
7
|
+
import crypto from "node:crypto";
|
|
8
|
+
import { doomConfigCandidates } from "@agimon-ai/po-config/layeredConfig";
|
|
9
|
+
import { parse } from "yaml";
|
|
10
|
+
//#region src/builders/hooks/index.ts
|
|
11
|
+
const HOOK_MODULES_FILE = "hook-modules.json";
|
|
12
|
+
/** Add checkout source names while retaining the admitted generation's artifact mappings. */
|
|
13
|
+
function checkoutHookDescriptor(descriptor, sourceRoot, repoRoot, directory) {
|
|
14
|
+
if (!descriptor || path.resolve(sourceRoot) === path.resolve(repoRoot)) return descriptor;
|
|
15
|
+
const value = JSON.parse(fs.readFileSync(descriptor.file, "utf8"));
|
|
16
|
+
if (!isRecord(value) || value.version !== 1 || !Array.isArray(value.modules)) throw new Error("invalid hook module descriptor");
|
|
17
|
+
const sources = /* @__PURE__ */ new Set();
|
|
18
|
+
const modules = [];
|
|
19
|
+
for (const entry of value.modules) {
|
|
20
|
+
if (!isRecord(entry) || typeof entry.source !== "string" || typeof entry.artifact !== "string" || !path.isAbsolute(entry.source) || !path.isAbsolute(entry.artifact) || ![
|
|
21
|
+
".mjs",
|
|
22
|
+
".js",
|
|
23
|
+
".cjs"
|
|
24
|
+
].includes(path.extname(entry.artifact)) || sources.has(entry.source)) throw new Error("invalid hook module artifact mapping");
|
|
25
|
+
sources.add(entry.source);
|
|
26
|
+
modules.push({
|
|
27
|
+
...entry,
|
|
28
|
+
source: entry.source,
|
|
29
|
+
artifact: entry.artifact
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const aliases = [];
|
|
33
|
+
for (const entry of modules) {
|
|
34
|
+
const relative = path.relative(sourceRoot, entry.source);
|
|
35
|
+
if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) continue;
|
|
36
|
+
const source = path.resolve(repoRoot, relative);
|
|
37
|
+
if (sources.has(source)) continue;
|
|
38
|
+
sources.add(source);
|
|
39
|
+
aliases.push({
|
|
40
|
+
...entry,
|
|
41
|
+
source
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (aliases.length === 0) return descriptor;
|
|
45
|
+
const file = path.join(directory, HOOK_MODULES_FILE);
|
|
46
|
+
fs.writeFileSync(file, `${JSON.stringify({
|
|
47
|
+
...value,
|
|
48
|
+
modules: [...modules, ...aliases]
|
|
49
|
+
}, null, 2)}\n`, { mode: 384 });
|
|
50
|
+
return { file };
|
|
51
|
+
}
|
|
52
|
+
async function hookParser(options) {
|
|
53
|
+
const hasModuleRows = doomConfigCandidates("hooks.yaml", options.repoRoot, options.homeDirectory).some((candidate) => {
|
|
54
|
+
if (!fs.existsSync(candidate.filePath)) return false;
|
|
55
|
+
const document = parse(fs.readFileSync(candidate.filePath, "utf8"));
|
|
56
|
+
if (!isRecord(document) || !isRecord(document.groups)) return false;
|
|
57
|
+
return Object.values(document.groups).some((group) => isRecord(group) && Array.isArray(group.hooks) && group.hooks.some((row) => isRecord(row) && isRecord(row.pi) && "module" in row.pi));
|
|
58
|
+
});
|
|
59
|
+
const parserEntry = optionalPackageEntry("@agimon-ai/po-hook", pathToFileURL(path.join(options.repoRoot, "package.json")).href) ?? (options.configRoot && options.configRoot !== options.repoRoot ? optionalPackageEntry("@agimon-ai/po-hook", pathToFileURL(path.join(options.configRoot, "package.json")).href) : void 0) ?? optionalPackageEntry("@agimon-ai/po-hook", import.meta.url);
|
|
60
|
+
if (hasModuleRows && !parserEntry) throw new Error("Hook module rows require @agimon-ai/po-hook. Install it in the repository or select a layer that provides it, then run po sync.");
|
|
61
|
+
return hasModuleRows && parserEntry ? await import(pathToFileURL(parserEntry).href) : void 0;
|
|
62
|
+
}
|
|
63
|
+
/** Validate the selected compiled hooks without importing repository code. */
|
|
64
|
+
async function validateHookModules(options) {
|
|
65
|
+
const parser = await hookParser(options);
|
|
66
|
+
if (!parser) return false;
|
|
67
|
+
const read = await parser.createHookDocumentReader({
|
|
68
|
+
homeDirectory: options.homeDirectory,
|
|
69
|
+
warn: () => void 0
|
|
70
|
+
}).registry(options.repoRoot);
|
|
71
|
+
if (read.failure) throw new Error(read.failure.message);
|
|
72
|
+
const allowed = options.hookGroups === void 0 ? void 0 : new Set(options.hookGroups);
|
|
73
|
+
const rows = read.entries.filter((row) => row.core || !allowed || allowed.has(row.groupId)).filter((row) => !(options.isSubagent && row.skipInSubagent));
|
|
74
|
+
const modules = parser.createHookModules({ descriptor: options.descriptor });
|
|
75
|
+
try {
|
|
76
|
+
await modules.validate(rows);
|
|
77
|
+
return rows.some((row) => row.module !== void 0);
|
|
78
|
+
} finally {
|
|
79
|
+
await modules.dispose();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Built JavaScript loads in place or from a package snapshot; TypeScript is compiled first. */
|
|
83
|
+
const BUILT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
84
|
+
".mjs",
|
|
85
|
+
".js",
|
|
86
|
+
".cjs"
|
|
87
|
+
]);
|
|
88
|
+
const TYPESCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
89
|
+
".ts",
|
|
90
|
+
".mts",
|
|
91
|
+
".cts"
|
|
92
|
+
]);
|
|
93
|
+
/** Pi's shared runtime must resolve to the copy this harness runs, as the sync compiler pinned it. */
|
|
94
|
+
const HOSTED_PACKAGES = /* @__PURE__ */ new Set([
|
|
95
|
+
"@earendil-works/pi-coding-agent",
|
|
96
|
+
"@earendil-works/pi-tui",
|
|
97
|
+
"@earendil-works/pi-ai"
|
|
98
|
+
]);
|
|
99
|
+
/**
|
|
100
|
+
* Compiles a TypeScript hook into one ESM file named by the hash of its bytes.
|
|
101
|
+
*
|
|
102
|
+
* Relative imports are bundled, so editing any of them yields a new file and URL. Bare
|
|
103
|
+
* imports are left external as the absolute file their importer resolves, or Pi's copy
|
|
104
|
+
* for hosted packages, so the artifact's location does not change what they load. A bare
|
|
105
|
+
* import that resolves to TypeScript is bundled, because Node does not strip it under
|
|
106
|
+
* node_modules. `import.meta.url` keeps naming each original source file.
|
|
107
|
+
*/
|
|
108
|
+
async function compileHookSource(source, directory) {
|
|
109
|
+
const { rolldown } = await import("rolldown");
|
|
110
|
+
const build = await rolldown({
|
|
111
|
+
input: source,
|
|
112
|
+
platform: "node",
|
|
113
|
+
onLog(_level, log, handler) {
|
|
114
|
+
if (log.code === "UNRESOLVED_IMPORT") handler("error", log);
|
|
115
|
+
},
|
|
116
|
+
plugins: [{
|
|
117
|
+
name: "po-hook-externals",
|
|
118
|
+
async resolveId(specifier, importer, extra) {
|
|
119
|
+
if (!importer || specifier.startsWith(".") || path.isAbsolute(specifier)) return null;
|
|
120
|
+
if (isBuiltin(specifier)) return {
|
|
121
|
+
id: specifier,
|
|
122
|
+
external: true
|
|
123
|
+
};
|
|
124
|
+
const root = specifier.split("/", specifier.startsWith("@") ? 2 : 1).join("/");
|
|
125
|
+
const resolved = (HOSTED_PACKAGES.has(root) ? optionalPackageEntry(specifier, import.meta.url) : void 0) ?? (await this.resolve(specifier, importer, {
|
|
126
|
+
...extra,
|
|
127
|
+
skipSelf: true
|
|
128
|
+
}))?.id;
|
|
129
|
+
if (resolved === void 0 || !path.isAbsolute(resolved)) return null;
|
|
130
|
+
if (TYPESCRIPT_EXTENSIONS.has(path.extname(resolved))) return resolved;
|
|
131
|
+
return {
|
|
132
|
+
id: pathToFileURL(resolved).href,
|
|
133
|
+
external: true
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
transform(code, id) {
|
|
137
|
+
if (!path.isAbsolute(id) || !code.includes("import.meta.url")) return null;
|
|
138
|
+
return code.replaceAll(/\bimport\.meta\.url\b/gu, JSON.stringify(pathToFileURL(id).href));
|
|
139
|
+
}
|
|
140
|
+
}]
|
|
141
|
+
});
|
|
142
|
+
let code;
|
|
143
|
+
try {
|
|
144
|
+
code = (await build.generate({
|
|
145
|
+
format: "esm",
|
|
146
|
+
sourcemap: false,
|
|
147
|
+
codeSplitting: false
|
|
148
|
+
})).output[0].code;
|
|
149
|
+
} finally {
|
|
150
|
+
await build.close();
|
|
151
|
+
}
|
|
152
|
+
await fs.promises.mkdir(directory, {
|
|
153
|
+
recursive: true,
|
|
154
|
+
mode: 448
|
|
155
|
+
});
|
|
156
|
+
const file = path.join(directory, `${crypto.createHash("sha256").update(code).digest("hex")}.mjs`);
|
|
157
|
+
if (!fs.existsSync(file)) {
|
|
158
|
+
const staging = `${file}.${String(process.pid)}.${crypto.randomUUID()}`;
|
|
159
|
+
await fs.promises.writeFile(staging, code, { mode: 384 });
|
|
160
|
+
await fs.promises.rename(staging, file);
|
|
161
|
+
}
|
|
162
|
+
return file;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Writes a hook module descriptor from the live registry.
|
|
166
|
+
*
|
|
167
|
+
* A built JavaScript source maps through `artifactFor` (the server's content-addressed
|
|
168
|
+
* package paths); a TypeScript source is compiled into `directory`. A source that cannot
|
|
169
|
+
* be prepared is left out with a notice naming its rows, so validation fails closed for
|
|
170
|
+
* them. The descriptor is named by its content, so equal registries share one file.
|
|
171
|
+
* Returns undefined when no registry row names a module.
|
|
172
|
+
*/
|
|
173
|
+
async function writeLiveHookModules(options) {
|
|
174
|
+
const parser = await hookParser(options);
|
|
175
|
+
if (!parser) return void 0;
|
|
176
|
+
const read = await parser.createHookDocumentReader({
|
|
177
|
+
homeDirectory: options.homeDirectory,
|
|
178
|
+
warn: () => void 0
|
|
179
|
+
}).registry(options.repoRoot);
|
|
180
|
+
if (read.failure) throw new Error(read.failure.message);
|
|
181
|
+
const sources = /* @__PURE__ */ new Map();
|
|
182
|
+
for (const row of read.entries) {
|
|
183
|
+
if (!row.module) continue;
|
|
184
|
+
const rows = sources.get(row.module) ?? [];
|
|
185
|
+
rows.push({
|
|
186
|
+
registry: row.registryId,
|
|
187
|
+
groupId: row.groupId,
|
|
188
|
+
rowId: row.rowId,
|
|
189
|
+
event: row.event
|
|
190
|
+
});
|
|
191
|
+
sources.set(row.module, rows);
|
|
192
|
+
}
|
|
193
|
+
if (sources.size === 0) return void 0;
|
|
194
|
+
const modules = [];
|
|
195
|
+
for (const [source, rows] of sources) {
|
|
196
|
+
const extension = path.extname(source);
|
|
197
|
+
try {
|
|
198
|
+
let artifact;
|
|
199
|
+
if (TYPESCRIPT_EXTENSIONS.has(extension)) artifact = await compileHookSource(source, options.directory);
|
|
200
|
+
else if (BUILT_EXTENSIONS.has(extension)) artifact = await options.artifactFor(source);
|
|
201
|
+
else throw new Error("a hook module must be TypeScript (.ts, .mts, .cts) or JavaScript (.mjs, .js, .cjs).");
|
|
202
|
+
modules.push({
|
|
203
|
+
source,
|
|
204
|
+
artifact,
|
|
205
|
+
rows
|
|
206
|
+
});
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const attribution = rows.map((row) => `${row.registry}: group ${row.groupId}, row ${row.rowId}, event ${row.event}`).join("; ");
|
|
209
|
+
options.onNotice?.(`Hook module ${source} is unavailable (${attribution}): ${error instanceof Error ? error.message : String(error)}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const content = `${JSON.stringify({
|
|
213
|
+
version: 1,
|
|
214
|
+
modules
|
|
215
|
+
}, null, 2)}\n`;
|
|
216
|
+
await fs.promises.mkdir(options.directory, {
|
|
217
|
+
recursive: true,
|
|
218
|
+
mode: 448
|
|
219
|
+
});
|
|
220
|
+
const file = path.join(options.directory, `${crypto.createHash("sha256").update(content).digest("hex")}.json`);
|
|
221
|
+
if (!fs.existsSync(file)) {
|
|
222
|
+
const staging = `${file}.${String(process.pid)}.${crypto.randomUUID()}`;
|
|
223
|
+
await fs.promises.writeFile(staging, content, { mode: 384 });
|
|
224
|
+
await fs.promises.rename(staging, file);
|
|
225
|
+
}
|
|
226
|
+
return { file };
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
export { HOOK_MODULES_FILE, checkoutHookDescriptor, validateHookModules, writeLiveHookModules };
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["parseYaml"],"sources":["../../../../src/builders/hooks/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport { isBuiltin } from 'node:module';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { doomConfigCandidates } from '@agimon-ai/po-config/layeredConfig';\nimport type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport { optionalPackageEntry } from '@agimon-ai/po-core/moduleResolution';\nimport { isRecord } from '@agimon-ai/po-core/runtimeJson';\nimport { parse as parseYaml } from 'yaml';\n\nexport const HOOK_MODULES_FILE = 'hook-modules.json';\n\n/** Add checkout source names while retaining the admitted generation's artifact mappings. */\nexport function checkoutHookDescriptor(\n descriptor: { file: string } | undefined,\n sourceRoot: string,\n repoRoot: string,\n directory: string,\n): { file: string } | undefined {\n if (!descriptor || path.resolve(sourceRoot) === path.resolve(repoRoot)) return descriptor;\n const value: unknown = JSON.parse(fs.readFileSync(descriptor.file, 'utf8'));\n if (!isRecord(value) || value.version !== 1 || !Array.isArray(value.modules))\n throw new Error('invalid hook module descriptor');\n const sources = new Set<string>();\n const modules: Array<Record<string, unknown> & { source: string; artifact: string }> = [];\n // Validate all originals first. Never repair an invalid descriptor by dropping entries.\n for (const entry of value.modules) {\n if (\n !isRecord(entry) ||\n typeof entry.source !== 'string' ||\n typeof entry.artifact !== 'string' ||\n !path.isAbsolute(entry.source) ||\n !path.isAbsolute(entry.artifact) ||\n !['.mjs', '.js', '.cjs'].includes(path.extname(entry.artifact)) ||\n sources.has(entry.source)\n )\n throw new Error('invalid hook module artifact mapping');\n sources.add(entry.source);\n modules.push({ ...entry, source: entry.source, artifact: entry.artifact });\n }\n const aliases = [];\n for (const entry of modules) {\n const relative = path.relative(sourceRoot, entry.source);\n if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) continue;\n const source = path.resolve(repoRoot, relative);\n if (sources.has(source)) continue;\n sources.add(source);\n aliases.push({ ...entry, source });\n }\n if (aliases.length === 0) return descriptor;\n const file = path.join(directory, HOOK_MODULES_FILE);\n fs.writeFileSync(file, `${JSON.stringify({ ...value, modules: [...modules, ...aliases] }, null, 2)}\\n`, {\n mode: 0o600,\n });\n return { file };\n}\n\ninterface HookRegistryRow {\n module?: string;\n core: boolean;\n skipInSubagent?: boolean;\n registryId: string;\n groupId: string;\n rowId: string;\n event: string;\n}\n\n/** The optional hook package owns parsing; the CLI only consumes this capability. */\ninterface HookParserModule {\n createHookModules(options: { descriptor?: { file: string } }): {\n validate(rows: readonly HookRegistryRow[]): Promise<void>;\n dispose(): Promise<void>;\n };\n createHookDocumentReader(options: { homeDirectory: string; warn: (message: string) => void }): {\n registry(repoRoot: string): Promise<{\n entries: HookRegistryRow[];\n failure?: { message: string };\n }>;\n };\n}\n\n/** Core plus the union of every mode's selection. An unset selection admits all. */\nexport function requiredHookGroups(config: MajorModesConfig): Set<string> | undefined {\n const groups = new Set<string>();\n for (const mode of Object.values(config.majorMode)) {\n const layers = mode.layers.map((name) => config.layers[name]);\n if (layers.length === 0 || layers.some((layer) => layer?.hookGroups === undefined)) return undefined;\n for (const layer of layers) for (const group of layer.hookGroups ?? []) groups.add(group);\n }\n return groups;\n}\n\nasync function hookParser(options: {\n repoRoot: string;\n configRoot?: string;\n homeDirectory: string;\n}): Promise<HookParserModule | undefined> {\n const candidates = doomConfigCandidates('hooks.yaml', options.repoRoot, options.homeDirectory);\n // Command-only registries predate module compilation and do not require the package.\n // This is discovery only. The public parser still owns validation and attribution.\n const hasModuleRows = candidates.some((candidate) => {\n if (!fs.existsSync(candidate.filePath)) return false;\n const document: unknown = parseYaml(fs.readFileSync(candidate.filePath, 'utf8'));\n if (!isRecord(document) || !isRecord(document.groups)) return false;\n return Object.values(document.groups).some(\n (group) =>\n isRecord(group) &&\n Array.isArray(group.hooks) &&\n group.hooks.some((row: unknown) => isRecord(row) && isRecord(row.pi) && 'module' in row.pi),\n );\n });\n const parserEntry =\n optionalPackageEntry('@agimon-ai/po-hook', pathToFileURL(path.join(options.repoRoot, 'package.json')).href) ??\n (options.configRoot && options.configRoot !== options.repoRoot\n ? optionalPackageEntry('@agimon-ai/po-hook', pathToFileURL(path.join(options.configRoot, 'package.json')).href)\n : undefined) ??\n optionalPackageEntry('@agimon-ai/po-hook', import.meta.url);\n if (hasModuleRows && !parserEntry)\n throw new Error(\n 'Hook module rows require @agimon-ai/po-hook. Install it in the repository or select a layer that provides it, then run po sync.',\n );\n return hasModuleRows && parserEntry\n ? ((await import(pathToFileURL(parserEntry).href)) as HookParserModule)\n : undefined;\n}\n\n/** Validate the selected compiled hooks without importing repository code. */\nexport async function validateHookModules(options: {\n repoRoot: string;\n configRoot?: string;\n homeDirectory: string;\n hookGroups?: readonly string[];\n descriptor?: { file: string };\n isSubagent?: boolean;\n}): Promise<boolean> {\n const parser = await hookParser(options);\n if (!parser) return false;\n const read = await parser\n .createHookDocumentReader({ homeDirectory: options.homeDirectory, warn: () => undefined })\n .registry(options.repoRoot);\n if (read.failure) throw new Error(read.failure.message);\n const allowed = options.hookGroups === undefined ? undefined : new Set(options.hookGroups);\n const rows = read.entries\n .filter((row) => row.core || !allowed || allowed.has(row.groupId))\n .filter((row) => !(options.isSubagent && row.skipInSubagent));\n const modules = parser.createHookModules({ descriptor: options.descriptor });\n try {\n await modules.validate(rows);\n return rows.some((row) => row.module !== undefined);\n } finally {\n await modules.dispose();\n }\n}\n\n/** Built JavaScript loads in place or from a package snapshot; TypeScript is compiled first. */\nconst BUILT_EXTENSIONS = new Set(['.mjs', '.js', '.cjs']);\nconst TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.mts', '.cts']);\n/** Pi's shared runtime must resolve to the copy this harness runs, as the sync compiler pinned it. */\nconst HOSTED_PACKAGES = new Set(['@earendil-works/pi-coding-agent', '@earendil-works/pi-tui', '@earendil-works/pi-ai']);\n\n/**\n * Compiles a TypeScript hook into one ESM file named by the hash of its bytes.\n *\n * Relative imports are bundled, so editing any of them yields a new file and URL. Bare\n * imports are left external as the absolute file their importer resolves, or Pi's copy\n * for hosted packages, so the artifact's location does not change what they load. A bare\n * import that resolves to TypeScript is bundled, because Node does not strip it under\n * node_modules. `import.meta.url` keeps naming each original source file.\n */\nasync function compileHookSource(source: string, directory: string): Promise<string> {\n const { rolldown } = await import('rolldown');\n const build = await rolldown({\n input: source,\n platform: 'node',\n onLog(_level, log, handler) {\n if (log.code === 'UNRESOLVED_IMPORT') handler('error', log);\n },\n plugins: [\n {\n name: 'po-hook-externals',\n async resolveId(specifier, importer, extra) {\n if (!importer || specifier.startsWith('.') || path.isAbsolute(specifier)) return null;\n if (isBuiltin(specifier)) return { id: specifier, external: true };\n const root = specifier.split('/', specifier.startsWith('@') ? 2 : 1).join('/');\n const hosted = HOSTED_PACKAGES.has(root) ? optionalPackageEntry(specifier, import.meta.url) : undefined;\n const resolved = hosted ?? (await this.resolve(specifier, importer, { ...extra, skipSelf: true }))?.id;\n if (resolved === undefined || !path.isAbsolute(resolved)) return null;\n if (TYPESCRIPT_EXTENSIONS.has(path.extname(resolved))) return resolved;\n return { id: pathToFileURL(resolved).href, external: true };\n },\n transform(code, id) {\n if (!path.isAbsolute(id) || !code.includes('import.meta.url')) return null;\n return code.replaceAll(/\\bimport\\.meta\\.url\\b/gu, JSON.stringify(pathToFileURL(id).href));\n },\n },\n ],\n });\n let code: string;\n try {\n const generated = await build.generate({ format: 'esm', sourcemap: false, codeSplitting: false });\n code = generated.output[0].code;\n } finally {\n await build.close();\n }\n await fs.promises.mkdir(directory, { recursive: true, mode: 0o700 });\n const file = path.join(directory, `${crypto.createHash('sha256').update(code).digest('hex')}.mjs`);\n if (!fs.existsSync(file)) {\n const staging = `${file}.${String(process.pid)}.${crypto.randomUUID()}`;\n await fs.promises.writeFile(staging, code, { mode: 0o600 });\n await fs.promises.rename(staging, file);\n }\n return file;\n}\n\n/**\n * Writes a hook module descriptor from the live registry.\n *\n * A built JavaScript source maps through `artifactFor` (the server's content-addressed\n * package paths); a TypeScript source is compiled into `directory`. A source that cannot\n * be prepared is left out with a notice naming its rows, so validation fails closed for\n * them. The descriptor is named by its content, so equal registries share one file.\n * Returns undefined when no registry row names a module.\n */\nexport async function writeLiveHookModules(options: {\n repoRoot: string;\n homeDirectory: string;\n directory: string;\n artifactFor: (source: string) => Promise<string>;\n onNotice?: (message: string) => void;\n}): Promise<{ file: string } | undefined> {\n const parser = await hookParser(options);\n if (!parser) return undefined;\n const read = await parser\n .createHookDocumentReader({ homeDirectory: options.homeDirectory, warn: () => undefined })\n .registry(options.repoRoot);\n if (read.failure) throw new Error(read.failure.message);\n const sources = new Map<string, Array<{ registry: string; groupId: string; rowId: string; event: string }>>();\n for (const row of read.entries) {\n if (!row.module) continue;\n const rows = sources.get(row.module) ?? [];\n rows.push({ registry: row.registryId, groupId: row.groupId, rowId: row.rowId, event: row.event });\n sources.set(row.module, rows);\n }\n if (sources.size === 0) return undefined;\n const modules = [];\n for (const [source, rows] of sources) {\n const extension = path.extname(source);\n try {\n let artifact: string;\n if (TYPESCRIPT_EXTENSIONS.has(extension)) artifact = await compileHookSource(source, options.directory);\n else if (BUILT_EXTENSIONS.has(extension)) artifact = await options.artifactFor(source);\n else throw new Error('a hook module must be TypeScript (.ts, .mts, .cts) or JavaScript (.mjs, .js, .cjs).');\n modules.push({ source, artifact, rows });\n } catch (error) {\n // Left out of the descriptor, so validation fails closed for its rows.\n const attribution = rows\n .map((row) => `${row.registry}: group ${row.groupId}, row ${row.rowId}, event ${row.event}`)\n .join('; ');\n options.onNotice?.(\n `Hook module ${source} is unavailable (${attribution}): ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n const content = `${JSON.stringify({ version: 1, modules }, null, 2)}\\n`;\n await fs.promises.mkdir(options.directory, { recursive: true, mode: 0o700 });\n const file = path.join(options.directory, `${crypto.createHash('sha256').update(content).digest('hex')}.json`);\n if (!fs.existsSync(file)) {\n const staging = `${file}.${String(process.pid)}.${crypto.randomUUID()}`;\n await fs.promises.writeFile(staging, content, { mode: 0o600 });\n await fs.promises.rename(staging, file);\n }\n return { file };\n}\n"],"mappings":"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"}
|