@dyyz1993/create-agent 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -0
- package/src/__tests__/cli.test.ts +85 -0
- package/src/__tests__/copy.test.ts +168 -0
- package/src/__tests__/templates.test.ts +87 -0
- package/src/cli.ts +65 -0
- package/src/commands/create.ts +49 -0
- package/src/commands/list.ts +12 -0
- package/src/commands/status.ts +85 -0
- package/src/commands/workspace.ts +129 -0
- package/src/lib/copy.ts +285 -0
- package/src/lib/templates.ts +57 -0
- package/src/lib/types.ts +6 -0
- package/templates/agent/.env.example +7 -0
- package/templates/agent/LICENSE +21 -0
- package/templates/agent/README.md +87 -0
- package/templates/agent/bun.lock +1279 -0
- package/templates/agent/electrobun.config.ts +27 -0
- package/templates/agent/eslint.config.mjs +63 -0
- package/templates/agent/llms.txt +24 -0
- package/templates/agent/package-lock.json +3670 -0
- package/templates/agent/package.json +59 -0
- package/templates/agent/postcss.config.js +6 -0
- package/templates/agent/scripts/dev.ts +138 -0
- package/templates/agent/src/__tests__/server-config.test.ts +59 -0
- package/templates/agent/src/bun/index.ts +73 -0
- package/templates/agent/src/gateway/__tests__/ws-handler.test.ts +48 -0
- package/templates/agent/src/gateway/http-routes.ts +1 -0
- package/templates/agent/src/gateway/ipc-transport.ts +68 -0
- package/templates/agent/src/gateway/ws-handler.ts +86 -0
- package/templates/agent/src/mainview/App.tsx +41 -0
- package/templates/agent/src/mainview/__tests__/components/ChatPanel.test.tsx +114 -0
- package/templates/agent/src/mainview/__tests__/components/ExplorerSidebar.test.tsx +141 -0
- package/templates/agent/src/mainview/__tests__/components/MessageBubble.test.tsx +72 -0
- package/templates/agent/src/mainview/__tests__/hooks/use-input-history.test.ts +125 -0
- package/templates/agent/src/mainview/__tests__/hooks/use-rpc-init.test.ts +217 -0
- package/templates/agent/src/mainview/__tests__/hooks/use-sidebar-resize.test.ts +127 -0
- package/templates/agent/src/mainview/__tests__/i18n/i18n.test.ts +48 -0
- package/templates/agent/src/mainview/__tests__/setup.ts +37 -0
- package/templates/agent/src/mainview/__tests__/stores/use-chat-store.test.ts +83 -0
- package/templates/agent/src/mainview/__tests__/stores/use-sidebar-store.test.ts +85 -0
- package/templates/agent/src/mainview/components/activity-bar/ActivityBar.tsx +36 -0
- package/templates/agent/src/mainview/components/activity-bar/MobileTabBar.tsx +36 -0
- package/templates/agent/src/mainview/components/activity-bar/__tests__/ActivityBar.test.tsx +44 -0
- package/templates/agent/src/mainview/components/activity-bar/__tests__/MobileTabBar.test.tsx +44 -0
- package/templates/agent/src/mainview/components/bash/BashPanel.tsx +206 -0
- package/templates/agent/src/mainview/components/bash/__tests__/BashPanel.test.tsx +103 -0
- package/templates/agent/src/mainview/components/chat/ChatPanel.tsx +102 -0
- package/templates/agent/src/mainview/components/chat/MessageBubble.tsx +86 -0
- package/templates/agent/src/mainview/components/common/ErrorBoundary.tsx +58 -0
- package/templates/agent/src/mainview/components/common/LanguageSwitcher.tsx +14 -0
- package/templates/agent/src/mainview/components/common/ThemeToggle.tsx +24 -0
- package/templates/agent/src/mainview/components/common/__tests__/ErrorBoundary.test.tsx +74 -0
- package/templates/agent/src/mainview/components/common/__tests__/LanguageSwitcher.test.tsx +44 -0
- package/templates/agent/src/mainview/components/common/__tests__/ThemeToggle.test.tsx +41 -0
- package/templates/agent/src/mainview/components/debug/DebugPanel.tsx +120 -0
- package/templates/agent/src/mainview/components/debug/__tests__/DebugPanel.test.tsx +102 -0
- package/templates/agent/src/mainview/components/diff/DiffViewerPanel.tsx +106 -0
- package/templates/agent/src/mainview/components/diff/__tests__/DiffViewerPanel.test.tsx +73 -0
- package/templates/agent/src/mainview/components/explorer/ConfirmDialog.tsx +53 -0
- package/templates/agent/src/mainview/components/explorer/ContextMenu.tsx +82 -0
- package/templates/agent/src/mainview/components/explorer/ExplorerSidebar.tsx +221 -0
- package/templates/agent/src/mainview/components/explorer/InlineInput.tsx +55 -0
- package/templates/agent/src/mainview/components/explorer/TreeNodeItem.tsx +121 -0
- package/templates/agent/src/mainview/components/explorer/__tests__/ConfirmDialog.test.tsx +37 -0
- package/templates/agent/src/mainview/components/explorer/__tests__/ContextMenu.test.tsx +49 -0
- package/templates/agent/src/mainview/components/explorer/__tests__/InlineInput.test.tsx +48 -0
- package/templates/agent/src/mainview/components/explorer/__tests__/TreeNodeItem.test.tsx +146 -0
- package/templates/agent/src/mainview/components/feed/FeedPanel.tsx +239 -0
- package/templates/agent/src/mainview/components/feed/__tests__/FeedPanel.test.tsx +108 -0
- package/templates/agent/src/mainview/components/file-preview/FilePreviewOverlay.tsx +56 -0
- package/templates/agent/src/mainview/components/file-preview/VirtualizedCodeView.tsx +99 -0
- package/templates/agent/src/mainview/components/file-preview/__tests__/FilePreviewOverlay.test.tsx +96 -0
- package/templates/agent/src/mainview/components/file-preview/__tests__/VirtualizedCodeView.test.tsx +58 -0
- package/templates/agent/src/mainview/components/git/GitBranchSelector.tsx +98 -0
- package/templates/agent/src/mainview/components/git/GitCommitInput.tsx +60 -0
- package/templates/agent/src/mainview/components/git/GitPanel.tsx +528 -0
- package/templates/agent/src/mainview/components/git/__tests__/GitBranchSelector.test.tsx +76 -0
- package/templates/agent/src/mainview/components/git/__tests__/GitCommitInput.test.tsx +91 -0
- package/templates/agent/src/mainview/components/git/__tests__/GitPanel.test.tsx +174 -0
- package/templates/agent/src/mainview/components/layout/AppLayout.tsx +170 -0
- package/templates/agent/src/mainview/components/layout/__tests__/AppLayout.test.tsx +163 -0
- package/templates/agent/src/mainview/components/rules/RulesPanel.tsx +117 -0
- package/templates/agent/src/mainview/components/rules/__tests__/RulesPanel.test.tsx +91 -0
- package/templates/agent/src/mainview/components/search/SearchPanel.tsx +404 -0
- package/templates/agent/src/mainview/components/search/__tests__/SearchPanel.test.tsx +50 -0
- package/templates/agent/src/mainview/components/sidebar/PinButton.tsx +20 -0
- package/templates/agent/src/mainview/components/sidebar/__tests__/PinButton.test.tsx +48 -0
- package/templates/agent/src/mainview/components/todo/TodoPanel.tsx +141 -0
- package/templates/agent/src/mainview/components/todo/__tests__/TodoPanel.test.tsx +91 -0
- package/templates/agent/src/mainview/global.d.ts +13 -0
- package/templates/agent/src/mainview/hooks/__tests__/use-breakpoint.test.ts +147 -0
- package/templates/agent/src/mainview/hooks/use-breakpoint.ts +34 -0
- package/templates/agent/src/mainview/hooks/use-input-history.ts +84 -0
- package/templates/agent/src/mainview/hooks/use-rpc-init.ts +61 -0
- package/templates/agent/src/mainview/hooks/use-sidebar-resize.ts +40 -0
- package/templates/agent/src/mainview/index.css +61 -0
- package/templates/agent/src/mainview/index.html +12 -0
- package/templates/agent/src/mainview/lib/api-client.ts +192 -0
- package/templates/agent/src/mainview/lib/i18n/index.ts +30 -0
- package/templates/agent/src/mainview/lib/i18n/locales/en.json +157 -0
- package/templates/agent/src/mainview/lib/i18n/locales/zh.json +157 -0
- package/templates/agent/src/mainview/lib/rpc-cache.ts +94 -0
- package/templates/agent/src/mainview/main.tsx +24 -0
- package/templates/agent/src/mainview/stores/__tests__/use-app-store.test.ts +86 -0
- package/templates/agent/src/mainview/stores/__tests__/use-bash-store.test.ts +99 -0
- package/templates/agent/src/mainview/stores/__tests__/use-connection-store.test.ts +26 -0
- package/templates/agent/src/mainview/stores/__tests__/use-explorer-store.test.ts +130 -0
- package/templates/agent/src/mainview/stores/__tests__/use-feed-store.test.ts +132 -0
- package/templates/agent/src/mainview/stores/__tests__/use-git-store.test.ts +161 -0
- package/templates/agent/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
- package/templates/agent/src/mainview/stores/__tests__/use-log-store.test.ts +28 -0
- package/templates/agent/src/mainview/stores/__tests__/use-notification-store.test.ts +102 -0
- package/templates/agent/src/mainview/stores/__tests__/use-rules-store.test.ts +75 -0
- package/templates/agent/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
- package/templates/agent/src/mainview/stores/__tests__/use-todo-store.test.ts +75 -0
- package/templates/agent/src/mainview/stores/message-batcher.ts +25 -0
- package/templates/agent/src/mainview/stores/use-app-store.ts +99 -0
- package/templates/agent/src/mainview/stores/use-bash-store.ts +93 -0
- package/templates/agent/src/mainview/stores/use-chat-store.ts +37 -0
- package/templates/agent/src/mainview/stores/use-connection-store.ts +42 -0
- package/templates/agent/src/mainview/stores/use-explorer-store.ts +320 -0
- package/templates/agent/src/mainview/stores/use-feed-store.ts +129 -0
- package/templates/agent/src/mainview/stores/use-git-store.ts +291 -0
- package/templates/agent/src/mainview/stores/use-locale-store.ts +27 -0
- package/templates/agent/src/mainview/stores/use-log-store.ts +16 -0
- package/templates/agent/src/mainview/stores/use-notification-store.ts +82 -0
- package/templates/agent/src/mainview/stores/use-rules-store.ts +54 -0
- package/templates/agent/src/mainview/stores/use-sidebar-store.ts +99 -0
- package/templates/agent/src/mainview/stores/use-theme-store.ts +46 -0
- package/templates/agent/src/mainview/stores/use-todo-store.ts +54 -0
- package/templates/agent/src/mainview/types/index.ts +33 -0
- package/templates/agent/src/mainview/utils/constants.ts +1 -0
- package/templates/agent/src/mainview/utils/drop-handler.ts +150 -0
- package/templates/agent/src/mainview/utils/file-icon.tsx +24 -0
- package/templates/agent/src/mainview/utils/file-utils.ts +35 -0
- package/templates/agent/src/server-config.ts +43 -0
- package/templates/agent/src/server.ts +89 -0
- package/templates/agent/src/shared/handlers/__tests__/bash-handler.test.ts +135 -0
- package/templates/agent/src/shared/handlers/__tests__/chat-handler.test.ts +77 -0
- package/templates/agent/src/shared/handlers/__tests__/feed-handler.test.ts +108 -0
- package/templates/agent/src/shared/handlers/__tests__/file-handler.test.ts +100 -0
- package/templates/agent/src/shared/handlers/__tests__/system-handler.test.ts +55 -0
- package/templates/agent/src/shared/handlers/__tests__/timer-handler.test.ts +77 -0
- package/templates/agent/src/shared/handlers/bash.ts +89 -0
- package/templates/agent/src/shared/handlers/chat.ts +179 -0
- package/templates/agent/src/shared/handlers/feed.ts +53 -0
- package/templates/agent/src/shared/handlers/file.ts +99 -0
- package/templates/agent/src/shared/handlers/git.ts +263 -0
- package/templates/agent/src/shared/handlers/index.ts +10 -0
- package/templates/agent/src/shared/handlers/rules.ts +45 -0
- package/templates/agent/src/shared/handlers/system.ts +27 -0
- package/templates/agent/src/shared/handlers/timer.ts +34 -0
- package/templates/agent/src/shared/handlers/todo.ts +45 -0
- package/templates/agent/src/shared/lib/__tests__/bash-security.test.ts +125 -0
- package/templates/agent/src/shared/lib/__tests__/logger.test.ts +92 -0
- package/templates/agent/src/shared/lib/__tests__/path-security.test.ts +77 -0
- package/templates/agent/src/shared/lib/bash-security.ts +64 -0
- package/templates/agent/src/shared/lib/logger.ts +130 -0
- package/templates/agent/src/shared/lib/path-security.ts +38 -0
- package/templates/agent/src/shared/lib/port-registry.ts +103 -0
- package/templates/agent/src/shared/modules/bash.ts +19 -0
- package/templates/agent/src/shared/modules/chat.ts +20 -0
- package/templates/agent/src/shared/modules/feed.ts +30 -0
- package/templates/agent/src/shared/modules/file.ts +40 -0
- package/templates/agent/src/shared/modules/git.ts +81 -0
- package/templates/agent/src/shared/modules/rules.ts +25 -0
- package/templates/agent/src/shared/modules/system.ts +8 -0
- package/templates/agent/src/shared/modules/timer.ts +11 -0
- package/templates/agent/src/shared/modules/todo.ts +27 -0
- package/templates/agent/src/shared/register-all-handlers.ts +36 -0
- package/templates/agent/src/shared/rpc-schema.ts +35 -0
- package/templates/agent/tailwind.config.js +15 -0
- package/templates/agent/tsconfig.json +26 -0
- package/templates/agent/vite.config.ts +3 -0
- package/templates/agent/vitest.config.ts +3 -0
- package/templates/chat/.env.example +6 -0
- package/templates/chat/LICENSE +21 -0
- package/templates/chat/README.md +56 -0
- package/templates/chat/bun.lock +1203 -0
- package/templates/chat/electrobun.config.ts +27 -0
- package/templates/chat/eslint.config.mjs +56 -0
- package/templates/chat/llms.txt +24 -0
- package/templates/chat/package-lock.json +3670 -0
- package/templates/chat/package.json +58 -0
- package/templates/chat/postcss.config.js +6 -0
- package/templates/chat/scripts/dev.ts +138 -0
- package/templates/chat/src/__tests__/server-config.test.ts +59 -0
- package/templates/chat/src/bun/index.ts +72 -0
- package/templates/chat/src/gateway/__tests__/ws-handler.test.ts +48 -0
- package/templates/chat/src/gateway/http-routes.ts +1 -0
- package/templates/chat/src/gateway/ipc-transport.ts +68 -0
- package/templates/chat/src/gateway/ws-handler.ts +86 -0
- package/templates/chat/src/mainview/App.tsx +108 -0
- package/templates/chat/src/mainview/__tests__/components/ChatPanel.test.tsx +76 -0
- package/templates/chat/src/mainview/__tests__/components/MessageBubble.test.tsx +48 -0
- package/templates/chat/src/mainview/__tests__/i18n/i18n.test.ts +48 -0
- package/templates/chat/src/mainview/__tests__/setup-verify.test.ts +8 -0
- package/templates/chat/src/mainview/__tests__/setup.ts +37 -0
- package/templates/chat/src/mainview/__tests__/stores/use-app-store.test.ts +46 -0
- package/templates/chat/src/mainview/__tests__/stores/use-chat-store.test.ts +104 -0
- package/templates/chat/src/mainview/__tests__/stores/use-connection-store.test.ts +35 -0
- package/templates/chat/src/mainview/__tests__/stores/use-log-store.test.ts +45 -0
- package/templates/chat/src/mainview/__tests__/stores/use-notification-store.test.ts +102 -0
- package/templates/chat/src/mainview/__tests__/stores/use-sidebar-store.test.ts +89 -0
- package/templates/chat/src/mainview/components/activity-bar/ActivityBar.tsx +26 -0
- package/templates/chat/src/mainview/components/activity-bar/MobileTabBar.tsx +20 -0
- package/templates/chat/src/mainview/components/chat/ChatPanel.tsx +66 -0
- package/templates/chat/src/mainview/components/chat/MessageBubble.tsx +85 -0
- package/templates/chat/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
- package/templates/chat/src/mainview/components/common/ThemeToggle.tsx +24 -0
- package/templates/chat/src/mainview/components/sidebar/PinButton.tsx +20 -0
- package/templates/chat/src/mainview/global.d.ts +13 -0
- package/templates/chat/src/mainview/hooks/use-breakpoint.ts +34 -0
- package/templates/chat/src/mainview/hooks/use-input-history.ts +84 -0
- package/templates/chat/src/mainview/index.css +61 -0
- package/templates/chat/src/mainview/index.html +12 -0
- package/templates/chat/src/mainview/lib/api-client.ts +175 -0
- package/templates/chat/src/mainview/lib/i18n/index.ts +30 -0
- package/templates/chat/src/mainview/lib/i18n/locales/en.json +157 -0
- package/templates/chat/src/mainview/lib/i18n/locales/zh.json +157 -0
- package/templates/chat/src/mainview/main.tsx +20 -0
- package/templates/chat/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
- package/templates/chat/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
- package/templates/chat/src/mainview/stores/message-batcher.ts +25 -0
- package/templates/chat/src/mainview/stores/use-app-store.ts +50 -0
- package/templates/chat/src/mainview/stores/use-chat-store.ts +37 -0
- package/templates/chat/src/mainview/stores/use-connection-store.ts +42 -0
- package/templates/chat/src/mainview/stores/use-locale-store.ts +27 -0
- package/templates/chat/src/mainview/stores/use-log-store.ts +16 -0
- package/templates/chat/src/mainview/stores/use-notification-store.ts +82 -0
- package/templates/chat/src/mainview/stores/use-sidebar-store.ts +98 -0
- package/templates/chat/src/mainview/stores/use-theme-store.ts +46 -0
- package/templates/chat/src/mainview/types/index.ts +8 -0
- package/templates/chat/src/mainview/utils/constants.ts +1 -0
- package/templates/chat/src/server-config.ts +42 -0
- package/templates/chat/src/server.ts +89 -0
- package/templates/chat/src/shared/__tests__/chat-handler.test.ts +71 -0
- package/templates/chat/src/shared/__tests__/system-handler.test.ts +70 -0
- package/templates/chat/src/shared/handlers/chat.ts +186 -0
- package/templates/chat/src/shared/handlers/index.ts +2 -0
- package/templates/chat/src/shared/handlers/system.ts +27 -0
- package/templates/chat/src/shared/lib/logger.ts +130 -0
- package/templates/chat/src/shared/lib/path-security.ts +38 -0
- package/templates/chat/src/shared/lib/port-registry.ts +103 -0
- package/templates/chat/src/shared/modules/chat.ts +20 -0
- package/templates/chat/src/shared/modules/system.ts +8 -0
- package/templates/chat/src/shared/register-all-handlers.ts +36 -0
- package/templates/chat/src/shared/rpc-schema.ts +11 -0
- package/templates/chat/tailwind.config.js +15 -0
- package/templates/chat/tsconfig.json +26 -0
- package/templates/chat/vite.config.ts +3 -0
- package/templates/chat/vitest.config.ts +3 -0
- package/templates/general/.env.example +7 -0
- package/templates/general/LICENSE +21 -0
- package/templates/general/README.md +113 -0
- package/templates/general/bun.lock +1266 -0
- package/templates/general/electrobun.config.ts +27 -0
- package/templates/general/eslint.config.mjs +56 -0
- package/templates/general/llms.txt +24 -0
- package/templates/general/package-lock.json +3670 -0
- package/templates/general/package.json +59 -0
- package/templates/general/postcss.config.js +6 -0
- package/templates/general/scripts/dev.ts +138 -0
- package/templates/general/src/__tests__/server-config.test.ts +59 -0
- package/templates/general/src/bun/index.ts +72 -0
- package/templates/general/src/gateway/http-routes.ts +1 -0
- package/templates/general/src/gateway/ipc-transport.ts +68 -0
- package/templates/general/src/gateway/ws-handler.ts +86 -0
- package/templates/general/src/mainview/App.tsx +40 -0
- package/templates/general/src/mainview/__tests__/components/ChatPanel.test.tsx +82 -0
- package/templates/general/src/mainview/__tests__/components/FeedPanel.test.tsx +109 -0
- package/templates/general/src/mainview/__tests__/components/GitPanel.test.tsx +151 -0
- package/templates/general/src/mainview/__tests__/i18n/i18n.test.ts +48 -0
- package/templates/general/src/mainview/__tests__/setup-verify.test.ts +8 -0
- package/templates/general/src/mainview/__tests__/setup.ts +37 -0
- package/templates/general/src/mainview/components/activity-bar/ActivityBar.tsx +40 -0
- package/templates/general/src/mainview/components/activity-bar/MobileTabBar.tsx +29 -0
- package/templates/general/src/mainview/components/chat/ChatPanel.tsx +66 -0
- package/templates/general/src/mainview/components/chat/MessageBubble.tsx +85 -0
- package/templates/general/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
- package/templates/general/src/mainview/components/common/ThemeToggle.tsx +24 -0
- package/templates/general/src/mainview/components/debug/DebugPanel.tsx +176 -0
- package/templates/general/src/mainview/components/diff/DiffViewerPanel.tsx +108 -0
- package/templates/general/src/mainview/components/explorer/ConfirmDialog.tsx +52 -0
- package/templates/general/src/mainview/components/explorer/ContextMenu.tsx +82 -0
- package/templates/general/src/mainview/components/explorer/ExplorerSidebar.tsx +225 -0
- package/templates/general/src/mainview/components/explorer/InlineInput.tsx +55 -0
- package/templates/general/src/mainview/components/explorer/TreeNodeItem.tsx +121 -0
- package/templates/general/src/mainview/components/feed/FeedPanel.tsx +248 -0
- package/templates/general/src/mainview/components/file-preview/FilePreviewOverlay.tsx +55 -0
- package/templates/general/src/mainview/components/file-preview/VirtualizedCodeView.tsx +99 -0
- package/templates/general/src/mainview/components/git/GitBranchSelector.tsx +93 -0
- package/templates/general/src/mainview/components/git/GitCommitInput.tsx +60 -0
- package/templates/general/src/mainview/components/git/GitPanel.tsx +533 -0
- package/templates/general/src/mainview/components/layout/AppLayout.tsx +146 -0
- package/templates/general/src/mainview/components/search/SearchPanel.tsx +405 -0
- package/templates/general/src/mainview/components/sidebar/PinButton.tsx +20 -0
- package/templates/general/src/mainview/global.d.ts +13 -0
- package/templates/general/src/mainview/hooks/use-breakpoint.ts +34 -0
- package/templates/general/src/mainview/hooks/use-input-history.ts +84 -0
- package/templates/general/src/mainview/hooks/use-rpc-init.ts +61 -0
- package/templates/general/src/mainview/hooks/use-sidebar-resize.ts +40 -0
- package/templates/general/src/mainview/index.css +61 -0
- package/templates/general/src/mainview/index.html +12 -0
- package/templates/general/src/mainview/lib/api-client.ts +175 -0
- package/templates/general/src/mainview/lib/i18n/index.ts +30 -0
- package/templates/general/src/mainview/lib/i18n/locales/en.json +157 -0
- package/templates/general/src/mainview/lib/i18n/locales/zh.json +157 -0
- package/templates/general/src/mainview/main.tsx +20 -0
- package/templates/general/src/mainview/stores/__tests__/use-chat-store.test.ts +104 -0
- package/templates/general/src/mainview/stores/__tests__/use-connection-store.test.ts +35 -0
- package/templates/general/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
- package/templates/general/src/mainview/stores/__tests__/use-log-store.test.ts +45 -0
- package/templates/general/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
- package/templates/general/src/mainview/stores/message-batcher.ts +25 -0
- package/templates/general/src/mainview/stores/use-app-store.ts +104 -0
- package/templates/general/src/mainview/stores/use-chat-store.ts +37 -0
- package/templates/general/src/mainview/stores/use-connection-store.ts +42 -0
- package/templates/general/src/mainview/stores/use-explorer-store.ts +315 -0
- package/templates/general/src/mainview/stores/use-feed-store.ts +129 -0
- package/templates/general/src/mainview/stores/use-git-store.ts +284 -0
- package/templates/general/src/mainview/stores/use-locale-store.ts +27 -0
- package/templates/general/src/mainview/stores/use-log-store.ts +16 -0
- package/templates/general/src/mainview/stores/use-notification-store.ts +82 -0
- package/templates/general/src/mainview/stores/use-sidebar-store.ts +99 -0
- package/templates/general/src/mainview/stores/use-theme-store.ts +46 -0
- package/templates/general/src/mainview/types/index.ts +33 -0
- package/templates/general/src/mainview/utils/constants.ts +1 -0
- package/templates/general/src/mainview/utils/drop-handler.ts +150 -0
- package/templates/general/src/mainview/utils/file-icon.tsx +24 -0
- package/templates/general/src/mainview/utils/file-utils.ts +35 -0
- package/templates/general/src/server-config.ts +42 -0
- package/templates/general/src/server.ts +89 -0
- package/templates/general/src/shared/handlers/__tests__/chat.test.ts +183 -0
- package/templates/general/src/shared/handlers/__tests__/system.test.ts +94 -0
- package/templates/general/src/shared/handlers/__tests__/timer.test.ts +113 -0
- package/templates/general/src/shared/handlers/chat.ts +179 -0
- package/templates/general/src/shared/handlers/feed.ts +53 -0
- package/templates/general/src/shared/handlers/file.ts +99 -0
- package/templates/general/src/shared/handlers/git.ts +263 -0
- package/templates/general/src/shared/handlers/index.ts +7 -0
- package/templates/general/src/shared/handlers/system.ts +27 -0
- package/templates/general/src/shared/handlers/timer.ts +34 -0
- package/templates/general/src/shared/lib/logger.ts +130 -0
- package/templates/general/src/shared/lib/path-security.ts +38 -0
- package/templates/general/src/shared/lib/port-registry.ts +103 -0
- package/templates/general/src/shared/modules/chat.ts +20 -0
- package/templates/general/src/shared/modules/feed.ts +30 -0
- package/templates/general/src/shared/modules/file.ts +40 -0
- package/templates/general/src/shared/modules/git.ts +81 -0
- package/templates/general/src/shared/modules/system.ts +8 -0
- package/templates/general/src/shared/modules/timer.ts +11 -0
- package/templates/general/src/shared/register-all-handlers.ts +36 -0
- package/templates/general/src/shared/rpc-schema.ts +31 -0
- package/templates/general/tailwind.config.js +15 -0
- package/templates/general/tsconfig.json +26 -0
- package/templates/general/vite.config.ts +3 -0
- package/templates/general/vitest.config.ts +3 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { existsSync, readFileSync, mkdirSync } from 'fs';
|
|
4
|
+
import { createServer } from 'net';
|
|
5
|
+
import type { PortEntry } from '../lib/types.js';
|
|
6
|
+
|
|
7
|
+
const PORT_REGISTRY = resolve(process.env.HOME || '~', '.pi-agent', 'ports.json');
|
|
8
|
+
|
|
9
|
+
function readRegistry(): Record<string, PortEntry> {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(readFileSync(PORT_REGISTRY, 'utf-8'));
|
|
12
|
+
} catch {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isPortFree(port: number): Promise<boolean> {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const server = createServer();
|
|
20
|
+
server.once('error', () => resolve(false));
|
|
21
|
+
server.once('listening', () => { server.close(); resolve(true); });
|
|
22
|
+
server.listen(port);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function findFreePorts(entries: Record<string, PortEntry>): Promise<{ backend: number; vite: number }> {
|
|
27
|
+
const usedPorts = new Set<number>();
|
|
28
|
+
for (const entry of Object.values(entries)) {
|
|
29
|
+
usedPorts.add(entry.port);
|
|
30
|
+
}
|
|
31
|
+
let backend = 3100;
|
|
32
|
+
while (usedPorts.has(backend) || !(await isPortFree(backend))) backend++;
|
|
33
|
+
let vite = 5173;
|
|
34
|
+
while (usedPorts.has(vite) || !(await isPortFree(vite))) vite++;
|
|
35
|
+
return { backend, vite };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function runWorkspace(args: string[]): Promise<void> {
|
|
39
|
+
const subCommand = args[0];
|
|
40
|
+
|
|
41
|
+
if (!subCommand || subCommand === '--help' || subCommand === '-h') {
|
|
42
|
+
console.log(`
|
|
43
|
+
Usage: create-agent workspace add <name> [--base <branch>]
|
|
44
|
+
|
|
45
|
+
Creates an isolated git worktree in .workspace/<name> with its own branch and ports.
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--base <branch> Base branch for the new worktree (default: current HEAD)
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
create-agent workspace add feature-chat-ui
|
|
52
|
+
create-agent workspace add fix-login --base develop
|
|
53
|
+
`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (subCommand !== 'add') {
|
|
58
|
+
console.error(`Unknown workspace subcommand: "${subCommand}"`);
|
|
59
|
+
console.log('Usage: create-agent workspace add <name>');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let name = '';
|
|
64
|
+
let baseBranch = '';
|
|
65
|
+
const rest = args.slice(1);
|
|
66
|
+
for (let i = 0; i < rest.length; i++) {
|
|
67
|
+
if (rest[i] === '--base' && rest[i + 1]) {
|
|
68
|
+
baseBranch = rest[++i];
|
|
69
|
+
} else if (!rest[i].startsWith('--')) {
|
|
70
|
+
name = rest[i];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!name) {
|
|
75
|
+
console.error('Error: workspace name is required');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const projectRoot = process.cwd();
|
|
80
|
+
const workspaceDir = resolve(projectRoot, '.workspace', name);
|
|
81
|
+
|
|
82
|
+
if (existsSync(workspaceDir)) {
|
|
83
|
+
console.error(`Error: workspace "${name}" already exists at ${workspaceDir}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const branchName = `workspace/${name}`;
|
|
88
|
+
const baseArg = baseBranch ? baseBranch : 'HEAD';
|
|
89
|
+
|
|
90
|
+
console.log(`Creating workspace: ${name}`);
|
|
91
|
+
console.log(` Branch: ${branchName}`);
|
|
92
|
+
console.log(` Directory: .workspace/${name}`);
|
|
93
|
+
|
|
94
|
+
mkdirSync(resolve(projectRoot, '.workspace'), { recursive: true });
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
execSync(`git worktree add "${workspaceDir}" -b ${branchName} ${baseArg}`, {
|
|
98
|
+
cwd: projectRoot,
|
|
99
|
+
stdio: 'pipe',
|
|
100
|
+
});
|
|
101
|
+
} catch (err: unknown) {
|
|
102
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
103
|
+
console.error(`Failed to create worktree: ${message}`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const registry = readRegistry();
|
|
108
|
+
const ports = await findFreePorts(registry);
|
|
109
|
+
|
|
110
|
+
console.log(` Backend port: ${ports.backend}`);
|
|
111
|
+
console.log(` Vite port: ${ports.vite}`);
|
|
112
|
+
console.log('');
|
|
113
|
+
console.log('Installing dependencies...');
|
|
114
|
+
try {
|
|
115
|
+
execSync('bun install', { cwd: workspaceDir, stdio: 'pipe' });
|
|
116
|
+
} catch {
|
|
117
|
+
console.log('(bun install skipped)');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log('Workspace created successfully!');
|
|
122
|
+
console.log('');
|
|
123
|
+
console.log('To start developing:');
|
|
124
|
+
console.log(` cd .workspace/${name}`);
|
|
125
|
+
console.log(` PORT=${ports.backend} VITE_PORT=${ports.vite} bun run dev:web`);
|
|
126
|
+
console.log('');
|
|
127
|
+
console.log('Or start from project root:');
|
|
128
|
+
console.log(` PORT=${ports.backend} VITE_PORT=${ports.vite} bun run dev:web`);
|
|
129
|
+
}
|
package/src/lib/copy.ts
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync } from 'fs';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
const SKIP_DIRS = new Set(['node_modules', 'build', 'dist', '.git', '.husky', '.trae']);
|
|
6
|
+
const SKIP_FILES = new Set(['bun.lock', 'rpc-browser.js']);
|
|
7
|
+
|
|
8
|
+
export interface CopyOptions {
|
|
9
|
+
projectName: string;
|
|
10
|
+
templateDir: string;
|
|
11
|
+
targetDir: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function deriveNames(projectName: string) {
|
|
15
|
+
const pascalName = projectName.replace(/(^|-)([a-z])/g, (_, _sep, c) => c.toUpperCase());
|
|
16
|
+
const identifier = `com.${projectName.replace(/-/g, '')}.app`;
|
|
17
|
+
const shortId = `com.${projectName.replace(/-/g, '')}`;
|
|
18
|
+
return { pascalName, identifier, shortId };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function copyAndReplace(srcDir: string, destDir: string, projectName: string): void {
|
|
22
|
+
const { pascalName, identifier, shortId } = deriveNames(projectName);
|
|
23
|
+
|
|
24
|
+
mkdirSync(destDir, { recursive: true });
|
|
25
|
+
|
|
26
|
+
const entries = readdirSync(srcDir, { withFileTypes: true });
|
|
27
|
+
|
|
28
|
+
for (const entry of entries) {
|
|
29
|
+
const srcPath = join(srcDir, entry.name);
|
|
30
|
+
const destPath = join(destDir, entry.name);
|
|
31
|
+
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
34
|
+
copyAndReplace(srcPath, destPath, projectName);
|
|
35
|
+
} else {
|
|
36
|
+
if (SKIP_FILES.has(entry.name)) continue;
|
|
37
|
+
|
|
38
|
+
let content = readFileSync(srcPath, 'utf-8');
|
|
39
|
+
|
|
40
|
+
content = content.replace(/pi-agent-template/g, projectName);
|
|
41
|
+
content = content.replace(/Pi Agent Template/g, pascalName);
|
|
42
|
+
content = content.replace(/Pi Agent/g, pascalName);
|
|
43
|
+
content = content.replace(/com\.piagent\.template/g, identifier);
|
|
44
|
+
content = content.replace(/com\.piagent/g, shortId);
|
|
45
|
+
content = content.replace(/@pi-agent\//g, `@${projectName}/`);
|
|
46
|
+
|
|
47
|
+
writeFileSync(destPath, content);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function copyTraeRules(monorepoRoot: string, targetDir: string, projectName: string): void {
|
|
53
|
+
const traeRulesDir = resolve(monorepoRoot, '.trae', 'rules');
|
|
54
|
+
if (!existsSync(traeRulesDir)) return;
|
|
55
|
+
|
|
56
|
+
const destRulesDir = join(targetDir, '.trae', 'rules');
|
|
57
|
+
mkdirSync(destRulesDir, { recursive: true });
|
|
58
|
+
|
|
59
|
+
const files = readdirSync(traeRulesDir).filter((f) => f !== 'memory.md');
|
|
60
|
+
for (const file of files) {
|
|
61
|
+
const src = join(traeRulesDir, file);
|
|
62
|
+
const dest = join(destRulesDir, file);
|
|
63
|
+
let content = readFileSync(src, 'utf-8');
|
|
64
|
+
content = content.replace(/pi-agent-template/g, projectName);
|
|
65
|
+
writeFileSync(dest, content);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function copySharedModules(monorepoRoot: string, targetDir: string, projectName: string): void {
|
|
70
|
+
const sharedDir = resolve(monorepoRoot, 'templates', 'shared');
|
|
71
|
+
if (!existsSync(sharedDir)) return;
|
|
72
|
+
|
|
73
|
+
const destSharedDir = join(targetDir, 'shared');
|
|
74
|
+
copyAndReplace(sharedDir, destSharedDir, projectName);
|
|
75
|
+
|
|
76
|
+
const tsconfigPath = join(targetDir, 'tsconfig.json');
|
|
77
|
+
if (existsSync(tsconfigPath)) {
|
|
78
|
+
let tsconfig = readFileSync(tsconfigPath, 'utf-8');
|
|
79
|
+
tsconfig = tsconfig.replace(/"\.\.\/shared\/\*"/g, '"./shared/*"');
|
|
80
|
+
tsconfig = tsconfig.replace(/"\.\.\/shared"/g, '"./shared"');
|
|
81
|
+
writeFileSync(tsconfigPath, tsconfig);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
cleanSharedViteConfig(destSharedDir);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function cleanViteConfig(targetDir: string): void {
|
|
88
|
+
const viteConfigPath = join(targetDir, "vite.config.ts");
|
|
89
|
+
const vitestConfigPath = join(targetDir, "vitest.config.ts");
|
|
90
|
+
|
|
91
|
+
for (const configPath of [viteConfigPath, vitestConfigPath]) {
|
|
92
|
+
if (!existsSync(configPath)) continue;
|
|
93
|
+
|
|
94
|
+
let config = readFileSync(configPath, "utf-8");
|
|
95
|
+
|
|
96
|
+
config = config.replace(
|
|
97
|
+
/,\n\s+resolve:\s*\{\n\s+alias:\s*\{[^}]*\}[,\s]*\}[,;]?\n/g,
|
|
98
|
+
""
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if (!config.includes('from "path"') && config.includes("resolve(")) {
|
|
102
|
+
config = 'import { resolve } from "path";\n' + config;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
config = config.replace(/from ["']\.\.\/shared\/vite-base\.config["']/g, 'from "./shared/vite-base.config"');
|
|
106
|
+
config = config.replace(/from ["']\.\.\/shared\/vitest-base\.config["']/g, 'from "./shared/vitest-base.config"');
|
|
107
|
+
|
|
108
|
+
writeFileSync(configPath, config);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function cleanSharedViteConfig(sharedDir: string): void {
|
|
113
|
+
const viteBaseConfigPath = join(sharedDir, "vite-base.config.ts");
|
|
114
|
+
const vitestBaseConfigPath = join(sharedDir, "vitest-base.config.ts");
|
|
115
|
+
|
|
116
|
+
for (const configPath of [viteBaseConfigPath, vitestBaseConfigPath]) {
|
|
117
|
+
if (!existsSync(configPath)) continue;
|
|
118
|
+
|
|
119
|
+
let config = readFileSync(configPath, "utf-8");
|
|
120
|
+
config = config.replace(
|
|
121
|
+
/,\n\s+resolve:\s*\{\n\s+alias:\s*\{[^}]*\}[,\s]*\}[,;]?\n/g,
|
|
122
|
+
""
|
|
123
|
+
);
|
|
124
|
+
config = config.replace(
|
|
125
|
+
/,\n\s+alias:\s*\{[^}]*\}[,\s]*[,;]?\n/g,
|
|
126
|
+
""
|
|
127
|
+
);
|
|
128
|
+
if (!config.includes("resolve(")) {
|
|
129
|
+
config = config.replace(/import\s*\{\s*resolve\s*\}\s*from\s*["']path["'];?\n?/g, "");
|
|
130
|
+
config = config.replace(
|
|
131
|
+
/export function create(Vite|Vitest)Config\(dirname: string\)/g,
|
|
132
|
+
"export function create$1Config()"
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
writeFileSync(configPath, config);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function resolvePackageVersion(packageName: string): string {
|
|
140
|
+
try {
|
|
141
|
+
return execSync(`npm view ${packageName} version`, { encoding: 'utf-8' }).trim();
|
|
142
|
+
} catch {
|
|
143
|
+
return '1.0.0';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const WORKSPACE_PACKAGES = [
|
|
148
|
+
'@dyyz1993/rpc-core',
|
|
149
|
+
'@dyyz1993/eslint-plugin-rpc',
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
function updatePackageJson(targetDir: string, _projectName: string): void {
|
|
153
|
+
const rootPkgPath = join(targetDir, 'package.json');
|
|
154
|
+
if (!existsSync(rootPkgPath)) return;
|
|
155
|
+
|
|
156
|
+
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'));
|
|
157
|
+
|
|
158
|
+
delete rootPkg.workspaces;
|
|
159
|
+
|
|
160
|
+
for (const depKey of ['dependencies', 'devDependencies'] as const) {
|
|
161
|
+
if (!rootPkg[depKey]) continue;
|
|
162
|
+
for (const pkgName of WORKSPACE_PACKAGES) {
|
|
163
|
+
if (!rootPkg[depKey][pkgName]) continue;
|
|
164
|
+
if (pkgName === '@dyyz1993/rpc-core') {
|
|
165
|
+
const version = resolvePackageVersion(pkgName);
|
|
166
|
+
rootPkg[depKey][pkgName] = `^${version}`;
|
|
167
|
+
} else {
|
|
168
|
+
delete rootPkg[depKey][pkgName];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, '\t') + '\n');
|
|
174
|
+
|
|
175
|
+
const eslintConfigPath = join(targetDir, 'eslint.config.mjs');
|
|
176
|
+
if (existsSync(eslintConfigPath)) {
|
|
177
|
+
const lines = readFileSync(eslintConfigPath, 'utf-8').split('\n');
|
|
178
|
+
const filteredLines: string[] = [];
|
|
179
|
+
|
|
180
|
+
let inRpcSection = false;
|
|
181
|
+
for (let i = 0; i < lines.length; i++) {
|
|
182
|
+
const line = lines[i];
|
|
183
|
+
|
|
184
|
+
if (line.includes('import rpcPlugin') && line.includes('@dyyz1993/eslint-plugin-rpc')) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (line.includes('RPC') && line.includes('规范规则')) {
|
|
189
|
+
inRpcSection = true;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (inRpcSection) {
|
|
194
|
+
if (line.trim().startsWith("'rpc/") || line.trim().startsWith('"rpc/')) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
inRpcSection = false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (line.includes('rpc: rpcPlugin')) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
filteredLines.push(line);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let content = filteredLines.join('\n');
|
|
208
|
+
content = content.replace(/\n\s+plugins:\s*\{\s*\},?\s*\n/g, '\n');
|
|
209
|
+
|
|
210
|
+
writeFileSync(eslintConfigPath, content);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export async function copyTemplate(options: CopyOptions): Promise<void> {
|
|
215
|
+
const { projectName, templateDir, targetDir } = options;
|
|
216
|
+
const localRoot = resolve(import.meta.dir, '..', '..', '..', '..');
|
|
217
|
+
const isMonorepo = existsSync(resolve(localRoot, 'templates', 'general'));
|
|
218
|
+
|
|
219
|
+
if (existsSync(targetDir)) {
|
|
220
|
+
throw new Error(`Directory "${targetDir}" already exists.`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const { identifier } = deriveNames(projectName);
|
|
224
|
+
|
|
225
|
+
console.log(`Creating project: ${projectName}`);
|
|
226
|
+
console.log(`Target directory: ${targetDir}`);
|
|
227
|
+
console.log(`App identifier: ${identifier}`);
|
|
228
|
+
console.log('');
|
|
229
|
+
|
|
230
|
+
copyAndReplace(templateDir, targetDir, projectName);
|
|
231
|
+
if (isMonorepo) {
|
|
232
|
+
copyTraeRules(localRoot, targetDir, projectName);
|
|
233
|
+
copySharedModules(localRoot, targetDir, projectName);
|
|
234
|
+
}
|
|
235
|
+
cleanViteConfig(targetDir);
|
|
236
|
+
updatePackageJson(targetDir, projectName);
|
|
237
|
+
|
|
238
|
+
console.log('Initializing git...');
|
|
239
|
+
execSync('git init', { cwd: targetDir, stdio: 'pipe' });
|
|
240
|
+
|
|
241
|
+
console.log('Installing dependencies...');
|
|
242
|
+
execSync('bun install', { cwd: targetDir, stdio: 'inherit' });
|
|
243
|
+
|
|
244
|
+
console.log('Building browser bundle...');
|
|
245
|
+
try {
|
|
246
|
+
execSync('bun run build:browser', { cwd: targetDir, stdio: 'pipe' });
|
|
247
|
+
} catch {
|
|
248
|
+
console.log('(build:browser skipped - script not found)');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const huskyDir = join(targetDir, '.husky');
|
|
252
|
+
mkdirSync(huskyDir, { recursive: true });
|
|
253
|
+
writeFileSync(
|
|
254
|
+
join(huskyDir, 'pre-commit'),
|
|
255
|
+
[
|
|
256
|
+
'#!/bin/sh',
|
|
257
|
+
'bun run lint',
|
|
258
|
+
'ERRORS=$(bunx tsc --noEmit 2>&1 | grep "error TS" | grep -v "node_modules" || true)',
|
|
259
|
+
'if [ -n "$ERRORS" ]; then',
|
|
260
|
+
' echo "$ERRORS"',
|
|
261
|
+
' exit 1',
|
|
262
|
+
'fi',
|
|
263
|
+
].join('\n') + '\n',
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
execSync('git add -A', { cwd: targetDir, stdio: 'pipe' });
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
execSync(`git commit --no-verify -m "feat: init ${projectName} from pi-agent-template"`, {
|
|
270
|
+
cwd: targetDir,
|
|
271
|
+
stdio: 'pipe',
|
|
272
|
+
});
|
|
273
|
+
} catch {
|
|
274
|
+
console.log('(git commit skipped - no files to commit)');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
console.log('');
|
|
278
|
+
console.log('Project created successfully!');
|
|
279
|
+
console.log('');
|
|
280
|
+
console.log('Next steps:');
|
|
281
|
+
console.log(` cd ${targetDir}`);
|
|
282
|
+
console.log(' bun run dev # Start desktop app (Electrobun)');
|
|
283
|
+
console.log(' bun run dev:web # Start web mode (Vite + Gateway)');
|
|
284
|
+
console.log('');
|
|
285
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
|
|
4
|
+
interface TemplateInfo {
|
|
5
|
+
type: string;
|
|
6
|
+
description: string;
|
|
7
|
+
available: boolean;
|
|
8
|
+
dir: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const TEMPLATES: TemplateInfo[] = [
|
|
12
|
+
{
|
|
13
|
+
type: 'general',
|
|
14
|
+
description: 'Full-featured template (File explorer, Git, Search, Chat, Timer, Feed)',
|
|
15
|
+
available: true,
|
|
16
|
+
dir: 'templates/general',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'chat',
|
|
20
|
+
description: 'Chat-focused template (Enhanced ChatPanel, Markdown, Session management)',
|
|
21
|
+
available: true,
|
|
22
|
+
dir: 'templates/chat',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'agent',
|
|
26
|
+
description: 'Coding agent template (Bash, Rules engine, Todo management)',
|
|
27
|
+
available: true,
|
|
28
|
+
dir: 'templates/agent',
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export function getTemplateInfo(type: string): TemplateInfo | undefined {
|
|
33
|
+
return TEMPLATES.find((t) => t.type === type);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function getAllTemplates(): TemplateInfo[] {
|
|
37
|
+
return TEMPLATES;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolveTemplateDir(monorepoRoot: string, type: string): string {
|
|
41
|
+
const info = getTemplateInfo(type);
|
|
42
|
+
if (!info) {
|
|
43
|
+
throw new Error(`Unknown template type: "${type}". Run "create-agent list" to see available types.`);
|
|
44
|
+
}
|
|
45
|
+
if (!info.available) {
|
|
46
|
+
throw new Error(`Template "${type}" is not available yet (coming soon).`);
|
|
47
|
+
}
|
|
48
|
+
return resolve(monorepoRoot, info.dir);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getRootDir(): string {
|
|
52
|
+
const localRoot = resolve(import.meta.dir, '..', '..', '..', '..');
|
|
53
|
+
if (existsSync(resolve(localRoot, 'templates', 'general'))) {
|
|
54
|
+
return localRoot;
|
|
55
|
+
}
|
|
56
|
+
return resolve(import.meta.dir, '..', '..');
|
|
57
|
+
}
|
package/src/lib/types.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 [username]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Pi Agent Template
|
|
2
|
+
|
|
3
|
+
Coding agent template built with Electrobun, React, Tailwind CSS, and RPC architecture. Extends the general template with **Bash**, **Rules**, and **Todo** management.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun install
|
|
9
|
+
|
|
10
|
+
# Development with HMR (recommended)
|
|
11
|
+
bun run dev:web
|
|
12
|
+
|
|
13
|
+
# Development without HMR
|
|
14
|
+
bun run dev
|
|
15
|
+
|
|
16
|
+
# Build
|
|
17
|
+
bun run build
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
All features from the **general** template, plus:
|
|
23
|
+
|
|
24
|
+
- **Bash Panel** — Execute shell commands, manage multiple processes, view output in a terminal-like interface
|
|
25
|
+
- **Rules Engine** — Define glob-pattern rules with enable/disable toggles for customizing agent behavior
|
|
26
|
+
- **Todo Manager** — Track tasks with pending/in_progress/completed status cycling
|
|
27
|
+
|
|
28
|
+
## RPC Modules
|
|
29
|
+
|
|
30
|
+
| Module | Methods | Events | Description |
|
|
31
|
+
|---|---|---|---|
|
|
32
|
+
| `system` | ping, hello, echo | - | Connectivity test |
|
|
33
|
+
| `file` | listDir, readFile, createFile, createDir, rename, delete, copy, findProjectRoot | - | File system operations |
|
|
34
|
+
| `timer` | start, stop | timer.tick | Timer + real-time push |
|
|
35
|
+
| `chat` | list, send | chat.message | Chat (supports role filtering) |
|
|
36
|
+
| `git` | status, diff, log, branches, checkout, add, reset, commit, push, pull | - | Git version control |
|
|
37
|
+
| `feed` | post, list | feed.update | Feed stream (supports category filtering) |
|
|
38
|
+
| `bash` | execute, kill, listProcesses | bash.output, bash.exit | Shell command execution |
|
|
39
|
+
| `rules` | list, add, toggle, remove | - | Rule management |
|
|
40
|
+
| `todo` | list, add, update, remove | - | Task tracking |
|
|
41
|
+
|
|
42
|
+
## Project Structure
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
├── src/
|
|
46
|
+
│ ├── bun/
|
|
47
|
+
│ │ └── index.ts # Desktop entry (Electrobun main process)
|
|
48
|
+
│ ├── server.ts # Web entry (HTTP + WebSocket server)
|
|
49
|
+
│ ├── gateway/
|
|
50
|
+
│ │ ├── http-routes.ts # HTTP endpoints
|
|
51
|
+
│ │ ├── ws-handler.ts # WebSocket RPC server
|
|
52
|
+
│ │ └── ipc-transport.ts # Electrobun IPC bridge
|
|
53
|
+
│ ├── shared/
|
|
54
|
+
│ │ ├── rpc-schema.ts # Unified RPC type definitions
|
|
55
|
+
│ │ ├── register-all-handlers.ts
|
|
56
|
+
│ │ ├── modules/ # RPC method type definitions
|
|
57
|
+
│ │ │ ├── bash.ts # Bash RPC types
|
|
58
|
+
│ │ │ ├── rules.ts # Rules RPC types
|
|
59
|
+
│ │ │ └── todo.ts # Todo RPC types
|
|
60
|
+
│ │ └── handlers/ # RPC handler implementations
|
|
61
|
+
│ │ ├── bash.ts # Bash handler (Bun.spawn)
|
|
62
|
+
│ │ ├── rules.ts # Rules CRUD handler
|
|
63
|
+
│ │ └── todo.ts # Todo CRUD handler
|
|
64
|
+
│ └── mainview/ # React frontend
|
|
65
|
+
│ ├── App.tsx # Main app with Bash/Rules/Todo tabs
|
|
66
|
+
│ ├── components/
|
|
67
|
+
│ │ ├── activity-bar/ # Sidebar + mobile tabs (includes Rules)
|
|
68
|
+
│ │ ├── bash/ # BashPanel — terminal interface
|
|
69
|
+
│ │ ├── rules/ # RulesPanel — rule management
|
|
70
|
+
│ │ ├── todo/ # TodoPanel — task management
|
|
71
|
+
│ │ ├── chat/
|
|
72
|
+
│ │ ├── explorer/
|
|
73
|
+
│ │ ├── feed/
|
|
74
|
+
│ │ ├── git/
|
|
75
|
+
│ │ ├── search/
|
|
76
|
+
│ │ └── debug/
|
|
77
|
+
│ ├── stores/
|
|
78
|
+
│ │ ├── use-bash-store.ts # Bash process state
|
|
79
|
+
│ │ ├── use-rules-store.ts # Rules state
|
|
80
|
+
│ │ └── use-todo-store.ts # Todo state
|
|
81
|
+
│ └── lib/
|
|
82
|
+
│ └── api-client.ts # Typed RPC client
|
|
83
|
+
├── eslint-plugin-rpc/
|
|
84
|
+
├── electrobun.config.ts
|
|
85
|
+
├── vite.config.ts
|
|
86
|
+
└── tailwind.config.js
|
|
87
|
+
```
|