coxpit 5.0.0 → 5.0.2
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 +1 -1
- package/src/board.ts +96 -16
- package/src/icons.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coxpit",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "Self-hosted cockpit for running a fleet of AI coding agents across your own machines — parallel worktree runs, live board, compare & merge, web terminal, design capture.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/board.ts
CHANGED
|
@@ -58,7 +58,10 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
58
58
|
.mdot.on{background:var(--s-done)}
|
|
59
59
|
|
|
60
60
|
/* ── layout ─────────────────────────────── */
|
|
61
|
-
|
|
61
|
+
/* fixed viewport height so the rail stays put and each column scrolls on its own
|
|
62
|
+
(the board grew tall with many cards and dragged the rail's + New below the fold) */
|
|
63
|
+
.layout{display:grid;grid-template-columns:318px 1fr;height:calc(100vh - 55px);overflow:hidden}
|
|
64
|
+
.layout > aside,.layout > main{min-height:0}
|
|
62
65
|
aside{border-right:1px solid var(--line);padding:20px 18px;background:var(--surface);
|
|
63
66
|
display:flex;flex-direction:column;gap:26px}
|
|
64
67
|
main{padding:20px;overflow:auto}
|
|
@@ -76,9 +79,29 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
76
79
|
input:focus,select:focus,textarea:focus{border-color:rgba(78,201,176,.55);outline:none}
|
|
77
80
|
input::placeholder,textarea::placeholder{color:var(--faint)}
|
|
78
81
|
textarea{resize:vertical;min-height:56px;line-height:1.5}
|
|
82
|
+
/* no native browser chrome — any bare <select> strips the OS arrow and draws a token chevron
|
|
83
|
+
(dressed selects hide entirely; this covers the undressed fallback like #archRepo) */
|
|
84
|
+
select{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding-right:26px;
|
|
85
|
+
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238792a2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
86
|
+
background-repeat:no-repeat;background-position:right 8px center;background-size:13px}
|
|
87
|
+
select option{background:#12151c;color:var(--ink)}
|
|
88
|
+
/* kill the native number spinner — a token stepper (below) replaces it */
|
|
89
|
+
input[type=number]{appearance:none;-webkit-appearance:none;-moz-appearance:textfield}
|
|
90
|
+
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
|
|
79
91
|
.row{display:flex;gap:8px}
|
|
80
92
|
.row>*{flex:1}
|
|
81
93
|
.row .narrow{flex:0 0 64px}
|
|
94
|
+
/* count stepper — token − N + (btn-ghost feel, dark, no native spinner) */
|
|
95
|
+
.stepper{display:flex;align-items:center;gap:0;flex:0 0 auto;border:1px solid var(--line);
|
|
96
|
+
border-radius:var(--r-ctl);background:#0e1118;overflow:hidden}
|
|
97
|
+
.stepper .stp{display:inline-flex;align-items:center;justify-content:center;width:26px;height:32px;
|
|
98
|
+
background:transparent;border:none;color:var(--muted);cursor:pointer;font-size:15px;line-height:1;
|
|
99
|
+
transition:background .15s,color .15s}
|
|
100
|
+
.stepper .stp:hover{background:var(--surface2);color:var(--ink)}
|
|
101
|
+
.stepper .stp .ic{width:14px;height:14px}
|
|
102
|
+
.stepper input.narrow{flex:0 0 30px;width:30px;text-align:center;border:none;border-radius:0;
|
|
103
|
+
background:transparent;padding:8px 0;font-variant-numeric:tabular-nums}
|
|
104
|
+
.stepper input.narrow:focus{border:none}
|
|
82
105
|
.check{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);cursor:pointer;user-select:none}
|
|
83
106
|
.check input{width:auto;accent-color:var(--brand)}
|
|
84
107
|
|
|
@@ -115,9 +138,10 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
115
138
|
#repoList .repo .rowmenu{display:none;align-items:center;gap:2px;flex:none}
|
|
116
139
|
#repoList .repo:hover .rowmenu{display:flex}
|
|
117
140
|
#repoList .repo:hover .cnt{display:none}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
141
|
+
/* rail repo-row actions — icon-ghost, never white: transparent bg · muted icon · hover ink + surface */
|
|
142
|
+
#repoList .repo .rmbtn{background:transparent;border:1px solid transparent;color:var(--muted);cursor:pointer;
|
|
143
|
+
padding:3px;display:inline-flex;border-radius:6px;transition:color .15s,background .15s,border-color .15s}
|
|
144
|
+
#repoList .repo .rmbtn:hover{color:var(--ink);background:var(--surface2)}
|
|
121
145
|
#repoList .repo .rmbtn .ic{width:13px;height:13px;color:inherit}
|
|
122
146
|
.navi{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:8px;color:var(--muted);
|
|
123
147
|
cursor:pointer;font-size:13px;border:none;background:transparent;width:100%;text-align:left;font-family:var(--sans)}
|
|
@@ -200,7 +224,8 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
200
224
|
.dd-btn:hover{border-color:var(--line-hi)}
|
|
201
225
|
.dd.open .dd-btn{border-color:rgba(78,201,176,.55)}
|
|
202
226
|
.dd-lbl{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
|
|
203
|
-
.dd-car{color:var(--faint);
|
|
227
|
+
.dd-car{color:var(--faint);display:inline-flex;align-items:center;transition:transform .15s}
|
|
228
|
+
.dd-car .ic{width:13px;height:13px}
|
|
204
229
|
.dd.open .dd-car{transform:rotate(180deg)}
|
|
205
230
|
.dd-panel{position:absolute;top:calc(100% + 5px);left:0;right:0;z-index:40;background:var(--surface2);
|
|
206
231
|
border:1px solid var(--line-hi);border-radius:9px;box-shadow:var(--shadow);max-height:230px;
|
|
@@ -211,14 +236,34 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
211
236
|
.dd-opt:hover{background:var(--surface);color:var(--ink)}
|
|
212
237
|
.dd-opt.on{color:var(--brand)}
|
|
213
238
|
.dd-opt.on::before{content:'✓ ';font-size:10px}
|
|
239
|
+
/* model combo — free-text input + a .dd-style recent-models menu (no native datalist/white popup) */
|
|
240
|
+
.mcombo{position:relative;display:flex;align-items:stretch;gap:0}
|
|
241
|
+
.mcombo input{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}
|
|
242
|
+
.mcombo .mc-tog{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:30px;
|
|
243
|
+
background:#0e1118;color:var(--faint);border:1px solid var(--line);border-left:none;
|
|
244
|
+
border-top-right-radius:var(--r-ctl);border-bottom-right-radius:var(--r-ctl);cursor:pointer;
|
|
245
|
+
transition:color .15s,border-color .15s}
|
|
246
|
+
.mcombo .mc-tog:hover{color:var(--ink)}
|
|
247
|
+
.mcombo .mc-tog .ic{width:13px;height:13px;transition:transform .15s}
|
|
248
|
+
.mcombo.open input,.mcombo.open .mc-tog{border-color:rgba(78,201,176,.55)}
|
|
249
|
+
.mcombo.open .mc-tog .ic{transform:rotate(180deg)}
|
|
250
|
+
.mcombo .dd-panel{top:calc(100% + 5px)}
|
|
251
|
+
.mcombo.open .dd-panel{display:block}
|
|
252
|
+
.mc-empty{padding:7px 10px;font-family:var(--mono);font-size:11px;color:var(--faint)}
|
|
214
253
|
.seg{display:flex;gap:3px;padding:3px;border:1px solid var(--line);border-radius:var(--r-ctl);background:#0e1118}
|
|
215
|
-
|
|
254
|
+
/* slim single-row option — matches the type/provider seg height; the risky hint rides inline, subtle */
|
|
255
|
+
.seg-opt{flex:1;display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:5px;
|
|
256
|
+
padding:6px 8px;border:none;min-width:0;
|
|
216
257
|
background:transparent;color:var(--muted);font-size:12px;font-weight:600;cursor:pointer;
|
|
217
258
|
border-radius:calc(var(--r-ctl) - 3px);transition:background .15s,color .15s}
|
|
218
259
|
.seg-opt:hover{color:var(--ink)}
|
|
219
260
|
.seg-opt.on{background:var(--surface2);color:var(--ink)}
|
|
220
261
|
.seg-opt[data-real="1"].on{background:var(--brand);color:var(--brand-ink)}
|
|
221
|
-
.seg-hint{font-family:var(--mono);font-size:
|
|
262
|
+
.seg-hint{font-family:var(--mono);font-size:9px;font-weight:500;text-transform:uppercase;letter-spacing:.05em;
|
|
263
|
+
opacity:.6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
264
|
+
/* the credit hint only reads once the risky option is chosen — keeps the resting seg clean & slim */
|
|
265
|
+
.seg-opt[data-real="1"]:not(.on) .seg-hint{display:none}
|
|
266
|
+
.seg-opt[data-real="1"].on .seg-hint{opacity:.75}
|
|
222
267
|
/* ── deliverable 계약 칩(Task compose) ── */
|
|
223
268
|
.ochips{display:flex;flex-wrap:wrap;gap:5px}
|
|
224
269
|
.ochip{background:transparent;color:var(--muted);border:1px solid var(--line);cursor:pointer;
|
|
@@ -669,7 +714,7 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
669
714
|
.menu-btn{display:none;font-size:15px;padding:5px 10px}
|
|
670
715
|
.scrim{position:fixed;inset:0;top:54px;background:rgba(5,7,10,.5);z-index:29;display:none}
|
|
671
716
|
@media (max-width:860px){
|
|
672
|
-
.layout{grid-template-columns:1fr;
|
|
717
|
+
.layout{grid-template-columns:1fr;height:calc(100dvh - 55px)}
|
|
673
718
|
/* 사이드바 = 오프캔버스 드로어 — 플릿이 첫 화면, 런처는 ☰ 뒤에 */
|
|
674
719
|
.menu-btn{display:inline-flex}
|
|
675
720
|
aside{position:fixed;top:54px;bottom:0;left:0;width:min(86vw,340px);max-width:100vw;z-index:30;
|
|
@@ -808,8 +853,11 @@ ${ICON_SPRITE}
|
|
|
808
853
|
</button>
|
|
809
854
|
<div class="opt-b" id="taskOptBody" hidden>
|
|
810
855
|
<p class="flabel">model · optional</p>
|
|
811
|
-
<
|
|
812
|
-
|
|
856
|
+
<div class="mcombo" id="modelCombo">
|
|
857
|
+
<input id="taskModel" placeholder="CLI default" autocomplete="off" spellcheck="false" />
|
|
858
|
+
<button type="button" class="mc-tog" id="modelTog" aria-label="recent models" title="recent models"><svg class="ic"><use href="#i-chevron-down"/></svg></button>
|
|
859
|
+
<div class="dd-panel" id="modelMenu"></div>
|
|
860
|
+
</div>
|
|
813
861
|
<p class="flabel">design capture · optional</p>
|
|
814
862
|
<select id="taskCapture"><option value="">no design capture</option></select>
|
|
815
863
|
<p class="flabel">deliverables · optional (contract)</p>
|
|
@@ -841,7 +889,11 @@ ${ICON_SPRITE}
|
|
|
841
889
|
<button type="button" class="seg-opt" data-real="1">Real agent<span class="seg-hint">spends credits</span></button>
|
|
842
890
|
</div>
|
|
843
891
|
<input type="checkbox" id="taskReal" hidden />
|
|
844
|
-
<
|
|
892
|
+
<div class="stepper" id="taskCountStep" title="agents — 1 for a job, N to explore variants">
|
|
893
|
+
<button type="button" class="stp" id="cntDown" aria-label="fewer agents"><svg class="ic"><use href="#i-minus"/></svg></button>
|
|
894
|
+
<input id="taskCount" class="narrow" type="number" min="1" max="8" value="1" inputmode="numeric" aria-label="agent count" />
|
|
895
|
+
<button type="button" class="stp" id="cntUp" aria-label="more agents"><svg class="ic"><use href="#i-plus"/></svg></button>
|
|
896
|
+
</div>
|
|
845
897
|
<button class="btn" type="submit" id="runFleetBtn"><svg class="ic"><use href="#i-play"/></svg> Run fleet</button>
|
|
846
898
|
</div>
|
|
847
899
|
</form>
|
|
@@ -1151,7 +1203,7 @@ function dressSelect(id){
|
|
|
1151
1203
|
const sel = $(id); if(!sel || sel.dataset.dd) return;
|
|
1152
1204
|
sel.dataset.dd = '1';
|
|
1153
1205
|
const dd = document.createElement('div'); dd.className = 'dd';
|
|
1154
|
-
dd.innerHTML = '<button type="button" class="dd-btn"><span class="dd-lbl"></span><span class="dd-car"
|
|
1206
|
+
dd.innerHTML = '<button type="button" class="dd-btn"><span class="dd-lbl"></span><span class="dd-car"><svg class="ic"><use href="#i-chevron-down"/></svg></span></button><div class="dd-panel"></div>';
|
|
1155
1207
|
sel.parentNode.insertBefore(dd, sel);
|
|
1156
1208
|
sel.style.display = 'none';
|
|
1157
1209
|
dd.querySelector('.dd-btn').addEventListener('click', (e)=>{
|
|
@@ -2983,7 +3035,7 @@ function setV(tab){
|
|
|
2983
3035
|
$('panelBench').style.display = tab==='bench' ? 'flex' : 'none';
|
|
2984
3036
|
// footer adapts: Task=Dry/Real·count·Run fleet · Goal=Dry/Real·Plan & run · Workbench=Open workbench only
|
|
2985
3037
|
$('modeSeg').style.display = tab==='bench' ? 'none' : 'flex'; // workbench 는 에이전트 없음
|
|
2986
|
-
$('
|
|
3038
|
+
$('taskCountStep').style.display = tab==='task' ? 'flex' : 'none'; // count 는 Task 만(플래너·워크벤치는 1)
|
|
2987
3039
|
$('runFleetBtn').innerHTML = ic(L_ICON[tab]) + ' ' + L_LABEL[tab];
|
|
2988
3040
|
}
|
|
2989
3041
|
document.querySelectorAll('#launchTabs .seg-opt').forEach(b=>{
|
|
@@ -3091,12 +3143,40 @@ function rememberModel(m){
|
|
|
3091
3143
|
}catch{}
|
|
3092
3144
|
paintModelHist();
|
|
3093
3145
|
}
|
|
3146
|
+
function modelHistList(){
|
|
3147
|
+
try{ return JSON.parse(localStorage.getItem('coxpit.models')||'[]'); }catch{ return []; }
|
|
3148
|
+
}
|
|
3094
3149
|
function paintModelHist(){
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
$('
|
|
3150
|
+
const h = modelHistList();
|
|
3151
|
+
const cur = $('taskModel').value.trim();
|
|
3152
|
+
$('modelMenu').innerHTML = h.length
|
|
3153
|
+
? h.map(m=>'<div class="dd-opt'+(m===cur?' on':'')+'" data-m="'+escA(m)+'">'+esc(m)+'</div>').join('')
|
|
3154
|
+
: '<div class="mc-empty">no recent models</div>';
|
|
3098
3155
|
}
|
|
3099
3156
|
paintModelHist();
|
|
3157
|
+
// model combo — free text stays; the caret opens a .dd-style recent-models menu (no native datalist)
|
|
3158
|
+
function closeModelMenu(){ $('modelCombo').classList.remove('open'); }
|
|
3159
|
+
$('modelTog').addEventListener('click', (e)=>{
|
|
3160
|
+
e.stopPropagation();
|
|
3161
|
+
const open = $('modelCombo').classList.contains('open');
|
|
3162
|
+
closeDropdowns(); closeModelMenu();
|
|
3163
|
+
if (!open){ paintModelHist(); $('modelCombo').classList.add('open'); }
|
|
3164
|
+
});
|
|
3165
|
+
$('modelMenu').addEventListener('click', (e)=>{
|
|
3166
|
+
const o = e.target.closest('.dd-opt'); if(!o) return;
|
|
3167
|
+
$('taskModel').value = o.dataset.m; closeModelMenu(); $('taskModel').focus();
|
|
3168
|
+
});
|
|
3169
|
+
document.addEventListener('click', closeModelMenu);
|
|
3170
|
+
|
|
3171
|
+
/* ── count stepper — token −/+ mirror the number input, clamped 1..8 ── */
|
|
3172
|
+
function stepCount(delta){
|
|
3173
|
+
const el = $('taskCount');
|
|
3174
|
+
const n = Math.max(1, Math.min(8, (Number(el.value)||1) + delta));
|
|
3175
|
+
el.value = String(n);
|
|
3176
|
+
}
|
|
3177
|
+
$('cntDown').addEventListener('click', ()=>stepCount(-1));
|
|
3178
|
+
$('cntUp').addEventListener('click', ()=>stepCount(1));
|
|
3179
|
+
$('taskCount').addEventListener('change', ()=>stepCount(0)); // clamp manual typing
|
|
3100
3180
|
|
|
3101
3181
|
/* ── agent mode segmented control (mirrors hidden #taskReal) ── */
|
|
3102
3182
|
const segOpts = Array.from(document.querySelectorAll('#modeSeg .seg-opt'));
|
package/src/icons.ts
CHANGED
|
@@ -19,7 +19,9 @@ export const ICON_SPRITE = `<svg style="position:absolute;width:0;height:0" aria
|
|
|
19
19
|
<symbol id="i-image" viewBox="0 0 24 24"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21"/></symbol>
|
|
20
20
|
<symbol id="i-message" viewBox="0 0 24 24"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></symbol>
|
|
21
21
|
<symbol id="i-chevron" viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></symbol>
|
|
22
|
+
<symbol id="i-chevron-down" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></symbol>
|
|
22
23
|
<symbol id="i-plus" viewBox="0 0 24 24"><path d="M5 12h14"/><path d="M12 5v14"/></symbol>
|
|
24
|
+
<symbol id="i-minus" viewBox="0 0 24 24"><path d="M5 12h14"/></symbol>
|
|
23
25
|
<symbol id="i-pencil" viewBox="0 0 24 24"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/></symbol>
|
|
24
26
|
<symbol id="i-trash" viewBox="0 0 24 24"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></symbol>
|
|
25
27
|
<symbol id="i-recycle" viewBox="0 0 24 24"><path d="M7 19H4.815a1.83 1.83 0 0 1-1.57-.881 1.785 1.785 0 0 1-.004-1.784L7.196 9.5"/><path d="M11 19h8.203a1.83 1.83 0 0 0 1.556-.89 1.784 1.784 0 0 0 0-1.775l-1.226-2.12"/><path d="m14 16-3 3 3 3"/><path d="M8.293 13.596 4.875 9.5 1.5 13.5"/><path d="m9 12 3-3-3-3"/><path d="M13.5 3.5 17 9.5l-3.5 2"/></symbol>
|