From 5af32e9e92a60d87e43b24441d1e369afc144ad8 Mon Sep 17 00:00:00 2001 From: rob Date: Tue, 6 Jan 2026 03:19:15 -0400 Subject: [PATCH] Update documentation 2026-01-06 --- 404.html | 2 +- assets/js/1db64337.2ac055a2.js | 1 + assets/js/1db64337.e2b8ddcf.js | 1 - ...~main.20c2acbd.js => runtime~main.95ff8c89.js} | 2 +- index.html | 15 +++++++++++---- 5 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 assets/js/1db64337.2ac055a2.js delete mode 100644 assets/js/1db64337.e2b8ddcf.js rename assets/js/{runtime~main.20c2acbd.js => runtime~main.95ff8c89.js} (96%) diff --git a/404.html b/404.html index aa1b2f4..cfa763c 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@ Development Hub - + diff --git a/assets/js/1db64337.2ac055a2.js b/assets/js/1db64337.2ac055a2.js new file mode 100644 index 0000000..d0049c2 --- /dev/null +++ b/assets/js/1db64337.2ac055a2.js @@ -0,0 +1 @@ +"use strict";(globalThis.webpackChunkproject_public_docs=globalThis.webpackChunkproject_public_docs||[]).push([[413],{6785(e,t,n){n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>a,frontMatter:()=>c,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"overview","title":"Development Hub","description":"Central orchestration project for managing Rob\'s multi-project development ecosystem.","source":"@site/docs/overview.md","sourceDirName":".","slug":"/","permalink":"/rob/development-hub/","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"slug":"/","sidebar_position":1},"sidebar":"docs"}');var i=n(4848),s=n(8453);const c={slug:"/",sidebar_position:1},l="Development Hub",d={},o=[{value:"Overview",id:"overview",level:2},{value:"GUI Application",id:"gui-application",level:2},{value:"Running the App",id:"running-the-app",level:3},{value:"Features",id:"features",level:3},{value:"Keyboard Shortcuts",id:"keyboard-shortcuts",level:3},{value:"The new-project Script",id:"the-new-project-script",level:2},{value:"What It Creates",id:"what-it-creates",level:3},{value:"Usage",id:"usage",level:3},{value:"Architecture",id:"architecture",level:2},{value:"Key Classes",id:"key-classes",level:3},{value:"Project Structure",id:"project-structure",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Gitea API Token",id:"gitea-api-token",level:3},{value:"Template Placeholders",id:"template-placeholders",level:2},{value:"Related Projects",id:"related-projects",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"development-hub",children:"Development Hub"})}),"\n",(0,i.jsx)(t.p,{children:"Central orchestration project for managing Rob's multi-project development ecosystem."}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"Development Hub provides:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"GUI Application"})," - PyQt6 workspace with project list, splittable terminal panes, and session persistence"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"CLI Tools"})," - Scripts to create and manage projects following consistent patterns"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Centralized Documentation"})," - Docusaurus-based docs with Gitea Pages deployment"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"gui-application",children:"GUI Application"}),"\n",(0,i.jsx)(t.p,{children:"A PyQt6-based workspace for managing your development projects."}),"\n",(0,i.jsx)(t.h3,{id:"running-the-app",children:"Running the App"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"cd ~/PycharmProjects/development-hub\nsource .venv/bin/activate\npython -m development_hub\n"})}),"\n",(0,i.jsx)(t.h3,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Project List"})," - Auto-discovers projects, right-click for actions (terminal, editor, Gitea, docs, deploy)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Splittable Panes"})," - Horizontal/vertical splits, each pane has its own tab bar"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"PTY Terminals"})," - Full terminal emulation with TUI support (vim, htop work)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Drag & Drop"})," - Drop files/folders into terminal to inject paths"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Session Persistence"})," - Remembers pane layout and open terminals on restart"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"New Project Dialog"})," - Create projects with optional Ramble voice input"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"keyboard-shortcuts",children:"Keyboard Shortcuts"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Shortcut"}),(0,i.jsx)(t.th,{children:"Action"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+Shift+T"})}),(0,i.jsx)(t.td,{children:"New terminal tab"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+Shift+W"})}),(0,i.jsx)(t.td,{children:"Close current tab"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+Shift+D"})}),(0,i.jsx)(t.td,{children:"Split horizontal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+Shift+E"})}),(0,i.jsx)(t.td,{children:"Split vertical"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+Shift+P"})}),(0,i.jsx)(t.td,{children:"Close active pane"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+Alt+Left/Right"})}),(0,i.jsx)(t.td,{children:"Switch panes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+B"})}),(0,i.jsx)(t.td,{children:"Toggle project panel"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Ctrl+N"})}),(0,i.jsx)(t.td,{children:"New project dialog"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"F5"})}),(0,i.jsx)(t.td,{children:"Refresh project list"})]})]})]}),"\n",(0,i.jsxs)(t.h2,{id:"the-new-project-script",children:["The ",(0,i.jsx)(t.code,{children:"new-project"})," Script"]}),"\n",(0,i.jsxs)(t.p,{children:["The main tool is ",(0,i.jsx)(t.code,{children:"new-project"}),", which automates creating a new project in the ecosystem:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:'new-project my-tool --title "My Tool" --tagline "Does useful things"\n'})}),"\n",(0,i.jsx)(t.h3,{id:"what-it-creates",children:"What It Creates"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Gitea repository"})," at ",(0,i.jsx)(t.code,{children:"gitea.brrd.tech/rob/my-tool"})]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Local project"})," at ",(0,i.jsx)(t.code,{children:"~/PycharmProjects/my-tool/"})," with:","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"CLAUDE.md"})," - AI assistant context"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"README.md"})," - Project readme"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"pyproject.toml"})," - Python packaging"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:".gitignore"})," - Standard ignores"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"docs/"})," - Symlink to centralized docs"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Documentation folder"})," at ",(0,i.jsx)(t.code,{children:"project-docs/docs/projects/my-tool/"})]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Build configuration"})," in ",(0,i.jsx)(t.code,{children:"build-public-docs.sh"})]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:'# Full specification\nnew-project myproject --title "My Project" --tagline "Short description"\n\n# Interactive mode (prompts for title/tagline)\nnew-project myproject\n\n# Options\n--dry-run Show what would happen without making changes\n--skip-gitea Skip Gitea repo creation (for offline use)\n--help Show help\n'})}),"\n",(0,i.jsx)(t.h2,{id:"architecture",children:"Architecture"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"src/development_hub/\n\u251c\u2500\u2500 __init__.py\n\u251c\u2500\u2500 __main__.py # Entry point\n\u251c\u2500\u2500 app.py # QApplication subclass\n\u251c\u2500\u2500 main_window.py # Main window with menus\n\u251c\u2500\u2500 project_list.py # Left panel - project discovery & context menu\n\u251c\u2500\u2500 workspace.py # Right panel - splittable panes with tabs\n\u251c\u2500\u2500 terminal_widget.py # PTY terminal with pyte emulation\n\u251c\u2500\u2500 project_discovery.py # Parse projects from build-public-docs.sh\n\u251c\u2500\u2500 dialogs.py # New Project (with Ramble), Settings dialogs\n\u251c\u2500\u2500 settings.py # JSON persistence for settings & session\n\u2514\u2500\u2500 styles.py # Dark theme stylesheet\n"})}),"\n",(0,i.jsx)(t.h3,{id:"key-classes",children:"Key Classes"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Class"}),(0,i.jsx)(t.th,{children:"File"}),(0,i.jsx)(t.th,{children:"Purpose"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"MainWindow"})}),(0,i.jsx)(t.td,{children:"main_window.py"}),(0,i.jsx)(t.td,{children:"QMainWindow with menus, splitter layout"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"ProjectListWidget"})}),(0,i.jsx)(t.td,{children:"project_list.py"}),(0,i.jsx)(t.td,{children:"Project list with context menu actions"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"WorkspaceManager"})}),(0,i.jsx)(t.td,{children:"workspace.py"}),(0,i.jsx)(t.td,{children:"Manages splittable pane layout"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"PaneWidget"})}),(0,i.jsx)(t.td,{children:"workspace.py"}),(0,i.jsx)(t.td,{children:"Tab container within a pane"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"TerminalWidget"})}),(0,i.jsx)(t.td,{children:"terminal_widget.py"}),(0,i.jsx)(t.td,{children:"PTY-based terminal with pyte screen emulation"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"project-structure",children:"Project Structure"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"development-hub/\n\u251c\u2500\u2500 src/development_hub/ # GUI application (see Architecture above)\n\u251c\u2500\u2500 bin/\n\u2502 \u2514\u2500\u2500 new-project # CLI scaffolding script\n\u251c\u2500\u2500 templates/\n\u2502 \u251c\u2500\u2500 gitignore.template # Python .gitignore with docs exclusion\n\u2502 \u251c\u2500\u2500 CLAUDE.md.template # AI context file\n\u2502 \u251c\u2500\u2500 README.md.template # Basic README\n\u2502 \u251c\u2500\u2500 pyproject.toml.template\n\u2502 \u251c\u2500\u2500 overview.md.template # Docs overview\n\u2502 \u2514\u2500\u2500 updating-documentation.md.template\n\u251c\u2500\u2500 docs/ # Symlink to project-docs\n\u251c\u2500\u2500 pyproject.toml # Python packaging with PyQt6 dep\n\u251c\u2500\u2500 CLAUDE.md\n\u2514\u2500\u2500 README.md\n"})}),"\n",(0,i.jsx)(t.h2,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(t.h3,{id:"gitea-api-token",children:"Gitea API Token"}),"\n",(0,i.jsx)(t.p,{children:"The script needs a Gitea API token to create repositories automatically."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Setup options:"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Environment variable: ",(0,i.jsx)(t.code,{children:"export GITEA_TOKEN=your_token"})]}),"\n",(0,i.jsxs)(t.li,{children:["Config file: ",(0,i.jsx)(t.code,{children:"~/.config/development-hub/gitea-token"})]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The script will prompt for the token on first run and save it automatically."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Creating a token:"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Go to ",(0,i.jsx)(t.a,{href:"https://gitea.brrd.tech/user/settings/applications",children:"https://gitea.brrd.tech/user/settings/applications"})]}),"\n",(0,i.jsx)(t.li,{children:"Generate a new token with 'repo' scope"}),"\n",(0,i.jsx)(t.li,{children:"Copy the token when prompted"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"template-placeholders",children:"Template Placeholders"}),"\n",(0,i.jsx)(t.p,{children:"When creating new projects, templates use these placeholders:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Placeholder"}),(0,i.jsx)(t.th,{children:"Description"}),(0,i.jsx)(t.th,{children:"Example"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{PROJECT_NAME}}"})}),(0,i.jsx)(t.td,{children:"Lowercase project name"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"my-tool"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{PROJECT_TITLE}}"})}),(0,i.jsx)(t.td,{children:"Display title"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"My Tool"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{PROJECT_TAGLINE}}"})}),(0,i.jsx)(t.td,{children:"Short description"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"Does useful things"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{YEAR}}"})}),(0,i.jsx)(t.td,{children:"Current year"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"2026"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{DATE}}"})}),(0,i.jsx)(t.td,{children:"Creation date"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"2026-01-06"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{GITEA_URL}}"})}),(0,i.jsx)(t.td,{children:"Gitea server URL"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"https://gitea.brrd.tech"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{{GITEA_OWNER}}"})}),(0,i.jsx)(t.td,{children:"Repository owner"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"rob"})})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"related-projects",children:"Related Projects"}),"\n",(0,i.jsx)(t.p,{children:"Development Hub manages these projects:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Project"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"../cmdforge/overview",children:"CmdForge"})}),(0,i.jsx)(t.td,{children:"AI-powered CLI tool builder"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"../cascadingdev/overview",children:"CascadingDev"})}),(0,i.jsx)(t.td,{children:"Cascading Development Framework"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"../orchestrated-discussions/overview",children:"Orchestrated Discussions"})}),(0,i.jsx)(t.td,{children:"AI Discussion Framework"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"../artifact-editor/overview",children:"Artifact Editor"})}),(0,i.jsx)(t.td,{children:"Code Artifact Editor"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"../ramble/overview",children:"Ramble"})}),(0,i.jsx)(t.td,{children:"Voice Note Transcription"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["All projects follow the same patterns and can be created using ",(0,i.jsx)(t.code,{children:"new-project"}),"."]})]})}function a(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453(e,t,n){n.d(t,{R:()=>c,x:()=>l});var r=n(6540);const i={},s=r.createContext(i);function c(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1db64337.e2b8ddcf.js b/assets/js/1db64337.e2b8ddcf.js deleted file mode 100644 index 8f37450..0000000 --- a/assets/js/1db64337.e2b8ddcf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkproject_public_docs=globalThis.webpackChunkproject_public_docs||[]).push([[413],{6785(e,n,t){t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"overview","title":"Development Hub","description":"Central orchestration project for managing Rob\'s multi-project development ecosystem.","source":"@site/docs/overview.md","sourceDirName":".","slug":"/","permalink":"/rob/development-hub/","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"slug":"/","sidebar_position":1},"sidebar":"docs"}');var i=t(4848),s=t(8453);const l={slug:"/",sidebar_position:1},o="Development Hub",c={},d=[{value:"Overview",id:"overview",level:2},{value:"GUI Application",id:"gui-application",level:2},{value:"Running the App",id:"running-the-app",level:3},{value:"Features",id:"features",level:3},{value:"Keyboard Shortcuts",id:"keyboard-shortcuts",level:3},{value:"The new-project Script",id:"the-new-project-script",level:2},{value:"What It Creates",id:"what-it-creates",level:3},{value:"Usage",id:"usage",level:3},{value:"Project Structure",id:"project-structure",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Gitea API Token",id:"gitea-api-token",level:3},{value:"Related Projects",id:"related-projects",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"development-hub",children:"Development Hub"})}),"\n",(0,i.jsx)(n.p,{children:"Central orchestration project for managing Rob's multi-project development ecosystem."}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:"Development Hub provides:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"GUI Application"})," - PyQt6 workspace with project list, splittable terminal panes, and session persistence"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"CLI Tools"})," - Scripts to create and manage projects following consistent patterns"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Centralized Documentation"})," - Docusaurus-based docs with Gitea Pages deployment"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"gui-application",children:"GUI Application"}),"\n",(0,i.jsx)(n.p,{children:"A PyQt6-based workspace for managing your development projects."}),"\n",(0,i.jsx)(n.h3,{id:"running-the-app",children:"Running the App"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ~/PycharmProjects/development-hub\nsource .venv/bin/activate\npython -m development_hub\n"})}),"\n",(0,i.jsx)(n.h3,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Project List"})," - Auto-discovers projects, right-click for actions (terminal, editor, Gitea, docs, deploy)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Splittable Panes"})," - Horizontal/vertical splits, each pane has its own tab bar"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"PTY Terminals"})," - Full terminal emulation with TUI support (vim, htop work)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Drag & Drop"})," - Drop files/folders into terminal to inject paths"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Session Persistence"})," - Remembers pane layout and open terminals on restart"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"New Project Dialog"})," - Create projects with optional Ramble voice input"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"keyboard-shortcuts",children:"Keyboard Shortcuts"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Shortcut"}),(0,i.jsx)(n.th,{children:"Action"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+Shift+T"})}),(0,i.jsx)(n.td,{children:"New terminal tab"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+Shift+W"})}),(0,i.jsx)(n.td,{children:"Close current tab"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+Shift+D"})}),(0,i.jsx)(n.td,{children:"Split horizontal"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+Shift+E"})}),(0,i.jsx)(n.td,{children:"Split vertical"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+Alt+Left/Right"})}),(0,i.jsx)(n.td,{children:"Switch panes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+B"})}),(0,i.jsx)(n.td,{children:"Toggle project panel"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Ctrl+N"})}),(0,i.jsx)(n.td,{children:"New project dialog"})]})]})]}),"\n",(0,i.jsxs)(n.h2,{id:"the-new-project-script",children:["The ",(0,i.jsx)(n.code,{children:"new-project"})," Script"]}),"\n",(0,i.jsxs)(n.p,{children:["The main tool is ",(0,i.jsx)(n.code,{children:"new-project"}),", which automates creating a new project in the ecosystem:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'new-project my-tool --title "My Tool" --tagline "Does useful things"\n'})}),"\n",(0,i.jsx)(n.h3,{id:"what-it-creates",children:"What It Creates"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Gitea repository"})," at ",(0,i.jsx)(n.code,{children:"gitea.brrd.tech/rob/my-tool"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Local project"})," at ",(0,i.jsx)(n.code,{children:"~/PycharmProjects/my-tool/"})," with:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CLAUDE.md"})," - AI assistant context"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Project readme"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"pyproject.toml"})," - Python packaging"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:".gitignore"})," - Standard ignores"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"docs/"})," - Symlink to centralized docs"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Documentation folder"})," at ",(0,i.jsx)(n.code,{children:"project-docs/docs/projects/my-tool/"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Build configuration"})," in ",(0,i.jsx)(n.code,{children:"build-public-docs.sh"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# Full specification\nnew-project myproject --title "My Project" --tagline "Short description"\n\n# Interactive mode (prompts for title/tagline)\nnew-project myproject\n\n# Options\n--dry-run Show what would happen without making changes\n--skip-gitea Skip Gitea repo creation (for offline use)\n--help Show help\n'})}),"\n",(0,i.jsx)(n.h2,{id:"project-structure",children:"Project Structure"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"development-hub/\n\u251c\u2500\u2500 src/development_hub/ # GUI application\n\u2502 \u251c\u2500\u2500 main_window.py # Main window with menus\n\u2502 \u251c\u2500\u2500 project_list.py # Project discovery & context menu\n\u2502 \u251c\u2500\u2500 workspace.py # Splittable pane layout\n\u2502 \u251c\u2500\u2500 terminal_widget.py # PTY terminal with pyte\n\u2502 \u251c\u2500\u2500 dialogs.py # New Project, Settings dialogs\n\u2502 \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 bin/\n\u2502 \u2514\u2500\u2500 new-project # CLI scaffolding script\n\u251c\u2500\u2500 templates/ # Project templates\n\u251c\u2500\u2500 docs/ # Symlink to this folder\n\u251c\u2500\u2500 pyproject.toml\n\u251c\u2500\u2500 CLAUDE.md\n\u2514\u2500\u2500 README.md\n"})}),"\n",(0,i.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.h3,{id:"gitea-api-token",children:"Gitea API Token"}),"\n",(0,i.jsx)(n.p,{children:"The script needs a Gitea API token to create repositories automatically."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Setup options:"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Environment variable: ",(0,i.jsx)(n.code,{children:"export GITEA_TOKEN=your_token"})]}),"\n",(0,i.jsxs)(n.li,{children:["Config file: ",(0,i.jsx)(n.code,{children:"~/.config/development-hub/gitea-token"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The script will prompt for the token on first run and save it automatically."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Creating a token:"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Go to ",(0,i.jsx)(n.a,{href:"https://gitea.brrd.tech/user/settings/applications",children:"https://gitea.brrd.tech/user/settings/applications"})]}),"\n",(0,i.jsx)(n.li,{children:"Generate a new token with 'repo' scope"}),"\n",(0,i.jsx)(n.li,{children:"Copy the token when prompted"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"related-projects",children:"Related Projects"}),"\n",(0,i.jsx)(n.p,{children:"Development Hub manages these projects:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Project"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.a,{href:"../cmdforge/overview",children:"CmdForge"})}),(0,i.jsx)(n.td,{children:"AI-powered CLI tool builder"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.a,{href:"../cascadingdev/overview",children:"CascadingDev"})}),(0,i.jsx)(n.td,{children:"Cascading Development Framework"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.a,{href:"../orchestrated-discussions/overview",children:"Orchestrated Discussions"})}),(0,i.jsx)(n.td,{children:"AI Discussion Framework"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.a,{href:"../artifact-editor/overview",children:"Artifact Editor"})}),(0,i.jsx)(n.td,{children:"Code Artifact Editor"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.a,{href:"../ramble/overview",children:"Ramble"})}),(0,i.jsx)(n.td,{children:"Voice Note Transcription"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["All projects follow the same patterns and can be created using ",(0,i.jsx)(n.code,{children:"new-project"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},8453(e,n,t){t.d(n,{R:()=>l,x:()=>o});var r=t(6540);const i={},s=r.createContext(i);function l(e){const n=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.20c2acbd.js b/assets/js/runtime~main.95ff8c89.js similarity index 96% rename from assets/js/runtime~main.20c2acbd.js rename to assets/js/runtime~main.95ff8c89.js index 8995d79..e58a2ff 100644 --- a/assets/js/runtime~main.20c2acbd.js +++ b/assets/js/runtime~main.95ff8c89.js @@ -1 +1 @@ -(()=>{"use strict";var e,r,t,a,o,n={},i={};function l(e){var r=i[e];if(void 0!==r)return r.exports;var t=i[e]={id:e,loaded:!1,exports:{}};return n[e].call(t.exports,t,t.exports,l),t.loaded=!0,t.exports}l.m=n,l.c=i,e=[],l.O=(r,t,a,o)=>{if(!t){var n=1/0;for(d=0;d=o)&&Object.keys(l.O).every(e=>l.O[e](t[c]))?t.splice(c--,1):(i=!1,o0&&e[d-1][2]>o;d--)e[d]=e[d-1];e[d]=[t,a,o]},l.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return l.d(r,{a:r}),r},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,l.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);l.r(o);var n={};r=r||[null,t({}),t([]),t(t)];for(var i=2&a&&e;("object"==typeof i||"function"==typeof i)&&!~r.indexOf(i);i=t(i))Object.getOwnPropertyNames(i).forEach(r=>n[r]=()=>e[r]);return n.default=()=>e,l.d(o,n),o},l.d=(e,r)=>{for(var t in r)l.o(r,t)&&!l.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},l.f={},l.e=e=>Promise.all(Object.keys(l.f).reduce((r,t)=>(l.f[t](e,r),r),[])),l.u=e=>"assets/js/"+({48:"a94703ab",98:"a7bd4aaa",143:"674bbca5",401:"17896441",413:"1db64337",647:"5e95c892",742:"aba21aa0"}[e]||e)+"."+{48:"b8c77466",98:"3ba34601",143:"1ea8ce94",237:"447ba118",401:"a2525508",413:"e2b8ddcf",647:"a3b66919",742:"4a552a5c"}[e]+".js",l.miniCssF=e=>{},l.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),a={},o="project-public-docs:",l.l=(e,r,t,n)=>{if(a[e])a[e].push(r);else{var i,c;if(void 0!==t)for(var u=document.getElementsByTagName("script"),d=0;d{i.onerror=i.onload=null,clearTimeout(b);var o=a[e];if(delete a[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(e=>e(t)),r)return r(t)},b=setTimeout(s.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=s.bind(null,i.onerror),i.onload=s.bind(null,i.onload),c&&document.head.appendChild(i)}},l.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.p="/rob/development-hub/",l.gca=function(e){return e={17896441:"401",a94703ab:"48",a7bd4aaa:"98","674bbca5":"143","1db64337":"413","5e95c892":"647",aba21aa0:"742"}[e]||e,l.p+l.u(e)},(()=>{var e={354:0,869:0};l.f.j=(r,t)=>{var a=l.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(/^(354|869)$/.test(r))e[r]=0;else{var o=new Promise((t,o)=>a=e[r]=[t,o]);t.push(a[2]=o);var n=l.p+l.u(r),i=new Error;l.l(n,t=>{if(l.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+o+": "+n+")",i.name="ChunkLoadError",i.type=o,i.request=n,a[1](i)}},"chunk-"+r,r)}},l.O.j=r=>0===e[r];var r=(r,t)=>{var a,o,[n,i,c]=t,u=0;if(n.some(r=>0!==e[r])){for(a in i)l.o(i,a)&&(l.m[a]=i[a]);if(c)var d=c(l)}for(r&&r(t);u{"use strict";var e,r,t,a,o,n={},i={};function l(e){var r=i[e];if(void 0!==r)return r.exports;var t=i[e]={id:e,loaded:!1,exports:{}};return n[e].call(t.exports,t,t.exports,l),t.loaded=!0,t.exports}l.m=n,l.c=i,e=[],l.O=(r,t,a,o)=>{if(!t){var n=1/0;for(d=0;d=o)&&Object.keys(l.O).every(e=>l.O[e](t[c]))?t.splice(c--,1):(i=!1,o0&&e[d-1][2]>o;d--)e[d]=e[d-1];e[d]=[t,a,o]},l.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return l.d(r,{a:r}),r},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,l.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);l.r(o);var n={};r=r||[null,t({}),t([]),t(t)];for(var i=2&a&&e;("object"==typeof i||"function"==typeof i)&&!~r.indexOf(i);i=t(i))Object.getOwnPropertyNames(i).forEach(r=>n[r]=()=>e[r]);return n.default=()=>e,l.d(o,n),o},l.d=(e,r)=>{for(var t in r)l.o(r,t)&&!l.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},l.f={},l.e=e=>Promise.all(Object.keys(l.f).reduce((r,t)=>(l.f[t](e,r),r),[])),l.u=e=>"assets/js/"+({48:"a94703ab",98:"a7bd4aaa",143:"674bbca5",401:"17896441",413:"1db64337",647:"5e95c892",742:"aba21aa0"}[e]||e)+"."+{48:"b8c77466",98:"3ba34601",143:"1ea8ce94",237:"447ba118",401:"a2525508",413:"2ac055a2",647:"a3b66919",742:"4a552a5c"}[e]+".js",l.miniCssF=e=>{},l.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),a={},o="project-public-docs:",l.l=(e,r,t,n)=>{if(a[e])a[e].push(r);else{var i,c;if(void 0!==t)for(var u=document.getElementsByTagName("script"),d=0;d{i.onerror=i.onload=null,clearTimeout(b);var o=a[e];if(delete a[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(e=>e(t)),r)return r(t)},b=setTimeout(s.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=s.bind(null,i.onerror),i.onload=s.bind(null,i.onload),c&&document.head.appendChild(i)}},l.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.p="/rob/development-hub/",l.gca=function(e){return e={17896441:"401",a94703ab:"48",a7bd4aaa:"98","674bbca5":"143","1db64337":"413","5e95c892":"647",aba21aa0:"742"}[e]||e,l.p+l.u(e)},(()=>{var e={354:0,869:0};l.f.j=(r,t)=>{var a=l.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(/^(354|869)$/.test(r))e[r]=0;else{var o=new Promise((t,o)=>a=e[r]=[t,o]);t.push(a[2]=o);var n=l.p+l.u(r),i=new Error;l.l(n,t=>{if(l.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+o+": "+n+")",i.name="ChunkLoadError",i.type=o,i.request=n,a[1](i)}},"chunk-"+r,r)}},l.O.j=r=>0===e[r];var r=(r,t)=>{var a,o,[n,i,c]=t,u=0;if(n.some(r=>0!==e[r])){for(a in i)l.o(i,a)&&(l.m[a]=i[a]);if(c)var d=c(l)}for(r&&r(t);u Development Hub - + @@ -34,7 +34,7 @@
  • New Project Dialog - Create projects with optional Ramble voice input
  • Keyboard Shortcuts

    -
    ShortcutAction
    Ctrl+Shift+TNew terminal tab
    Ctrl+Shift+WClose current tab
    Ctrl+Shift+DSplit horizontal
    Ctrl+Shift+ESplit vertical
    Ctrl+Alt+Left/RightSwitch panes
    Ctrl+BToggle project panel
    Ctrl+NNew project dialog
    +
    ShortcutAction
    Ctrl+Shift+TNew terminal tab
    Ctrl+Shift+WClose current tab
    Ctrl+Shift+DSplit horizontal
    Ctrl+Shift+ESplit vertical
    Ctrl+Shift+PClose active pane
    Ctrl+Alt+Left/RightSwitch panes
    Ctrl+BToggle project panel
    Ctrl+NNew project dialog
    F5Refresh project list

    The new-project Script

    The main tool is new-project, which automates creating a new project in the ecosystem:

    new-project my-tool --title "My Tool" --tagline "Does useful things"
    @@ -55,8 +55,12 @@

    Usage

    # Full specification
    new-project myproject --title "My Project" --tagline "Short description"

    # Interactive mode (prompts for title/tagline)
    new-project myproject

    # Options
    --dry-run Show what would happen without making changes
    --skip-gitea Skip Gitea repo creation (for offline use)
    --help Show help
    +

    Architecture

    +
    src/development_hub/
    ├── __init__.py
    ├── __main__.py # Entry point
    ├── app.py # QApplication subclass
    ├── main_window.py # Main window with menus
    ├── project_list.py # Left panel - project discovery & context menu
    ├── workspace.py # Right panel - splittable panes with tabs
    ├── terminal_widget.py # PTY terminal with pyte emulation
    ├── project_discovery.py # Parse projects from build-public-docs.sh
    ├── dialogs.py # New Project (with Ramble), Settings dialogs
    ├── settings.py # JSON persistence for settings & session
    └── styles.py # Dark theme stylesheet
    +

    Key Classes

    +
    ClassFilePurpose
    MainWindowmain_window.pyQMainWindow with menus, splitter layout
    ProjectListWidgetproject_list.pyProject list with context menu actions
    WorkspaceManagerworkspace.pyManages splittable pane layout
    PaneWidgetworkspace.pyTab container within a pane
    TerminalWidgetterminal_widget.pyPTY-based terminal with pyte screen emulation

    Project Structure

    -
    development-hub/
    ├── src/development_hub/ # GUI application
    │ ├── main_window.py # Main window with menus
    │ ├── project_list.py # Project discovery & context menu
    │ ├── workspace.py # Splittable pane layout
    │ ├── terminal_widget.py # PTY terminal with pyte
    │ ├── dialogs.py # New Project, Settings dialogs
    │ └── ...
    ├── bin/
    │ └── new-project # CLI scaffolding script
    ├── templates/ # Project templates
    ├── docs/ # Symlink to this folder
    ├── pyproject.toml
    ├── CLAUDE.md
    └── README.md
    +
    development-hub/
    ├── src/development_hub/ # GUI application (see Architecture above)
    ├── bin/
    │ └── new-project # CLI scaffolding script
    ├── templates/
    │ ├── gitignore.template # Python .gitignore with docs exclusion
    │ ├── CLAUDE.md.template # AI context file
    │ ├── README.md.template # Basic README
    │ ├── pyproject.toml.template
    │ ├── overview.md.template # Docs overview
    │ └── updating-documentation.md.template
    ├── docs/ # Symlink to project-docs
    ├── pyproject.toml # Python packaging with PyQt6 dep
    ├── CLAUDE.md
    └── README.md

    Configuration

    Gitea API Token

    The script needs a Gitea API token to create repositories automatically.

    @@ -72,9 +76,12 @@
  • Generate a new token with 'repo' scope
  • Copy the token when prompted
  • +

    Template Placeholders

    +

    When creating new projects, templates use these placeholders:

    +
    PlaceholderDescriptionExample
    {{PROJECT_NAME}}Lowercase project namemy-tool
    {{PROJECT_TITLE}}Display titleMy Tool
    {{PROJECT_TAGLINE}}Short descriptionDoes useful things
    {{YEAR}}Current year2026
    {{DATE}}Creation date2026-01-06
    {{GITEA_URL}}Gitea server URLhttps://gitea.brrd.tech
    {{GITEA_OWNER}}Repository ownerrob

    Development Hub manages these projects:

    ProjectDescription
    CmdForgeAI-powered CLI tool builder
    CascadingDevCascading Development Framework
    Orchestrated DiscussionsAI Discussion Framework
    Artifact EditorCode Artifact Editor
    RambleVoice Note Transcription
    -

    All projects follow the same patterns and can be created using new-project.

    +

    All projects follow the same patterns and can be created using new-project.

    \ No newline at end of file