coxpit 5.0.0 → 5.0.1
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 +88 -12
- 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.1",
|
|
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
|
@@ -76,9 +76,29 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
76
76
|
input:focus,select:focus,textarea:focus{border-color:rgba(78,201,176,.55);outline:none}
|
|
77
77
|
input::placeholder,textarea::placeholder{color:var(--faint)}
|
|
78
78
|
textarea{resize:vertical;min-height:56px;line-height:1.5}
|
|
79
|
+
/* no native browser chrome — any bare <select> strips the OS arrow and draws a token chevron
|
|
80
|
+
(dressed selects hide entirely; this covers the undressed fallback like #archRepo) */
|
|
81
|
+
select{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding-right:26px;
|
|
82
|
+
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");
|
|
83
|
+
background-repeat:no-repeat;background-position:right 8px center;background-size:13px}
|
|
84
|
+
select option{background:#12151c;color:var(--ink)}
|
|
85
|
+
/* kill the native number spinner — a token stepper (below) replaces it */
|
|
86
|
+
input[type=number]{appearance:none;-webkit-appearance:none;-moz-appearance:textfield}
|
|
87
|
+
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
|
|
79
88
|
.row{display:flex;gap:8px}
|
|
80
89
|
.row>*{flex:1}
|
|
81
90
|
.row .narrow{flex:0 0 64px}
|
|
91
|
+
/* count stepper — token − N + (btn-ghost feel, dark, no native spinner) */
|
|
92
|
+
.stepper{display:flex;align-items:center;gap:0;flex:0 0 auto;border:1px solid var(--line);
|
|
93
|
+
border-radius:var(--r-ctl);background:#0e1118;overflow:hidden}
|
|
94
|
+
.stepper .stp{display:inline-flex;align-items:center;justify-content:center;width:26px;height:32px;
|
|
95
|
+
background:transparent;border:none;color:var(--muted);cursor:pointer;font-size:15px;line-height:1;
|
|
96
|
+
transition:background .15s,color .15s}
|
|
97
|
+
.stepper .stp:hover{background:var(--surface2);color:var(--ink)}
|
|
98
|
+
.stepper .stp .ic{width:14px;height:14px}
|
|
99
|
+
.stepper input.narrow{flex:0 0 30px;width:30px;text-align:center;border:none;border-radius:0;
|
|
100
|
+
background:transparent;padding:8px 0;font-variant-numeric:tabular-nums}
|
|
101
|
+
.stepper input.narrow:focus{border:none}
|
|
82
102
|
.check{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);cursor:pointer;user-select:none}
|
|
83
103
|
.check input{width:auto;accent-color:var(--brand)}
|
|
84
104
|
|
|
@@ -115,9 +135,10 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
115
135
|
#repoList .repo .rowmenu{display:none;align-items:center;gap:2px;flex:none}
|
|
116
136
|
#repoList .repo:hover .rowmenu{display:flex}
|
|
117
137
|
#repoList .repo:hover .cnt{display:none}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
138
|
+
/* rail repo-row actions — icon-ghost, never white: transparent bg · muted icon · hover ink + surface */
|
|
139
|
+
#repoList .repo .rmbtn{background:transparent;border:1px solid transparent;color:var(--muted);cursor:pointer;
|
|
140
|
+
padding:3px;display:inline-flex;border-radius:6px;transition:color .15s,background .15s,border-color .15s}
|
|
141
|
+
#repoList .repo .rmbtn:hover{color:var(--ink);background:var(--surface);border-color:var(--line-hi)}
|
|
121
142
|
#repoList .repo .rmbtn .ic{width:13px;height:13px;color:inherit}
|
|
122
143
|
.navi{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:8px;color:var(--muted);
|
|
123
144
|
cursor:pointer;font-size:13px;border:none;background:transparent;width:100%;text-align:left;font-family:var(--sans)}
|
|
@@ -211,14 +232,34 @@ export const BOARD_HTML = /* html */ `<!doctype html>
|
|
|
211
232
|
.dd-opt:hover{background:var(--surface);color:var(--ink)}
|
|
212
233
|
.dd-opt.on{color:var(--brand)}
|
|
213
234
|
.dd-opt.on::before{content:'✓ ';font-size:10px}
|
|
235
|
+
/* model combo — free-text input + a .dd-style recent-models menu (no native datalist/white popup) */
|
|
236
|
+
.mcombo{position:relative;display:flex;align-items:stretch;gap:0}
|
|
237
|
+
.mcombo input{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}
|
|
238
|
+
.mcombo .mc-tog{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:30px;
|
|
239
|
+
background:#0e1118;color:var(--faint);border:1px solid var(--line);border-left:none;
|
|
240
|
+
border-top-right-radius:var(--r-ctl);border-bottom-right-radius:var(--r-ctl);cursor:pointer;
|
|
241
|
+
transition:color .15s,border-color .15s}
|
|
242
|
+
.mcombo .mc-tog:hover{color:var(--ink)}
|
|
243
|
+
.mcombo .mc-tog .ic{width:13px;height:13px;transition:transform .15s}
|
|
244
|
+
.mcombo.open input,.mcombo.open .mc-tog{border-color:rgba(78,201,176,.55)}
|
|
245
|
+
.mcombo.open .mc-tog .ic{transform:rotate(180deg)}
|
|
246
|
+
.mcombo .dd-panel{top:calc(100% + 5px)}
|
|
247
|
+
.mcombo.open .dd-panel{display:block}
|
|
248
|
+
.mc-empty{padding:7px 10px;font-family:var(--mono);font-size:11px;color:var(--faint)}
|
|
214
249
|
.seg{display:flex;gap:3px;padding:3px;border:1px solid var(--line);border-radius:var(--r-ctl);background:#0e1118}
|
|
215
|
-
|
|
250
|
+
/* slim single-row option — matches the type/provider seg height; the risky hint rides inline, subtle */
|
|
251
|
+
.seg-opt{flex:1;display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:5px;
|
|
252
|
+
padding:6px 8px;border:none;min-width:0;
|
|
216
253
|
background:transparent;color:var(--muted);font-size:12px;font-weight:600;cursor:pointer;
|
|
217
254
|
border-radius:calc(var(--r-ctl) - 3px);transition:background .15s,color .15s}
|
|
218
255
|
.seg-opt:hover{color:var(--ink)}
|
|
219
256
|
.seg-opt.on{background:var(--surface2);color:var(--ink)}
|
|
220
257
|
.seg-opt[data-real="1"].on{background:var(--brand);color:var(--brand-ink)}
|
|
221
|
-
.seg-hint{font-family:var(--mono);font-size:
|
|
258
|
+
.seg-hint{font-family:var(--mono);font-size:9px;font-weight:500;text-transform:uppercase;letter-spacing:.05em;
|
|
259
|
+
opacity:.6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
260
|
+
/* the credit hint only reads once the risky option is chosen — keeps the resting seg clean & slim */
|
|
261
|
+
.seg-opt[data-real="1"]:not(.on) .seg-hint{display:none}
|
|
262
|
+
.seg-opt[data-real="1"].on .seg-hint{opacity:.75}
|
|
222
263
|
/* ── deliverable 계약 칩(Task compose) ── */
|
|
223
264
|
.ochips{display:flex;flex-wrap:wrap;gap:5px}
|
|
224
265
|
.ochip{background:transparent;color:var(--muted);border:1px solid var(--line);cursor:pointer;
|
|
@@ -808,8 +849,11 @@ ${ICON_SPRITE}
|
|
|
808
849
|
</button>
|
|
809
850
|
<div class="opt-b" id="taskOptBody" hidden>
|
|
810
851
|
<p class="flabel">model · optional</p>
|
|
811
|
-
<
|
|
812
|
-
|
|
852
|
+
<div class="mcombo" id="modelCombo">
|
|
853
|
+
<input id="taskModel" placeholder="CLI default" autocomplete="off" spellcheck="false" />
|
|
854
|
+
<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>
|
|
855
|
+
<div class="dd-panel" id="modelMenu"></div>
|
|
856
|
+
</div>
|
|
813
857
|
<p class="flabel">design capture · optional</p>
|
|
814
858
|
<select id="taskCapture"><option value="">no design capture</option></select>
|
|
815
859
|
<p class="flabel">deliverables · optional (contract)</p>
|
|
@@ -841,7 +885,11 @@ ${ICON_SPRITE}
|
|
|
841
885
|
<button type="button" class="seg-opt" data-real="1">Real agent<span class="seg-hint">spends credits</span></button>
|
|
842
886
|
</div>
|
|
843
887
|
<input type="checkbox" id="taskReal" hidden />
|
|
844
|
-
<
|
|
888
|
+
<div class="stepper" id="taskCountStep" title="agents — 1 for a job, N to explore variants">
|
|
889
|
+
<button type="button" class="stp" id="cntDown" aria-label="fewer agents"><svg class="ic"><use href="#i-minus"/></svg></button>
|
|
890
|
+
<input id="taskCount" class="narrow" type="number" min="1" max="8" value="1" inputmode="numeric" aria-label="agent count" />
|
|
891
|
+
<button type="button" class="stp" id="cntUp" aria-label="more agents"><svg class="ic"><use href="#i-plus"/></svg></button>
|
|
892
|
+
</div>
|
|
845
893
|
<button class="btn" type="submit" id="runFleetBtn"><svg class="ic"><use href="#i-play"/></svg> Run fleet</button>
|
|
846
894
|
</div>
|
|
847
895
|
</form>
|
|
@@ -2983,7 +3031,7 @@ function setV(tab){
|
|
|
2983
3031
|
$('panelBench').style.display = tab==='bench' ? 'flex' : 'none';
|
|
2984
3032
|
// footer adapts: Task=Dry/Real·count·Run fleet · Goal=Dry/Real·Plan & run · Workbench=Open workbench only
|
|
2985
3033
|
$('modeSeg').style.display = tab==='bench' ? 'none' : 'flex'; // workbench 는 에이전트 없음
|
|
2986
|
-
$('
|
|
3034
|
+
$('taskCountStep').style.display = tab==='task' ? 'flex' : 'none'; // count 는 Task 만(플래너·워크벤치는 1)
|
|
2987
3035
|
$('runFleetBtn').innerHTML = ic(L_ICON[tab]) + ' ' + L_LABEL[tab];
|
|
2988
3036
|
}
|
|
2989
3037
|
document.querySelectorAll('#launchTabs .seg-opt').forEach(b=>{
|
|
@@ -3091,12 +3139,40 @@ function rememberModel(m){
|
|
|
3091
3139
|
}catch{}
|
|
3092
3140
|
paintModelHist();
|
|
3093
3141
|
}
|
|
3142
|
+
function modelHistList(){
|
|
3143
|
+
try{ return JSON.parse(localStorage.getItem('coxpit.models')||'[]'); }catch{ return []; }
|
|
3144
|
+
}
|
|
3094
3145
|
function paintModelHist(){
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
$('
|
|
3146
|
+
const h = modelHistList();
|
|
3147
|
+
const cur = $('taskModel').value.trim();
|
|
3148
|
+
$('modelMenu').innerHTML = h.length
|
|
3149
|
+
? h.map(m=>'<div class="dd-opt'+(m===cur?' on':'')+'" data-m="'+escA(m)+'">'+esc(m)+'</div>').join('')
|
|
3150
|
+
: '<div class="mc-empty">no recent models</div>';
|
|
3098
3151
|
}
|
|
3099
3152
|
paintModelHist();
|
|
3153
|
+
// model combo — free text stays; the caret opens a .dd-style recent-models menu (no native datalist)
|
|
3154
|
+
function closeModelMenu(){ $('modelCombo').classList.remove('open'); }
|
|
3155
|
+
$('modelTog').addEventListener('click', (e)=>{
|
|
3156
|
+
e.stopPropagation();
|
|
3157
|
+
const open = $('modelCombo').classList.contains('open');
|
|
3158
|
+
closeDropdowns(); closeModelMenu();
|
|
3159
|
+
if (!open){ paintModelHist(); $('modelCombo').classList.add('open'); }
|
|
3160
|
+
});
|
|
3161
|
+
$('modelMenu').addEventListener('click', (e)=>{
|
|
3162
|
+
const o = e.target.closest('.dd-opt'); if(!o) return;
|
|
3163
|
+
$('taskModel').value = o.dataset.m; closeModelMenu(); $('taskModel').focus();
|
|
3164
|
+
});
|
|
3165
|
+
document.addEventListener('click', closeModelMenu);
|
|
3166
|
+
|
|
3167
|
+
/* ── count stepper — token −/+ mirror the number input, clamped 1..8 ── */
|
|
3168
|
+
function stepCount(delta){
|
|
3169
|
+
const el = $('taskCount');
|
|
3170
|
+
const n = Math.max(1, Math.min(8, (Number(el.value)||1) + delta));
|
|
3171
|
+
el.value = String(n);
|
|
3172
|
+
}
|
|
3173
|
+
$('cntDown').addEventListener('click', ()=>stepCount(-1));
|
|
3174
|
+
$('cntUp').addEventListener('click', ()=>stepCount(1));
|
|
3175
|
+
$('taskCount').addEventListener('change', ()=>stepCount(0)); // clamp manual typing
|
|
3100
3176
|
|
|
3101
3177
|
/* ── agent mode segmented control (mirrors hidden #taskReal) ── */
|
|
3102
3178
|
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>
|