xitto-kernel 0.9.2 → 0.9.3
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/CHANGELOG.md +9 -0
- package/package.json +1 -1
- package/src/app/web/index.html +38 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.3
|
|
4
|
+
|
|
5
|
+
- **許願台佈局優化(視覺層次 + 互動細節)**:
|
|
6
|
+
- **頂部列**:專案控制(下拉 + 選資料夾 + 新專案)群組成一個卡片靠右、加底部分隔線、置中對齊;標題與控制不再擠成一團;窄螢幕隱藏副標
|
|
7
|
+
- **左欄**:歷史成品與檔案兩段做成卡片區塊;**當前任務在歷史列高亮**(知道你正在看哪個);時間改友善格式(月/日 時:分);列項改輕量(hover/active),不再雙層卡片
|
|
8
|
+
- **許願框**:focus 高亮邊框 + 「⌘/Ctrl+Enter 送出」提示與快捷鍵
|
|
9
|
+
- **主區**:歡迎/空狀態改虛線框、置中,更像「等你下訂單」
|
|
10
|
+
- 純前端(CSS/HTML/小 JS);測試 192/192 + JS 語法 + 結構驗證
|
|
11
|
+
|
|
3
12
|
## 0.9.2
|
|
4
13
|
|
|
5
14
|
- **修:報告顯示完成但找不到真實檔案**(成品寫到工作區外)。從執行歷史查出:某任務 workspace=`/Users/…/Xiza`(本地就地),但 agent 把報告 `write` 到 `/tmp/…`、`/app/…`(絕對路徑,工作區外)→ 成品掃描只看工作區 → `artifacts:{created:[]}`,但 summary 說完成 → 使用者看到「有報告」卻找不到檔。兩道修法:
|
package/package.json
CHANGED
package/src/app/web/index.html
CHANGED
|
@@ -12,19 +12,27 @@
|
|
|
12
12
|
/* 單頁佈局:頂部許願 + 左欄(歷史+檔案) + 主區(當前任務/成品/預覽共用)。窄螢幕收單欄 */
|
|
13
13
|
.layout { display:grid; grid-template-columns:300px minmax(0,1fr); gap:24px; align-items:start; margin-top:18px; }
|
|
14
14
|
.nav { position:sticky; top:14px; max-height:calc(100vh - 28px); display:flex; flex-direction:column; gap:16px; }
|
|
15
|
-
.navsec { display:flex; flex-direction:column; min-height:0; }
|
|
16
|
-
.navsec h3 { margin:0 0 8px; }
|
|
15
|
+
.navsec { display:flex; flex-direction:column; min-height:0; background:var(--card); border:1px solid var(--line); border-radius:12px; padding:10px 12px; }
|
|
16
|
+
.navsec h3 { margin:0 0 8px; position:sticky; top:0; }
|
|
17
17
|
.hist-sec #history, .file-sec #wbfiles { overflow:auto; } /* 兩段各自內捲,都到得了底 */
|
|
18
|
-
.hist-sec { flex:0 1 auto; max-height:
|
|
19
|
-
.file-sec { flex:1 1 auto; min-height:
|
|
18
|
+
.hist-sec { flex:0 1 auto; max-height:44vh; } .hist-sec #history { max-height:40vh; }
|
|
19
|
+
.file-sec { flex:1 1 auto; min-height:120px; } .file-sec #wbfiles { flex:1; }
|
|
20
20
|
.work { min-width:0; }
|
|
21
|
-
.welcome { padding:
|
|
21
|
+
.welcome { padding:56px 24px; text-align:center; line-height:2; font-size:15px; border:1px dashed var(--line); border-radius:14px; }
|
|
22
22
|
@media (max-width:860px){ .layout{ grid-template-columns:1fr; } .nav{ position:static; max-height:none; } .hist-sec,.hist-sec #history,.file-sec #wbfiles{ max-height:none; } }
|
|
23
|
-
header { display:flex; align-items:
|
|
24
|
-
header h1 { font-size:
|
|
23
|
+
header { display:flex; align-items:center; gap:12px; padding-bottom:14px; border-bottom:1px solid var(--line); }
|
|
24
|
+
header h1 { font-size:20px; margin:0; white-space:nowrap; }
|
|
25
25
|
header .sub { color:var(--dim); font-size:13px; }
|
|
26
|
-
.
|
|
27
|
-
.
|
|
26
|
+
.topctl { display:flex; align-items:center; gap:8px; background:var(--card); border:1px solid var(--line); border-radius:10px; padding:5px 8px; }
|
|
27
|
+
.prjlabel { color:var(--dim); font-size:12px; }
|
|
28
|
+
.topctl select { padding:5px 8px; max-width:200px; }
|
|
29
|
+
.topctl button { padding:5px 10px; font-size:13px; font-weight:500; }
|
|
30
|
+
@media (max-width:640px){ header .sub { display:none; } }
|
|
31
|
+
.ask { background:var(--card); border:1px solid var(--line); border-radius:14px; padding:14px; margin:18px 0; transition:border-color .15s; }
|
|
32
|
+
.ask:focus-within { border-color:var(--accent); }
|
|
33
|
+
.ask textarea { width:100%; background:#0c0e12; color:var(--fg); border:1px solid var(--line); border-radius:10px; padding:12px; font:inherit; resize:vertical; min-height:70px; outline:none; }
|
|
34
|
+
.ask textarea:focus { border-color:var(--accent); }
|
|
35
|
+
.askhint { color:var(--dim); font-size:12px; }
|
|
28
36
|
.row { display:flex; gap:10px; align-items:center; margin-top:10px; }
|
|
29
37
|
select, button { font:inherit; }
|
|
30
38
|
select { background:#0c0e12; color:var(--fg); border:1px solid var(--line); border-radius:8px; padding:8px; }
|
|
@@ -72,12 +80,14 @@
|
|
|
72
80
|
.qbox .q { color:var(--warn); margin-bottom:8px; }
|
|
73
81
|
.qbox input { width:100%; background:#0c0e12; color:var(--fg); border:1px solid var(--line); border-radius:8px; padding:9px; font:inherit; }
|
|
74
82
|
h3 { color:var(--dim); font-size:13px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; margin:28px 0 8px; }
|
|
75
|
-
.hist {
|
|
76
|
-
.hist:hover {
|
|
77
|
-
.hist
|
|
83
|
+
.hist { border:1px solid transparent; border-radius:8px; padding:8px 10px; margin:3px 0; cursor:pointer; }
|
|
84
|
+
.hist:hover { background:#0c0e12; }
|
|
85
|
+
.hist.active { background:#0c0e12; border-color:var(--accent); }
|
|
86
|
+
.hist .g { font-size:13.5px; line-height:1.4; } .hist .m { color:var(--dim); font-size:11px; margin-top:2px; }
|
|
78
87
|
.empty { color:var(--dim); font-size:13px; }
|
|
79
|
-
.wbrow { display:flex; align-items:center; gap:10px; padding:
|
|
80
|
-
.
|
|
88
|
+
.wbrow { display:flex; align-items:center; gap:10px; padding:7px 10px; border-radius:8px; margin:1px 0; }
|
|
89
|
+
.wbrow:hover { background:#0c0e12; }
|
|
90
|
+
.wbname { flex:1; color:var(--accent); cursor:pointer; font-size:13.5px; }
|
|
81
91
|
.wbmeta { color:var(--dim); font-size:12px; }
|
|
82
92
|
.wbdel { cursor:pointer; opacity:.6; } .wbdel:hover { opacity:1; }
|
|
83
93
|
.followup { margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
|
|
@@ -106,11 +116,14 @@
|
|
|
106
116
|
<div class="wrap">
|
|
107
117
|
<header>
|
|
108
118
|
<h1>🪄 xitto 許願台</h1>
|
|
109
|
-
<span class="sub"
|
|
119
|
+
<span class="sub">說出你想完成的事,做完給你成品</span>
|
|
110
120
|
<span class="spacer"></span>
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
<div class="topctl">
|
|
122
|
+
<span class="prjlabel">專案</span>
|
|
123
|
+
<select id="space" title="專案/空間:不同專案的檔案與記憶各自獨立"></select>
|
|
124
|
+
<button class="ghost" id="browsebtn" title="瀏覽並選一個真實資料夾(本地模式)" style="display:none">📁 選</button>
|
|
125
|
+
<button class="ghost" id="newspace" title="新增一個專案/空間">+ 新專案</button>
|
|
126
|
+
</div>
|
|
114
127
|
</header>
|
|
115
128
|
|
|
116
129
|
<div id="fsmodal" class="modal" style="display:none">
|
|
@@ -132,6 +145,7 @@
|
|
|
132
145
|
<div class="row">
|
|
133
146
|
<select id="pack" title="領域"></select>
|
|
134
147
|
<span class="spacer"></span>
|
|
148
|
+
<span class="askhint">⌘ / Ctrl + Enter 送出</span>
|
|
135
149
|
<button id="go">交辦 →</button>
|
|
136
150
|
</div>
|
|
137
151
|
</div>
|
|
@@ -297,8 +311,9 @@ $("#go").onclick = async () => {
|
|
|
297
311
|
$("#goal").value = "";
|
|
298
312
|
$("#fview").style.display="none"; expandedLog=false;
|
|
299
313
|
activeId = r.taskId;
|
|
300
|
-
poll();
|
|
314
|
+
poll(); loadHistory();
|
|
301
315
|
};
|
|
316
|
+
$("#goal").addEventListener("keydown", e=>{ if((e.metaKey||e.ctrlKey) && e.key==="Enter"){ e.preventDefault(); $("#go").click(); } });
|
|
302
317
|
|
|
303
318
|
function statusClass(s){ return s==="running"?"running":s==="needs-input"?"needs":s==="done"?"done":(s==="error"||s==="cancelled"||s==="interrupted")?"error":""; }
|
|
304
319
|
function statusText(s){ return ({queued:"排隊中",running:"進行中…","needs-input":"需要你回答",done:"已完成",error:"失敗",cancelled:"已中斷",interrupted:"已中斷(重啟)"})[s]||s; }
|
|
@@ -363,11 +378,12 @@ async function submitFollowup(sessionId, pack, workspace){
|
|
|
363
378
|
async function loadHistory() {
|
|
364
379
|
const r = await api("/v1/tasks").then(r=>r.json());
|
|
365
380
|
const list = (r.tasks||[]).filter(t=>t.mode==="goal" && (t.workspace||"default")===curSpace).reverse();
|
|
366
|
-
$("#history").innerHTML = list.length ? list.map(t=>`<div class="hist" onclick="openTask('${t.taskId}')">
|
|
381
|
+
$("#history").innerHTML = list.length ? list.map(t=>`<div class="hist${t.taskId===activeId?' active':''}" onclick="openTask('${t.taskId}')">
|
|
367
382
|
<div class="g">${t.continued?'<span class="cont" title="接續前一個任務">↳</span> ':''}${esc(t.goal||t.taskId)} <span class="status ${statusClass(t.status)}">${statusText(t.status)}</span></div>
|
|
368
|
-
<div class="m">${esc(t.createdAt)}</div></div>`).join("") : `<div class="empty">還沒有任何任務。</div>`;
|
|
383
|
+
<div class="m">${esc(fmtTime(t.createdAt))}</div></div>`).join("") : `<div class="empty">還沒有任何任務。</div>`;
|
|
369
384
|
}
|
|
370
|
-
|
|
385
|
+
function fmtTime(s){ try{ const d=new Date(s); return d.toLocaleString(undefined,{month:"numeric",day:"numeric",hour:"2-digit",minute:"2-digit"}); }catch{ return s; } }
|
|
386
|
+
async function openTask(id){ activeId=id; const t=await api("/v1/tasks/"+id).then(r=>r.json()); liveTask=t; $("#fview").style.display="none"; renderCurrent(t); loadHistory(); if(t.status==="running"||t.status==="queued"){poll();} window.scrollTo({top:0,behavior:"smooth"}); }
|
|
371
387
|
|
|
372
388
|
loadHistory(); loadFiles();
|
|
373
389
|
</script>
|