projax 1.3.10 → 1.3.11
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/dist/api/database.d.ts +1 -0
- package/dist/api/database.d.ts.map +1 -1
- package/dist/api/database.js +19 -1
- package/dist/api/database.js.map +1 -1
- package/dist/api/package.json +1 -3
- package/dist/api/routes/projects.d.ts.map +1 -1
- package/dist/api/routes/projects.js +21 -7
- package/dist/api/routes/projects.js.map +1 -1
- package/dist/api/types.d.ts +1 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/core/database.d.ts +1 -0
- package/dist/electron/core/database.d.ts +1 -0
- package/dist/electron/main.js +37 -40
- package/dist/electron/preload.d.ts +1 -0
- package/dist/electron/preload.js +1 -0
- package/dist/electron/renderer/assets/index-59AhiV_K.css +1 -0
- package/dist/electron/renderer/assets/index-BGV4pGGx.js +46 -0
- package/dist/electron/renderer/assets/index-BT_e6Msc.js +46 -0
- package/dist/electron/renderer/assets/index-Bu1Gyxs5.js +46 -0
- package/dist/electron/renderer/assets/index-C9bA-P-3.css +1 -0
- package/dist/electron/renderer/assets/index-CJlaCHj5.css +1 -0
- package/dist/electron/renderer/assets/index-CTxba8Fs.js +61 -0
- package/dist/electron/renderer/assets/index-C_6HLZ3g.js +46 -0
- package/dist/electron/renderer/assets/index-Cejn7BcN.js +46 -0
- package/dist/electron/renderer/assets/index-CfEtNYYJ.js +46 -0
- package/dist/electron/renderer/assets/index-CgMqjX1w.css +1 -0
- package/dist/electron/renderer/assets/index-CknIIag9.js +61 -0
- package/dist/electron/renderer/assets/index-Csg1hzAW.js +61 -0
- package/dist/electron/renderer/assets/index-CtD66H57.js +46 -0
- package/dist/electron/renderer/assets/index-Cz5tpCH_.css +1 -0
- package/dist/electron/renderer/assets/index-CzSAm4rV.js +46 -0
- package/dist/electron/renderer/assets/index-D7t8lZFK.js +46 -0
- package/dist/electron/renderer/assets/index-DAfjuYKX.js +61 -0
- package/dist/electron/renderer/assets/index-DPZN2_De.css +1 -0
- package/dist/electron/renderer/assets/index-DZfKv3qb.js +61 -0
- package/dist/electron/renderer/assets/index-DmLmfvuw.css +1 -0
- package/dist/electron/renderer/assets/index-DyhB_yB5.js +61 -0
- package/dist/electron/renderer/assets/index-IV4RpG6x.css +1 -0
- package/dist/electron/renderer/assets/index-O6z5EG_7.js +46 -0
- package/dist/electron/renderer/assets/index-_QUmEi7R.css +1 -0
- package/dist/electron/renderer/index.html +2 -2
- package/dist/index.js +276 -1
- package/package.json +15 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.project-list{padding:.75rem}.project-list-loading,.project-list-empty{padding:2rem;text-align:center;color:var(--text-secondary)}.project-list-empty .hint{font-size:12px;color:var(--text-tertiary);margin-top:.5rem}.project-item{padding:.875rem;margin-bottom:.5rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;cursor:pointer;transition:all .15s ease;position:relative}.project-item:before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:transparent;transition:background .15s ease}.project-item:hover{background:var(--bg-hover);border-color:var(--border-hover);transform:translate(2px)}.project-item:hover:before{background:var(--accent-cyan)}.project-item.selected{background:var(--bg-hover);border-color:var(--accent-cyan);box-shadow:var(--shadow-sm)}.project-item.keyboard-focused{outline:2px solid var(--accent-cyan);outline-offset:-2px;background:var(--bg-hover)}.project-item.selected:before{background:var(--accent-cyan)}.project-item-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:.5rem;gap:.5rem}.project-name{font-size:13px;font-weight:600;color:var(--text-primary);margin:0;flex:1;font-family:inherit;letter-spacing:.2px}.project-remove-btn{background:transparent;border:1px solid transparent;font-size:18px;color:var(--text-tertiary);cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:3px;transition:all .15s ease;flex-shrink:0;line-height:1}.project-remove-btn:hover{background:#ff52521a;color:#ff5252;border-color:#ff52524d}.project-path{font-size:11px;color:var(--text-tertiary);margin:.25rem 0;word-break:break-all;font-family:SF Mono,Monaco,monospace;opacity:.8}.project-meta{display:flex;justify-content:space-between;align-items:center;margin-top:.5rem;font-size:11px;color:var(--text-tertiary);gap:.5rem}.project-tags{display:flex;flex-wrap:wrap;gap:.375rem;margin-top:.5rem}.project-tag{background:var(--bg-hover);border:1px solid var(--border-color);padding:.125rem .5rem;border-radius:3px;font-size:10px;font-weight:500;color:var(--accent-cyan);font-family:SF Mono,Monaco,monospace;text-transform:uppercase;letter-spacing:.3px}.project-scanned{flex:1;font-family:SF Mono,Monaco,monospace}.project-scan-btn{background:transparent;border:1px solid var(--border-color);font-size:12px;cursor:pointer;padding:.25rem .5rem;border-radius:3px;transition:all .15s ease;color:var(--text-secondary);font-family:inherit}.project-scan-btn:hover:not(:disabled){background:var(--bg-hover);border-color:var(--accent-green);color:var(--accent-green)}.project-scan-btn:disabled{opacity:.3;cursor:not-allowed}.running-indicator-dot{color:var(--accent-green);margin-right:.5rem;font-size:10px;animation:pulse 2s infinite}.project-item.running:before{background:var(--accent-green)}.running-count{background:var(--accent-green);color:var(--bg-primary);padding:.125rem .5rem;border-radius:10px;font-size:10px;font-weight:600;font-family:SF Mono,Monaco,monospace}.running-ports{display:flex;gap:.25rem;flex-wrap:wrap}.port-badge{background:var(--accent-blue);color:var(--bg-primary);padding:.125rem .5rem;border-radius:3px;font-size:10px;font-weight:600;font-family:SF Mono,Monaco,monospace}.project-urls-section{background:var(--bg-secondary);padding:1.25rem;border-radius:4px;border:1px solid var(--border-color);margin-bottom:1.5rem}.urls-list{display:flex;flex-direction:column;gap:.5rem}.url-item{padding:.875rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;transition:all .15s ease;display:flex;justify-content:space-between;align-items:center;gap:1rem}.url-item:hover{background:var(--bg-hover);border-color:var(--border-hover)}.url-text{font-family:SF Mono,Monaco,monospace;font-size:12px;color:var(--accent-cyan);flex:1;word-break:break-all;cursor:pointer;text-decoration:underline}.url-text:hover{color:var(--accent-blue)}.project-details{max-width:1000px}.project-details-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.5rem;padding-bottom:1rem;border-bottom:1px solid var(--border-color);gap:1rem}.project-details-header h2{font-size:18px;color:var(--text-primary);margin-bottom:.5rem;font-weight:600;font-family:inherit;letter-spacing:.3px}.project-name-editable{cursor:pointer;transition:color .15s ease}.project-name-editable:hover{color:var(--accent-cyan)}.project-name-edit{margin-bottom:.5rem}.project-name-input{background:var(--bg-tertiary);border:1px solid var(--accent-cyan);border-radius:4px;padding:.5rem;font-size:18px;font-weight:600;color:var(--text-primary);font-family:inherit;width:100%;max-width:400px}.project-name-input:focus{outline:none;box-shadow:0 0 0 2px #39c5cf33}.project-description-edit{margin-bottom:.5rem}.project-description-input{background:var(--bg-tertiary);border:1px solid var(--accent-cyan);border-radius:4px;padding:.5rem;font-size:13px;color:var(--text-primary);font-family:inherit;width:100%;max-width:600px;resize:vertical;min-height:60px}.project-description-input:focus{outline:none;box-shadow:0 0 0 2px #39c5cf33}.project-description{cursor:pointer;color:var(--text-secondary);font-size:13px;transition:color .15s ease;margin-bottom:.5rem}.project-description:hover{color:var(--text-primary)}.header-actions-group{display:flex;gap:.5rem;align-items:center}.project-path{color:var(--text-tertiary);font-size:11px;word-break:break-all;font-family:SF Mono,Monaco,monospace;opacity:.8}.project-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.75rem;margin-bottom:1.5rem}.stat-card{background:var(--bg-secondary);padding:1rem;border-radius:4px;border:1px solid var(--border-color);text-align:left;transition:all .15s ease}.stat-card:hover{border-color:var(--border-hover);background:var(--bg-tertiary)}.stat-value{font-size:24px;font-weight:600;color:var(--accent-cyan);margin-bottom:.25rem;font-family:SF Mono,Monaco,monospace;line-height:1.2}.stat-label{font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.5px;font-weight:500}.framework-breakdown{background:var(--bg-secondary);padding:1.25rem;border-radius:4px;border:1px solid var(--border-color);margin-bottom:1.5rem}.framework-breakdown h3{font-size:13px;color:var(--text-primary);margin-bottom:1rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;font-family:inherit}.framework-list{display:flex;flex-wrap:wrap;gap:.5rem}.framework-item{display:flex;align-items:center;gap:.5rem;padding:.375rem .75rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:3px;transition:all .15s ease}.framework-item:hover{border-color:var(--accent-purple);background:var(--bg-hover)}.framework-name{font-weight:500;color:var(--text-primary);font-size:12px;font-family:SF Mono,Monaco,monospace}.framework-count{background:var(--accent-purple);color:var(--bg-primary);padding:.125rem .5rem;border-radius:2px;font-size:11px;font-weight:600;font-family:SF Mono,Monaco,monospace}.tests-section{background:var(--bg-secondary);padding:1.25rem;border-radius:4px;border:1px solid var(--border-color);margin-bottom:1.5rem}.tests-section h3{font-size:13px;color:var(--text-primary);margin-bottom:1rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;font-family:inherit}.no-tests{padding:2rem;text-align:center;color:var(--text-tertiary);font-size:12px}.tests-list{display:flex;flex-direction:column;gap:.5rem}.test-item{padding:.875rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;transition:all .15s ease}.test-item:hover{background:var(--bg-hover);border-color:var(--border-hover);transform:translate(2px)}.test-file{display:flex;justify-content:space-between;align-items:center;margin-bottom:.5rem;gap:.75rem}.test-path{font-family:SF Mono,Monaco,monospace;font-size:12px;color:var(--text-primary);flex:1;word-break:break-all}.test-framework{background:var(--accent-blue);color:var(--bg-primary);padding:.25rem .5rem;border-radius:3px;font-size:10px;font-weight:600;font-family:SF Mono,Monaco,monospace;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0}.test-status{font-size:11px;color:var(--text-tertiary);font-family:SF Mono,Monaco,monospace}.jenkins-placeholder{background:var(--bg-secondary);padding:1.25rem;border-radius:4px;border:1px dashed var(--border-color);opacity:.6}.jenkins-placeholder h3{font-size:13px;color:var(--text-secondary);margin-bottom:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;font-family:inherit}.placeholder-text{color:var(--text-tertiary);font-style:italic;font-size:12px;line-height:1.6}.danger-zone{background:#f851490d;padding:1.25rem;border-radius:4px;border:1px solid rgba(248,81,73,.3);margin-top:1.5rem}.danger-zone h3{font-size:13px;color:#f85149;margin-bottom:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;font-family:inherit}.danger-zone-text{color:var(--text-secondary);font-size:12px;line-height:1.6;margin-bottom:1rem}.danger-zone .btn-danger{background:transparent;border:1px solid #f85149;color:#f85149}.danger-zone .btn-danger:hover:not(:disabled){background:#f85149;color:var(--bg-primary)}.btn-small{padding:.375rem .75rem;font-size:11px}.tags-section{background:var(--bg-secondary);padding:1.25rem;border-radius:4px;border:1px solid var(--border-color);margin-bottom:1.5rem}.tags-content{margin-top:.75rem}.tags-list{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}.tag-item{background:var(--bg-tertiary);border:1px solid var(--border-color);padding:.375rem .375rem .375rem .625rem;border-radius:4px;font-size:11px;font-weight:500;color:var(--accent-cyan);font-family:SF Mono,Monaco,monospace;text-transform:uppercase;letter-spacing:.3px;display:flex;align-items:center;gap:.375rem;transition:all .15s ease}.tag-item:hover{border-color:var(--accent-cyan)}.tag-remove{background:none;border:none;color:var(--text-tertiary);cursor:pointer;padding:0 4px;font-size:16px;line-height:1;transition:color .15s ease}.tag-remove:hover{color:#f85149}.tag-add-btn{background:transparent;border:1px dashed var(--border-color);padding:.375rem .75rem;border-radius:4px;font-size:11px;font-weight:500;color:var(--text-secondary);cursor:pointer;transition:all .15s ease;text-transform:uppercase;letter-spacing:.3px}.tag-add-btn:hover{border-color:var(--accent-cyan);color:var(--accent-cyan);background:var(--bg-tertiary)}.tag-input-wrapper{position:relative;display:inline-block}.tag-input{background:var(--bg-tertiary);border:1px solid var(--accent-cyan);border-radius:4px;padding:.375rem .625rem;font-size:11px;font-family:SF Mono,Monaco,monospace;color:var(--text-primary);min-width:120px;outline:none}.tag-input:focus{box-shadow:0 0 0 2px #39c5cf33}.tag-suggestions{position:absolute;top:calc(100% + 4px);left:0;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;box-shadow:var(--shadow-md);z-index:100;min-width:100%;max-width:200px}.tag-suggestion{padding:.5rem .75rem;cursor:pointer;font-size:11px;color:var(--text-primary);font-family:SF Mono,Monaco,monospace;transition:all .15s ease}.tag-suggestion:first-child{border-radius:4px 4px 0 0}.tag-suggestion:last-child{border-radius:0 0 4px 4px}.tag-suggestion:hover{background:var(--bg-hover);color:var(--accent-cyan)}.ports-section,.scripts-section,.running-processes-section{background:var(--bg-secondary);padding:1.25rem;border-radius:4px;border:1px solid var(--border-color);margin-bottom:1.5rem}.section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.section-header h3{font-size:13px;color:var(--text-primary);font-weight:600;text-transform:uppercase;letter-spacing:.5px;font-family:inherit;margin:0}.project-type-badge{background:var(--bg-tertiary);border:1px solid var(--border-color);padding:.25rem .5rem;border-radius:3px;font-size:10px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.3px;font-family:SF Mono,Monaco,monospace}.ports-list,.scripts-list,.processes-list{display:flex;flex-direction:column;gap:.5rem}.port-item{padding:.875rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;transition:all .15s ease}.port-item:hover{background:var(--bg-hover);border-color:var(--border-hover)}.port-info{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.port-number{font-family:SF Mono,Monaco,monospace;font-size:13px;font-weight:600;color:var(--accent-cyan)}.port-script{font-family:SF Mono,Monaco,monospace;font-size:11px;color:var(--text-secondary)}.port-source{font-family:SF Mono,Monaco,monospace;font-size:11px;color:var(--text-tertiary);flex:1}.script-item{padding:.875rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;transition:all .15s ease;display:flex;justify-content:space-between;align-items:center;gap:1rem}.script-item:hover{background:var(--bg-hover);border-color:var(--border-hover)}.script-info{display:flex;align-items:center;gap:.75rem;flex:1;flex-wrap:wrap}.script-name{font-family:SF Mono,Monaco,monospace;font-size:13px;font-weight:600;color:var(--text-primary);min-width:80px}.script-command{font-family:SF Mono,Monaco,monospace;font-size:11px;color:var(--text-secondary);flex:1;word-break:break-all}.script-runner{background:var(--bg-hover);border:1px solid var(--border-color);padding:.25rem .5rem;border-radius:3px;font-size:10px;font-weight:600;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.3px;font-family:SF Mono,Monaco,monospace;flex-shrink:0}.script-actions{display:flex;gap:.5rem;flex-shrink:0}.loading-state,.no-scripts{padding:2rem;text-align:center;color:var(--text-tertiary);font-size:12px}.running-indicator{color:var(--accent-green);font-size:12px;margin-right:.5rem;animation:pulse 2s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.process-item{padding:.875rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;transition:all .15s ease;display:flex;justify-content:space-between;align-items:center;gap:1rem}.process-item:hover{background:var(--bg-hover);border-color:var(--border-hover)}.process-info{display:flex;align-items:center;gap:.75rem;flex:1;flex-wrap:wrap}.process-name{font-family:SF Mono,Monaco,monospace;font-size:13px;font-weight:600;color:var(--text-primary);min-width:100px}.process-pid{font-family:SF Mono,Monaco,monospace;font-size:11px;color:var(--text-secondary)}.process-uptime{font-family:SF Mono,Monaco,monospace;font-size:11px;color:var(--text-tertiary)}.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content{background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:4px;width:90%;max-width:500px;box-shadow:var(--shadow-lg);animation:modalSlideIn .2s ease}@keyframes modalSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:1.25rem;border-bottom:1px solid var(--border-color)}.modal-header h2{font-size:14px;color:var(--text-primary);margin:0;font-weight:600;text-transform:uppercase;letter-spacing:.5px;font-family:inherit}.modal-close{background:transparent;border:1px solid transparent;font-size:20px;color:var(--text-tertiary);cursor:pointer;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:3px;transition:all .15s ease;line-height:1}.modal-close:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--border-color)}.modal-content form{padding:1.25rem}.form-group{margin-bottom:1.25rem}.form-group label{display:block;margin-bottom:.5rem;font-weight:500;color:var(--text-primary);font-size:12px;text-transform:uppercase;letter-spacing:.3px;font-family:inherit}.path-input-group{display:flex;gap:.5rem}.path-input-group input{flex:1;padding:.625rem;border:1px solid var(--border-color);border-radius:4px;font-size:12px;font-family:SF Mono,Monaco,monospace;background:var(--bg-tertiary);color:var(--text-primary);transition:all .15s ease}.path-input-group input::placeholder{color:var(--text-tertiary);opacity:.6}.path-input-group input:focus{outline:none;border-color:var(--accent-cyan);box-shadow:0 0 0 2px #39c5cf1a;background:var(--bg-hover)}.path-input-group input:disabled{background:var(--bg-primary);cursor:not-allowed;opacity:.5}.modal-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.25rem}.project-search{padding:12px;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);position:sticky;top:0;z-index:10}.search-input-group{display:flex;gap:8px;position:relative}.search-input-wrapper{flex:1;position:relative;display:flex;align-items:center}.search-input{flex:1;padding:8px 36px 8px 12px;border:1px solid var(--border-color);border-radius:4px;font-size:14px;outline:none;transition:border-color .2s;background:var(--bg-tertiary);color:var(--text-primary)}.sort-icon-btn{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--text-tertiary);cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:3px;transition:all .15s ease}.sort-icon-btn:hover{color:var(--text-primary);background:var(--bg-hover)}.sort-menu{position:absolute;top:calc(100% + 4px);right:0;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;box-shadow:var(--shadow-md);z-index:100;min-width:180px;padding:4px}.sort-menu-item{padding:8px 12px;cursor:pointer;border-radius:3px;font-size:13px;color:var(--text-primary);display:flex;justify-content:space-between;align-items:center;transition:all .15s ease}.sort-menu-item:hover{background:var(--bg-hover)}.sort-menu-item.active{background:var(--bg-hover);color:var(--accent-cyan)}.sort-menu-item .checkmark{color:var(--accent-green);font-size:12px;margin-left:8px}.search-input:focus{border-color:var(--accent-cyan)}.search-input::placeholder{color:var(--text-tertiary)}.search-filter{padding:8px 12px;border:1px solid var(--border-color);border-radius:4px;font-size:14px;background:var(--bg-tertiary);color:var(--text-primary);cursor:pointer;outline:none;transition:border-color .2s}.search-filter:focus{border-color:var(--accent-cyan)}.search-filter:hover{border-color:var(--border-hover);background:var(--bg-hover)}.settings-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.settings-modal{background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;width:90%;max-width:600px;max-height:90vh;display:flex;flex-direction:column;box-shadow:var(--shadow-lg)}.settings-header{display:flex;justify-content:space-between;align-items:center;padding:1.5rem;border-bottom:1px solid var(--border-color)}.settings-header h2{font-size:18px;font-weight:600;color:var(--text-primary);margin:0}.settings-close-btn{background:none;border:none;color:var(--text-secondary);font-size:24px;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .15s ease}.settings-close-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.settings-content{padding:1.5rem;overflow-y:auto;flex:1}.settings-section{margin-bottom:2rem}.settings-section:last-child{margin-bottom:0}.settings-section h3{font-size:14px;font-weight:600;color:var(--text-primary);margin-bottom:1rem;text-transform:uppercase;letter-spacing:.5px}.settings-field{margin-bottom:1rem}.settings-field:last-child{margin-bottom:0}.settings-field label{display:block;font-size:12px;color:var(--text-secondary);margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.3px}.settings-select,.settings-input{width:100%;padding:.75rem;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;color:var(--text-primary);font-size:13px;font-family:inherit;outline:none;transition:border-color .15s ease}.settings-select:focus,.settings-input:focus{border-color:var(--accent-cyan)}.settings-input{font-family:SF Mono,Monaco,monospace}.settings-footer{display:flex;justify-content:flex-end;gap:.75rem;padding:1.5rem;border-top:1px solid var(--border-color)}.loading-state{padding:3rem;text-align:center;color:var(--text-tertiary);font-size:13px}.app-header{-webkit-app-region:drag;-webkit-user-select:none;user-select:none;display:flex;align-items:center;gap:1rem}.app-header button,.app-header .btn,.app-header .btn-link,.app-header .header-actions{-webkit-app-region:no-drag}.status-bar{background:var(--bg-secondary);border-top:1px solid var(--border-color);padding:.5rem 1.5rem;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;font-size:11px;font-family:SF Mono,Monaco,monospace}.status-bar-content{display:flex;align-items:center;gap:1rem;width:100%;justify-content:space-between}.status-indicator{display:flex;align-items:center;gap:.5rem}.status-dot{width:6px;height:6px;border-radius:50%;display:inline-block}.status-dot.connected{background:var(--accent-green);box-shadow:0 0 4px var(--accent-green)}.status-dot.disconnected{background:#f85149;box-shadow:0 0 4px #f85149}.status-text{color:var(--text-secondary);font-size:11px;text-transform:uppercase;letter-spacing:.5px}.api-port{color:var(--text-tertiary);font-size:11px;font-family:SF Mono,Monaco,monospace}.app{display:flex;flex-direction:column;height:100vh;overflow:hidden;background:var(--bg-primary)}.app-header{background:var(--bg-secondary);border-bottom:1px solid var(--border-color);padding:.5rem 1.5rem;display:flex;align-items:center;justify-content:center;gap:1rem;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);position:relative;z-index:10;flex-shrink:0}.app-header:after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 0%,var(--accent-cyan) 50%,transparent 100%);opacity:.3}.app-logo{margin:0;font-size:12px;font-weight:600;letter-spacing:1.5px;color:var(--accent-cyan);position:absolute;left:50%;transform:translate(-50%)}.header-actions{display:flex;gap:1.5rem;margin-left:auto}.btn-link{padding:0;border:none;background:none;font-size:11px;font-weight:500;cursor:pointer;transition:color .15s ease;font-family:inherit;letter-spacing:.3px;text-transform:uppercase;color:var(--text-secondary);-webkit-app-region:no-drag}.btn-link:hover:not(:disabled){color:var(--text-primary)}.btn-link:disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.btn-link-primary{color:var(--accent-cyan)}.btn-link-primary:hover:not(:disabled){color:var(--accent-blue)}.btn{padding:.5rem 1rem;border:1px solid var(--border-color);border-radius:4px;font-size:12px;font-weight:500;cursor:pointer;transition:all .15s ease;font-family:inherit;letter-spacing:.3px;text-transform:uppercase;background:var(--bg-tertiary);color:var(--text-primary)}.btn:disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.btn-primary{background:var(--accent-cyan);color:var(--bg-primary);border-color:var(--accent-cyan);font-weight:600}.btn-primary:hover:not(:disabled){background:var(--accent-blue);border-color:var(--accent-blue);transform:translateY(-1px);box-shadow:var(--shadow-sm)}.btn-secondary{background:transparent;color:var(--text-secondary);border-color:var(--border-color)}.btn-secondary:hover:not(:disabled){background:var(--bg-hover);border-color:var(--border-hover);color:var(--text-primary)}.btn-danger{background:transparent;color:#f85149;border-color:#f85149}.btn-danger:hover:not(:disabled){background:#f851491a;border-color:#f85149;color:#f85149}.app-content{display:flex;flex:1;overflow:hidden;position:relative}.react-resizable-handle{position:absolute;width:4px;right:-2px;top:0;bottom:0;cursor:col-resize;background:transparent;z-index:10}.react-resizable-handle:hover{background:var(--accent-cyan);opacity:.3}.react-resizable-handle:active{background:var(--accent-cyan);opacity:.6}.sidebar{width:100%;height:100%;background:var(--bg-secondary);border-right:1px solid var(--border-color);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column}.sidebar::-webkit-scrollbar{width:6px}.sidebar::-webkit-scrollbar-track{background:var(--bg-primary)}.sidebar::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:3px}.sidebar::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}.main-content{flex:1;overflow-y:auto;padding:1.5rem;background:var(--bg-primary)}.main-content::-webkit-scrollbar{width:6px}.main-content::-webkit-scrollbar-track{background:var(--bg-primary)}.main-content::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:3px}.main-content::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--text-secondary);text-align:center;padding:2rem}.empty-state h2{margin-bottom:.5rem;color:var(--text-primary);font-size:16px;font-weight:500}.empty-state p{color:var(--text-tertiary);font-size:13px}.app-footer{background:var(--bg-secondary);border-top:1px solid var(--border-color);padding:.5rem 1.5rem;flex-shrink:0}*{margin:0;padding:0;box-sizing:border-box}:root{--bg-primary: #0d1117;--bg-secondary: #161b22;--bg-tertiary: #1c2128;--bg-hover: #21262d;--border-color: #30363d;--border-hover: #484f58;--text-primary: #c9d1d9;--text-secondary: #8b949e;--text-tertiary: #6e7681;--accent-cyan: #39c5cf;--accent-blue: #58a6ff;--accent-green: #3fb950;--accent-purple: #bc8cff;--accent-orange: #ffa657;--shadow-sm: 0 1px 3px rgba(0, 0, 0, .3);--shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--shadow-lg: 0 8px 24px rgba(0, 0, 0, .5)}body{font-family:SF Mono,Monaco,Inconsolata,Fira Code,Fira Mono,Droid Sans Mono,Source Code Pro,Menlo,Consolas,Courier New,monospace;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:var(--bg-primary);color:var(--text-primary);font-size:13px;line-height:1.5;-webkit-user-select:none;user-select:none}input,textarea,[contenteditable=true],[contenteditable=""]{-webkit-user-select:text;user-select:text}code{font-family:SF Mono,Monaco,Inconsolata,Fira Code,Fira Mono,Droid Sans Mono,Source Code Pro,Menlo,Consolas,Courier New,monospace}#root{width:100%;height:100vh}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' http://localhost:* ws://localhost:*;" />
|
|
7
7
|
<title>projax</title>
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-DAfjuYKX.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-59AhiV_K.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/dist/index.js
CHANGED
|
@@ -249,6 +249,8 @@ program
|
|
|
249
249
|
.description('Add a project to the dashboard')
|
|
250
250
|
.argument('[path]', 'Path to the project directory')
|
|
251
251
|
.option('-n, --name <name>', 'Custom name for the project (defaults to directory name)')
|
|
252
|
+
.option('-d, --description <description>', 'Description for the project')
|
|
253
|
+
.option('--tags <tags>', 'Comma-separated list of tags')
|
|
252
254
|
.action(async (projectPath, options) => {
|
|
253
255
|
try {
|
|
254
256
|
let finalPath = projectPath;
|
|
@@ -316,8 +318,25 @@ program
|
|
|
316
318
|
projectName = nameAnswer.name.trim();
|
|
317
319
|
}
|
|
318
320
|
const project = db.addProject(projectName, resolvedPath);
|
|
321
|
+
// Update description and tags if provided
|
|
322
|
+
const updates = {};
|
|
323
|
+
if (options?.description !== undefined) {
|
|
324
|
+
updates.description = options.description.trim() || null;
|
|
325
|
+
}
|
|
326
|
+
if (options?.tags) {
|
|
327
|
+
updates.tags = options.tags.split(',').map(t => t.trim()).filter(Boolean);
|
|
328
|
+
}
|
|
329
|
+
if (Object.keys(updates).length > 0) {
|
|
330
|
+
db.updateProject(project.id, updates);
|
|
331
|
+
}
|
|
319
332
|
console.log(`✓ Added project: ${project.name} (ID: ${project.id})`);
|
|
320
333
|
console.log(` Path: ${project.path}`);
|
|
334
|
+
if (options?.description) {
|
|
335
|
+
console.log(` Description: ${options.description}`);
|
|
336
|
+
}
|
|
337
|
+
if (options?.tags) {
|
|
338
|
+
console.log(` Tags: ${options.tags}`);
|
|
339
|
+
}
|
|
321
340
|
// Ask if user wants to scan for tests
|
|
322
341
|
const inquirer = (await Promise.resolve().then(() => __importStar(require('inquirer')))).default;
|
|
323
342
|
const scanAnswer = await inquirer.prompt([
|
|
@@ -570,6 +589,262 @@ program
|
|
|
570
589
|
process.exit(1);
|
|
571
590
|
}
|
|
572
591
|
});
|
|
592
|
+
// Description command
|
|
593
|
+
program
|
|
594
|
+
.command('desc')
|
|
595
|
+
.alias('description')
|
|
596
|
+
.description('Set or get project description')
|
|
597
|
+
.argument('<project>', 'Project ID or name')
|
|
598
|
+
.argument('[description]', 'New description (leave empty to view current)')
|
|
599
|
+
.action((projectIdentifier, description) => {
|
|
600
|
+
try {
|
|
601
|
+
const db = (0, core_bridge_1.getDatabaseManager)();
|
|
602
|
+
const projects = (0, core_bridge_1.getAllProjects)();
|
|
603
|
+
const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
|
|
604
|
+
if (!project) {
|
|
605
|
+
console.error(`Error: Project not found: ${projectIdentifier}`);
|
|
606
|
+
process.exit(1);
|
|
607
|
+
}
|
|
608
|
+
if (description === undefined) {
|
|
609
|
+
// Show current description
|
|
610
|
+
if (project.description) {
|
|
611
|
+
console.log(project.description);
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
console.log('No description set.');
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
// Update description
|
|
619
|
+
const trimmedDesc = description.trim() || null;
|
|
620
|
+
db.updateProject(project.id, { description: trimmedDesc });
|
|
621
|
+
if (trimmedDesc) {
|
|
622
|
+
console.log(`✓ Updated description for "${project.name}": ${trimmedDesc}`);
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
console.log(`✓ Removed description for "${project.name}"`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
catch (error) {
|
|
630
|
+
console.error('Error managing description:', error instanceof Error ? error.message : error);
|
|
631
|
+
process.exit(1);
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
// Tags command
|
|
635
|
+
program
|
|
636
|
+
.command('tags')
|
|
637
|
+
.description('Manage project tags')
|
|
638
|
+
.argument('<project>', 'Project ID or name')
|
|
639
|
+
.argument('[action]', 'Action: add, remove, or list (default: list)', 'list')
|
|
640
|
+
.argument('[tag]', 'Tag name (required for add/remove)')
|
|
641
|
+
.action((projectIdentifier, action = 'list', tag) => {
|
|
642
|
+
try {
|
|
643
|
+
const db = (0, core_bridge_1.getDatabaseManager)();
|
|
644
|
+
const projects = (0, core_bridge_1.getAllProjects)();
|
|
645
|
+
const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
|
|
646
|
+
if (!project) {
|
|
647
|
+
console.error(`Error: Project not found: ${projectIdentifier}`);
|
|
648
|
+
process.exit(1);
|
|
649
|
+
}
|
|
650
|
+
const currentTags = project.tags || [];
|
|
651
|
+
if (action === 'list' || !action) {
|
|
652
|
+
// List tags
|
|
653
|
+
if (currentTags.length === 0) {
|
|
654
|
+
console.log('No tags set for this project.');
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
console.log(`Tags for "${project.name}":`);
|
|
658
|
+
currentTags.forEach(t => console.log(` - ${t}`));
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
else if (action === 'add') {
|
|
662
|
+
if (!tag || !tag.trim()) {
|
|
663
|
+
console.error('Error: Tag name is required for add action');
|
|
664
|
+
process.exit(1);
|
|
665
|
+
}
|
|
666
|
+
const newTag = tag.trim();
|
|
667
|
+
if (currentTags.includes(newTag)) {
|
|
668
|
+
console.log(`Tag "${newTag}" already exists for "${project.name}"`);
|
|
669
|
+
}
|
|
670
|
+
else {
|
|
671
|
+
db.updateProject(project.id, { tags: [...currentTags, newTag] });
|
|
672
|
+
console.log(`✓ Added tag "${newTag}" to "${project.name}"`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else if (action === 'remove') {
|
|
676
|
+
if (!tag || !tag.trim()) {
|
|
677
|
+
console.error('Error: Tag name is required for remove action');
|
|
678
|
+
process.exit(1);
|
|
679
|
+
}
|
|
680
|
+
const tagToRemove = tag.trim();
|
|
681
|
+
if (!currentTags.includes(tagToRemove)) {
|
|
682
|
+
console.log(`Tag "${tagToRemove}" does not exist for "${project.name}"`);
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
db.updateProject(project.id, { tags: currentTags.filter(t => t !== tagToRemove) });
|
|
686
|
+
console.log(`✓ Removed tag "${tagToRemove}" from "${project.name}"`);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
console.error(`Error: Unknown action "${action}". Use: list, add, or remove`);
|
|
691
|
+
process.exit(1);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
catch (error) {
|
|
695
|
+
console.error('Error managing tags:', error instanceof Error ? error.message : error);
|
|
696
|
+
process.exit(1);
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
// Open command - open project in editor
|
|
700
|
+
program
|
|
701
|
+
.command('open')
|
|
702
|
+
.description('Open project in editor')
|
|
703
|
+
.argument('<project>', 'Project ID or name')
|
|
704
|
+
.action(async (projectIdentifier) => {
|
|
705
|
+
try {
|
|
706
|
+
const projects = (0, core_bridge_1.getAllProjects)();
|
|
707
|
+
const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
|
|
708
|
+
if (!project) {
|
|
709
|
+
console.error(`Error: Project not found: ${projectIdentifier}`);
|
|
710
|
+
process.exit(1);
|
|
711
|
+
}
|
|
712
|
+
// Load settings from core
|
|
713
|
+
const corePath = path.join(__dirname, '..', '..', 'core', 'dist', 'settings');
|
|
714
|
+
const localCorePath = path.join(__dirname, '..', '..', '..', 'core', 'dist', 'settings');
|
|
715
|
+
let settings;
|
|
716
|
+
try {
|
|
717
|
+
settings = require(corePath);
|
|
718
|
+
}
|
|
719
|
+
catch {
|
|
720
|
+
try {
|
|
721
|
+
settings = require(localCorePath);
|
|
722
|
+
}
|
|
723
|
+
catch {
|
|
724
|
+
console.error('Error: Could not load settings');
|
|
725
|
+
process.exit(1);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
const editorSettings = settings.getEditorSettings();
|
|
729
|
+
let command;
|
|
730
|
+
const args = [project.path];
|
|
731
|
+
if (editorSettings.type === 'custom' && editorSettings.customPath) {
|
|
732
|
+
command = editorSettings.customPath;
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
switch (editorSettings.type) {
|
|
736
|
+
case 'vscode':
|
|
737
|
+
command = 'code';
|
|
738
|
+
break;
|
|
739
|
+
case 'cursor':
|
|
740
|
+
command = 'cursor';
|
|
741
|
+
break;
|
|
742
|
+
case 'windsurf':
|
|
743
|
+
command = 'windsurf';
|
|
744
|
+
break;
|
|
745
|
+
case 'zed':
|
|
746
|
+
command = 'zed';
|
|
747
|
+
break;
|
|
748
|
+
default:
|
|
749
|
+
command = 'code';
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
const { spawn } = require('child_process');
|
|
753
|
+
spawn(command, args, {
|
|
754
|
+
detached: true,
|
|
755
|
+
stdio: 'ignore',
|
|
756
|
+
}).unref();
|
|
757
|
+
console.log(`✓ Opening "${project.name}" in ${editorSettings.type || 'editor'}...`);
|
|
758
|
+
}
|
|
759
|
+
catch (error) {
|
|
760
|
+
console.error('Error opening project:', error instanceof Error ? error.message : error);
|
|
761
|
+
process.exit(1);
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
// Files command - open project directory
|
|
765
|
+
program
|
|
766
|
+
.command('files')
|
|
767
|
+
.description('Open project directory in file manager')
|
|
768
|
+
.argument('<project>', 'Project ID or name')
|
|
769
|
+
.action((projectIdentifier) => {
|
|
770
|
+
try {
|
|
771
|
+
const projects = (0, core_bridge_1.getAllProjects)();
|
|
772
|
+
const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
|
|
773
|
+
if (!project) {
|
|
774
|
+
console.error(`Error: Project not found: ${projectIdentifier}`);
|
|
775
|
+
process.exit(1);
|
|
776
|
+
}
|
|
777
|
+
let command;
|
|
778
|
+
const args = [project.path];
|
|
779
|
+
if (os.platform() === 'darwin') {
|
|
780
|
+
command = 'open';
|
|
781
|
+
}
|
|
782
|
+
else if (os.platform() === 'win32') {
|
|
783
|
+
command = 'explorer';
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
command = 'xdg-open';
|
|
787
|
+
}
|
|
788
|
+
const { spawn } = require('child_process');
|
|
789
|
+
spawn(command, args, {
|
|
790
|
+
detached: true,
|
|
791
|
+
stdio: 'ignore',
|
|
792
|
+
}).unref();
|
|
793
|
+
console.log(`✓ Opening "${project.name}" directory...`);
|
|
794
|
+
}
|
|
795
|
+
catch (error) {
|
|
796
|
+
console.error('Error opening directory:', error instanceof Error ? error.message : error);
|
|
797
|
+
process.exit(1);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
// URLs command - list detected URLs for a project
|
|
801
|
+
program
|
|
802
|
+
.command('urls')
|
|
803
|
+
.description('List detected URLs for a project')
|
|
804
|
+
.argument('<project>', 'Project ID or name')
|
|
805
|
+
.action(async (projectIdentifier) => {
|
|
806
|
+
try {
|
|
807
|
+
const projects = (0, core_bridge_1.getAllProjects)();
|
|
808
|
+
const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
|
|
809
|
+
if (!project) {
|
|
810
|
+
console.error(`Error: Project not found: ${projectIdentifier}`);
|
|
811
|
+
process.exit(1);
|
|
812
|
+
}
|
|
813
|
+
const urls = new Set();
|
|
814
|
+
// Get URLs from running processes
|
|
815
|
+
const { getRunningProcessesClean } = await Promise.resolve().then(() => __importStar(require('./script-runner')));
|
|
816
|
+
const runningProcesses = await getRunningProcessesClean();
|
|
817
|
+
const projectProcesses = runningProcesses.filter((p) => p.projectPath === project.path);
|
|
818
|
+
for (const process of projectProcesses) {
|
|
819
|
+
if (process.detectedUrls && Array.isArray(process.detectedUrls)) {
|
|
820
|
+
for (const url of process.detectedUrls) {
|
|
821
|
+
urls.add(url);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
// Get URLs from detected ports
|
|
826
|
+
const db = (0, core_bridge_1.getDatabaseManager)();
|
|
827
|
+
const projectPorts = db.getProjectPorts(project.id);
|
|
828
|
+
for (const portInfo of projectPorts) {
|
|
829
|
+
const url = `http://localhost:${portInfo.port}`;
|
|
830
|
+
urls.add(url);
|
|
831
|
+
}
|
|
832
|
+
const urlArray = Array.from(urls).sort();
|
|
833
|
+
if (urlArray.length === 0) {
|
|
834
|
+
console.log(`No URLs detected for "${project.name}"`);
|
|
835
|
+
}
|
|
836
|
+
else {
|
|
837
|
+
console.log(`\nDetected URLs for "${project.name}":`);
|
|
838
|
+
urlArray.forEach((url, idx) => {
|
|
839
|
+
console.log(` ${idx + 1}. ${url}`);
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
catch (error) {
|
|
844
|
+
console.error('Error listing URLs:', error instanceof Error ? error.message : error);
|
|
845
|
+
process.exit(1);
|
|
846
|
+
}
|
|
847
|
+
});
|
|
573
848
|
// Remove command
|
|
574
849
|
program
|
|
575
850
|
.command('remove')
|
|
@@ -1151,7 +1426,7 @@ program
|
|
|
1151
1426
|
// Check if first argument is not a known command
|
|
1152
1427
|
(async () => {
|
|
1153
1428
|
const args = process.argv.slice(2);
|
|
1154
|
-
const knownCommands = ['prxi', 'i', 'add', 'list', 'scan', 'remove', 'rn', 'rename', 'cd', 'pwd', 'run', 'ps', 'stop', 'web', 'desktop', 'ui', 'scripts', 'scan-ports', 'api', '--help', '-h', '--version', '-V'];
|
|
1429
|
+
const knownCommands = ['prxi', 'i', 'add', 'list', 'scan', 'remove', 'rn', 'rename', 'cd', 'pwd', 'run', 'ps', 'stop', 'web', 'desktop', 'ui', 'scripts', 'scan-ports', 'api', 'desc', 'description', 'tags', 'open', 'files', 'urls', '--help', '-h', '--version', '-V'];
|
|
1155
1430
|
// If we have at least 1 argument and first is not a known command, treat as project identifier
|
|
1156
1431
|
if (args.length >= 1 && !knownCommands.includes(args[0])) {
|
|
1157
1432
|
const projectIdentifier = args[0];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projax",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.11",
|
|
4
|
+
"description": "Cross-platform project management dashboard for tracking local development projects. Features CLI, Terminal UI, Desktop app, REST API, and built-in tools for test detection, port management, and script execution.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"prx": "./dist/index.js"
|
|
@@ -37,7 +37,19 @@
|
|
|
37
37
|
"project-management",
|
|
38
38
|
"dashboard",
|
|
39
39
|
"cli",
|
|
40
|
-
"developer-tools"
|
|
40
|
+
"developer-tools",
|
|
41
|
+
"project-tracker",
|
|
42
|
+
"development-workflow",
|
|
43
|
+
"test-detection",
|
|
44
|
+
"port-management",
|
|
45
|
+
"script-runner",
|
|
46
|
+
"electron",
|
|
47
|
+
"terminal-ui",
|
|
48
|
+
"rest-api",
|
|
49
|
+
"nodejs",
|
|
50
|
+
"python",
|
|
51
|
+
"rust",
|
|
52
|
+
"go"
|
|
41
53
|
],
|
|
42
54
|
"author": "",
|
|
43
55
|
"license": "MIT"
|