@godmode-team/godmode 1.7.2 → 1.8.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/LICENSE +94 -46
- package/README.md +195 -36
- package/assets/agent-roster/competitor-watch.md +40 -0
- package/assets/agent-roster/content-writer.md +35 -53
- package/assets/agent-roster/godmode-builder.md +2 -2
- package/assets/agent-roster/inbox-manager.md +38 -0
- package/assets/agent-roster/meeting-prep.md +40 -16
- package/assets/agent-roster/skill-optimizer.md +50 -0
- package/assets/agent-roster/weekly-review.md +42 -0
- package/assets/skills/autoresearch.md +1 -1
- package/assets/skills/pattern-scout.md +1 -1
- package/assets/skills/visual-qa.md +128 -0
- package/dist/godmode-ui/aeo.html +1 -1
- package/dist/godmode-ui/assets/brain-tab-B1CYwAJ7.js +402 -0
- package/dist/godmode-ui/assets/connections-tab-Cuv4eW0d.js +91 -0
- package/dist/godmode-ui/assets/ctrl-settings-COfcdhha.js +5 -0
- package/dist/godmode-ui/assets/dashboards-tab-7hHXzWPp.js +137 -0
- package/dist/godmode-ui/assets/index-DcYipcbm.js +1994 -0
- package/dist/godmode-ui/assets/index-DmEmOd0w.css +1 -0
- package/dist/godmode-ui/assets/lit-core-CTInmNPB.js +3 -0
- package/dist/godmode-ui/assets/markdown-i_gIkIP3.js +59 -0
- package/dist/godmode-ui/assets/second-brain-tab-DkFatLwl.js +350 -0
- package/dist/godmode-ui/assets/setup-BnLadXY9.js +1 -0
- package/dist/godmode-ui/assets/team-tab-Q3icI_Q-.js +296 -0
- package/dist/godmode-ui/assets/today-tab-C6lIMzgY.js +209 -0
- package/dist/godmode-ui/assets/views-settings-B2UFEtoi.js +4643 -0
- package/dist/godmode-ui/assets/work-tab-DwU559Bx.js +1 -0
- package/dist/godmode-ui/assets/workspaces-vzpIVgdl.js +718 -0
- package/dist/godmode-ui/index.html +11 -5
- package/dist/index.js +1658 -36092
- package/dist/mcp-entry.js +1272 -0
- package/dist/standalone.js +1917 -0
- package/openclaw.plugin.json +36 -7
- package/package.json +27 -13
- package/scripts/godmode-gateway.service +41 -0
- package/scripts/install-systemd.sh +99 -0
- package/skill-cards/adversarial-board.md +63 -0
- package/skill-cards/autoresearch.md +39 -0
- package/skill-cards/bill-review.md +26 -0
- package/skill-cards/calendar.md +32 -0
- package/skill-cards/code-quality.md +31 -0
- package/skill-cards/competitor-scan.md +26 -0
- package/skill-cards/content-generation.md +26 -0
- package/skill-cards/context-deep-dive.md +65 -0
- package/skill-cards/cron-workflows.md +33 -0
- package/skill-cards/dashboards.md +38 -0
- package/skill-cards/delegate.md +57 -0
- package/skill-cards/files.md +38 -0
- package/skill-cards/godmode-builder.md +58 -0
- package/skill-cards/inbox-sweep.md +26 -0
- package/skill-cards/integrations.md +40 -0
- package/skill-cards/life-admin.md +26 -0
- package/skill-cards/meetings.md +42 -0
- package/skill-cards/meta-problem-solver.md +52 -0
- package/skill-cards/people.md +39 -0
- package/skill-cards/personal-brand.md +71 -0
- package/skill-cards/project-orchestrator.md +97 -0
- package/skill-cards/project-pipeline.md +78 -0
- package/skill-cards/proof-editor.md +28 -0
- package/skill-cards/quality-gate.md +57 -0
- package/skill-cards/quarterly-review.md +26 -0
- package/skill-cards/queue.md +40 -0
- package/skill-cards/screenpipe.md +49 -0
- package/skill-cards/second-brain.md +46 -0
- package/skill-cards/standup-prep.md +26 -0
- package/skill-cards/tasks.md +34 -0
- package/skill-cards/visual-qa.md +56 -0
- package/skill-cards/workspace-memory.md +51 -0
- package/skill-cards/x-twitter.md +37 -0
- package/dist/godmode-ui/assets/dashboards-CrT3s0NG.js +0 -1
- package/dist/godmode-ui/assets/index-BtwTHiwI.js +0 -9353
- package/dist/godmode-ui/assets/index-xiAdnGJD.css +0 -1
- package/dist/godmode-ui/assets/options-QuHclvvX.js +0 -1
- package/dist/godmode-ui/assets/second-brain-ghSM5E6X.js +0 -1
- package/dist/godmode-ui/assets/setup-CWjMtnE4.js +0 -1
- package/dist/godmode-ui/consciousness-icon-64.png +0 -0
- package/dist/godmode-ui/consciousness-icon.png +0 -0
- package/dist/godmode-ui/godmode-logo.png +0 -0
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
import{A as c,b as a}from"./lit-core-CTInmNPB.js";import{f as P,ab as Q}from"./ctrl-settings-COfcdhha.js";function ie(e){return!Number.isFinite(e)||e<=0?"0 B":e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function z(e){switch(e){case"markdown":return"📄";case"html":return"🌐";case"image":return"🖼️";case"json":return"🧩";case"folder":return"📁";default:return"📄"}}function te(e){return e==="running"?"ws-session-dot ws-session-dot--running":e==="blocked"?"ws-session-dot ws-session-dot--blocked":"ws-session-dot ws-session-dot--complete"}function le(e){return`ws-task-priority ws-task-priority--${e}`}function oe(e){return e==="high"?"High":e==="low"?"Low":"Med"}function re(e){if(!e)return"";const t=Q();return e===t?"Today":e<t?`Overdue (${e})`:e}function ce(e){if(!e)return"ws-task-due";const t=Q();return e<t?"ws-task-due ws-task-due--overdue":e===t?"ws-task-due ws-task-due--today":"ws-task-due"}function V(e,t="due"){const s={high:0,medium:1,low:2};return[...e].sort((n,i)=>{if(t==="priority"){const l=s[n.priority]-s[i.priority];return l!==0?l:n.dueDate&&i.dueDate?n.dueDate.localeCompare(i.dueDate):n.dueDate&&!i.dueDate?-1:!n.dueDate&&i.dueDate?1:0}if(t==="newest")return(i.createdAt||"").localeCompare(n.createdAt||"");if(n.dueDate&&i.dueDate){const l=n.dueDate.localeCompare(i.dueDate);if(l!==0)return l}else{if(n.dueDate&&!i.dueDate)return-1;if(!n.dueDate&&i.dueDate)return 1}return s[n.priority]-s[i.priority]})}function se(e,t,s,n,i,l,r){const p=e.status==="complete";return n===e.id?a`
|
|
2
|
+
<form
|
|
3
|
+
class="ws-list-row ws-task-row ws-task-edit-row"
|
|
4
|
+
aria-label="Edit task: ${e.title}"
|
|
5
|
+
@submit=${d=>{d.preventDefault();const m=d.currentTarget,u=m.querySelector(".ws-task-edit-input"),k=m.querySelector(".ws-task-date-input"),b=u.value.trim();b&&(l?.(e.id,{title:b,dueDate:k.value||null}),i?.(null))}}
|
|
6
|
+
>
|
|
7
|
+
<input
|
|
8
|
+
type="text"
|
|
9
|
+
class="ws-task-edit-input"
|
|
10
|
+
aria-label="Task title"
|
|
11
|
+
.value=${e.title}
|
|
12
|
+
@click=${d=>d.stopPropagation()}
|
|
13
|
+
/>
|
|
14
|
+
<input
|
|
15
|
+
type="date"
|
|
16
|
+
class="ws-task-date-input"
|
|
17
|
+
aria-label="Task due date"
|
|
18
|
+
.value=${e.dueDate??""}
|
|
19
|
+
/>
|
|
20
|
+
<button type="submit" class="ws-task-save-btn" aria-label="Save task changes">Save</button>
|
|
21
|
+
<button
|
|
22
|
+
type="button"
|
|
23
|
+
class="ws-task-cancel-btn"
|
|
24
|
+
aria-label="Cancel editing"
|
|
25
|
+
@click=${()=>i?.(null)}
|
|
26
|
+
>Cancel</button>
|
|
27
|
+
</form>
|
|
28
|
+
`:a`
|
|
29
|
+
<div class="ws-list-row ws-task-row ${p?"ws-task-row--complete":""}" role="listitem">
|
|
30
|
+
<button
|
|
31
|
+
class="ws-task-check ${p?"ws-task-check--done":""}"
|
|
32
|
+
@click=${()=>t?.(e.id,e.status)}
|
|
33
|
+
title=${p?"Mark incomplete":"Mark complete"}
|
|
34
|
+
aria-label="${p?"Mark incomplete":"Mark complete"}: ${e.title}"
|
|
35
|
+
>
|
|
36
|
+
${p?"✓":""}
|
|
37
|
+
</button>
|
|
38
|
+
<span
|
|
39
|
+
class="ws-list-title ws-task-title-clickable ${p?"ws-task-title--done":""}"
|
|
40
|
+
@click=${()=>i?.(e.id)}
|
|
41
|
+
title="Click to edit"
|
|
42
|
+
>${e.title}</span>
|
|
43
|
+
${e.briefSection?a`<span class="ws-task-section">${e.briefSection}</span>`:c}
|
|
44
|
+
<span class=${le(e.priority)}>${oe(e.priority)}</span>
|
|
45
|
+
${e.dueDate?a`<span class=${ce(e.dueDate)}>${re(e.dueDate)}</span>`:c}
|
|
46
|
+
${!p&&e.queueStatus?.status==="processing"?a`<span class="ws-task-agent-status ws-task-agent-status--processing" aria-live="polite">
|
|
47
|
+
<span class="ws-task-agent-dot"></span>
|
|
48
|
+
${e.queueStatus.roleName} working...
|
|
49
|
+
</span>`:!p&&e.queueStatus?.status==="review"&&s?a`<button
|
|
50
|
+
class="ws-task-start-btn ws-task-start-btn--review"
|
|
51
|
+
@click=${()=>s(e.id)}
|
|
52
|
+
title="Review agent output"
|
|
53
|
+
aria-label="Review agent output for: ${e.title}"
|
|
54
|
+
>Review</button>`:e.queueStatus?.status==="done"?a`
|
|
55
|
+
${r?a`<button
|
|
56
|
+
class="ws-task-start-btn ws-task-start-btn--done"
|
|
57
|
+
@click=${()=>r(e.id)}
|
|
58
|
+
title="Preview agent output"
|
|
59
|
+
aria-label="View output for: ${e.title}"
|
|
60
|
+
>View Output</button>`:c}
|
|
61
|
+
${s?a`<button
|
|
62
|
+
class="ws-task-start-btn ws-task-start-btn--chat"
|
|
63
|
+
@click=${()=>s(e.id)}
|
|
64
|
+
title="Open chat session for this task"
|
|
65
|
+
aria-label="Open chat for: ${e.title}"
|
|
66
|
+
>Open Chat</button>`:c}
|
|
67
|
+
`:!p&&s?a`<button
|
|
68
|
+
class="ws-task-start-btn"
|
|
69
|
+
@click=${()=>s(e.id)}
|
|
70
|
+
title="Start working on this task"
|
|
71
|
+
aria-label="Start task: ${e.title}"
|
|
72
|
+
>Start</button>`:c}
|
|
73
|
+
</div>
|
|
74
|
+
`}function $e(e,t,s,n,i,l,r){const p=e.status==="complete";return n===e.id?a`
|
|
75
|
+
<form
|
|
76
|
+
class="ws-list-row ws-task-row ws-task-edit-row"
|
|
77
|
+
aria-label="Edit task: ${e.title}"
|
|
78
|
+
@submit=${d=>{d.preventDefault();const m=d.currentTarget,u=m.querySelector(".ws-task-edit-input"),k=m.querySelector(".ws-task-date-input"),b=u.value.trim();b&&(l?.(e.id,{title:b,dueDate:k.value||null}),i?.(null))}}
|
|
79
|
+
>
|
|
80
|
+
<input
|
|
81
|
+
type="text"
|
|
82
|
+
class="ws-task-edit-input"
|
|
83
|
+
aria-label="Task title"
|
|
84
|
+
.value=${e.title}
|
|
85
|
+
@click=${d=>d.stopPropagation()}
|
|
86
|
+
/>
|
|
87
|
+
<input
|
|
88
|
+
type="date"
|
|
89
|
+
class="ws-task-date-input"
|
|
90
|
+
aria-label="Task due date"
|
|
91
|
+
.value=${e.dueDate??""}
|
|
92
|
+
/>
|
|
93
|
+
<button type="submit" class="ws-task-save-btn" aria-label="Save task changes">Save</button>
|
|
94
|
+
<button
|
|
95
|
+
type="button"
|
|
96
|
+
class="ws-task-cancel-btn"
|
|
97
|
+
aria-label="Cancel editing"
|
|
98
|
+
@click=${()=>i?.(null)}
|
|
99
|
+
>Cancel</button>
|
|
100
|
+
</form>
|
|
101
|
+
`:a`
|
|
102
|
+
<div class="ws-list-row ws-task-row ${p?"ws-task-row--complete":""}" role="listitem">
|
|
103
|
+
<button
|
|
104
|
+
class="ws-task-check ${p?"ws-task-check--done":""}"
|
|
105
|
+
@click=${()=>t?.(e.id,e.status)}
|
|
106
|
+
title=${p?"Mark incomplete":"Mark complete"}
|
|
107
|
+
aria-label="${p?"Mark incomplete":"Mark complete"}: ${e.title}"
|
|
108
|
+
>
|
|
109
|
+
${p?"✓":""}
|
|
110
|
+
</button>
|
|
111
|
+
<span
|
|
112
|
+
class="ws-list-title ws-task-title-clickable ${p?"ws-task-title--done":""}"
|
|
113
|
+
@click=${()=>i?.(e.id)}
|
|
114
|
+
title="Click to edit"
|
|
115
|
+
>${e.title}</span>
|
|
116
|
+
${e.project?a`<span class="ws-task-project">${e.project}</span>`:c}
|
|
117
|
+
${e.briefSection?a`<span class="ws-task-section">${e.briefSection}</span>`:c}
|
|
118
|
+
<span class=${le(e.priority)}>${oe(e.priority)}</span>
|
|
119
|
+
${e.dueDate?a`<span class=${ce(e.dueDate)}>${re(e.dueDate)}</span>`:c}
|
|
120
|
+
${!p&&e.queueStatus?.status==="processing"?a`<span class="ws-task-agent-status ws-task-agent-status--processing" aria-live="polite">
|
|
121
|
+
<span class="ws-task-agent-dot"></span>
|
|
122
|
+
${e.queueStatus.roleName} working...
|
|
123
|
+
</span>`:!p&&e.queueStatus?.status==="review"&&s?a`<button
|
|
124
|
+
class="ws-task-start-btn ws-task-start-btn--review"
|
|
125
|
+
@click=${()=>s(e.id)}
|
|
126
|
+
title="Review agent output"
|
|
127
|
+
aria-label="Review agent output for: ${e.title}"
|
|
128
|
+
>Review</button>`:e.queueStatus?.status==="done"?a`
|
|
129
|
+
${r?a`<button
|
|
130
|
+
class="ws-task-start-btn ws-task-start-btn--done"
|
|
131
|
+
@click=${()=>r(e.id)}
|
|
132
|
+
title="Preview agent output"
|
|
133
|
+
aria-label="View output for: ${e.title}"
|
|
134
|
+
>View Output</button>`:c}
|
|
135
|
+
${s?a`<button
|
|
136
|
+
class="ws-task-start-btn ws-task-start-btn--chat"
|
|
137
|
+
@click=${()=>s(e.id)}
|
|
138
|
+
title="Open chat session for this task"
|
|
139
|
+
aria-label="Open chat for: ${e.title}"
|
|
140
|
+
>Open Chat</button>`:c}
|
|
141
|
+
`:!p&&s?a`<button
|
|
142
|
+
class="ws-task-start-btn"
|
|
143
|
+
@click=${()=>s(e.id)}
|
|
144
|
+
title="Start working on this task"
|
|
145
|
+
aria-label="Start task: ${e.title}"
|
|
146
|
+
>Start</button>`:c}
|
|
147
|
+
</div>
|
|
148
|
+
`}function be(e,t){return e.trim()?t.toLowerCase().includes(e.trim().toLowerCase()):!0}function ae(e,t){if(!e.trim())return t;const s=e.trim().toLowerCase();return t.filter(n=>n.name.toLowerCase().includes(s)||n.path.toLowerCase().includes(s)||n.type.toLowerCase().includes(s)||(n.searchText??"").toLowerCase().includes(s))}function ne(e,t){if(!e.trim())return t;const s=e.trim().toLowerCase();return t.filter(n=>n.title.toLowerCase().includes(s)||n.key.toLowerCase().includes(s))}function pe(e,t){if(!e.trim())return t;const s=e.trim().toLowerCase();return t.reduce((n,i)=>{if(i.type==="file")(i.name.toLowerCase().includes(s)||i.path.toLowerCase().includes(s))&&n.push(i);else{const l=pe(e,i.children??[]);l.length>0&&n.push({...i,children:l})}return n},[])}function de(e){let t=0;for(const s of e)s.type==="file"?t++:s.children&&(t+=de(s.children));return t}const ke=10;function fe(e){if(!e.searchText)return null;const t=e.searchText.trim();if(!t)return null;const s=t.match(/#+ (.+?)(?:\s#|$)/);return s?s[1].trim().slice(0,120):(t.startsWith("---")?t.replace(/^---.*?---\s*/s,""):t).slice(0,120)||null}function he(e,t=ke){return[...e].sort((s,n)=>n.modified.getTime()-s.modified.getTime()).slice(0,t)}function ue(e,t,s){if(e.type==="file"){const r=s.pinnedPaths.has(e.path);return a`
|
|
149
|
+
<div class="ws-folder-file-row" role="listitem" style="padding-left: ${12+t*16}px">
|
|
150
|
+
<button
|
|
151
|
+
class="ws-folder-file"
|
|
152
|
+
aria-label="Open file: ${e.name}"
|
|
153
|
+
@click=${()=>s.onItemClick?.({path:e.path,name:e.name,type:e.fileType??"text",size:e.size??0,modified:e.modified??new Date})}
|
|
154
|
+
>
|
|
155
|
+
<span class="ws-list-icon" aria-hidden="true">${z(e.fileType??"text")}</span>
|
|
156
|
+
<span class="ws-list-title">${e.name}</span>
|
|
157
|
+
${e.size!=null?a`<span class="ws-list-meta">${ie(e.size)}</span>`:c}
|
|
158
|
+
${e.modified?a`<span class="ws-list-meta">${P(e.modified.getTime())}</span>`:c}
|
|
159
|
+
</button>
|
|
160
|
+
<button
|
|
161
|
+
class="ws-pin-btn ${r?"active":""}"
|
|
162
|
+
@click=${()=>s.onPinToggle?.(s.workspaceId,e.path,r)}
|
|
163
|
+
title=${r?"Unpin":"Pin"}
|
|
164
|
+
aria-label="${r?"Unpin":"Pin"} file: ${e.name}"
|
|
165
|
+
>
|
|
166
|
+
${r?"Unpin":"Pin"}
|
|
167
|
+
</button>
|
|
168
|
+
</div>
|
|
169
|
+
`}const n=s.expandedFolders.has(e.path),i=e.children??[],l=de(i);return a`
|
|
170
|
+
<div class="ws-folder-node" role="listitem">
|
|
171
|
+
<button
|
|
172
|
+
class="ws-folder-header"
|
|
173
|
+
style="padding-left: ${12+t*16}px"
|
|
174
|
+
@click=${()=>s.onToggleFolder?.(e.path)}
|
|
175
|
+
aria-expanded=${n}
|
|
176
|
+
aria-label="${n?"Collapse":"Expand"} folder: ${e.name}, ${l} files"
|
|
177
|
+
>
|
|
178
|
+
<span class="ws-folder-chevron ${n?"expanded":""}" aria-hidden="true">▶</span>
|
|
179
|
+
<span class="ws-list-icon" aria-hidden="true">📁</span>
|
|
180
|
+
<span class="ws-folder-name">${e.name}</span>
|
|
181
|
+
<span class="ws-folder-count">${l} ${l===1?"file":"files"}</span>
|
|
182
|
+
</button>
|
|
183
|
+
${n?a`
|
|
184
|
+
<div class="ws-folder-children">
|
|
185
|
+
${i.map(r=>ue(r,t+1,s))}
|
|
186
|
+
</div>
|
|
187
|
+
`:c}
|
|
188
|
+
</div>
|
|
189
|
+
`}function ve(e,t,s){return a`
|
|
190
|
+
<div class="workspace-card-wrapper" role="listitem">
|
|
191
|
+
<button
|
|
192
|
+
class="workspace-card"
|
|
193
|
+
@click=${()=>{console.log("[workspace-card] click:",e.name,"onSelect:",typeof t),t?.(e)}}
|
|
194
|
+
title="Open workspace"
|
|
195
|
+
aria-label="Open workspace: ${e.name}"
|
|
196
|
+
>
|
|
197
|
+
<div class="workspace-card-emoji" aria-hidden="true">${e.emoji}</div>
|
|
198
|
+
<div class="workspace-card-content">
|
|
199
|
+
<div class="workspace-card-name">${e.name}</div>
|
|
200
|
+
<div class="workspace-card-meta">
|
|
201
|
+
${e.connectionCount>0?a`<span>${e.connectionCount} connections</span><span class="workspace-card-separator">•</span>`:c}
|
|
202
|
+
<span>${e.artifactCount} artifacts</span>
|
|
203
|
+
<span class="workspace-card-separator">•</span>
|
|
204
|
+
<span>${e.sessionCount} sessions</span>
|
|
205
|
+
${e.feedCount>0?a`<span class="workspace-card-separator">•</span><span>${e.feedCount} feed</span>`:c}
|
|
206
|
+
<span class="workspace-card-separator">•</span>
|
|
207
|
+
<span>${P(e.lastUpdated.getTime())}</span>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</button>
|
|
211
|
+
${s?a`<button
|
|
212
|
+
class="workspace-card-delete"
|
|
213
|
+
title="Delete workspace"
|
|
214
|
+
aria-label="Delete workspace: ${e.name}"
|
|
215
|
+
@click=${n=>{n.stopPropagation(),confirm(`Delete workspace "${e.name}"? This removes it from your list but does not delete any files.`)&&s(e)}}
|
|
216
|
+
>×</button>`:c}
|
|
217
|
+
</div>
|
|
218
|
+
`}function j(e){const{workspaceId:t,entry:s,pinned:n,onOpen:i,onPinToggle:l}=e;return a`
|
|
219
|
+
<div class="ws-list-row" role="listitem">
|
|
220
|
+
<button class="ws-list-main" @click=${()=>i?.(s)} aria-label="Open file: ${s.name}">
|
|
221
|
+
<span class="ws-list-icon" aria-hidden="true">${z(s.type)}</span>
|
|
222
|
+
<span class="ws-list-title">${s.name}</span>
|
|
223
|
+
<span class="ws-list-meta">${ie(s.size)}</span>
|
|
224
|
+
<span class="ws-list-meta">${P(s.modified.getTime())}</span>
|
|
225
|
+
</button>
|
|
226
|
+
<button
|
|
227
|
+
class="ws-pin-btn ${n?"active":""}"
|
|
228
|
+
@click=${()=>l?.(t,s.path,n)}
|
|
229
|
+
title=${n?"Unpin":"Pin"}
|
|
230
|
+
aria-label="${n?"Unpin":"Pin"} file: ${s.name}"
|
|
231
|
+
>
|
|
232
|
+
${n?"Unpin":"Pin"}
|
|
233
|
+
</button>
|
|
234
|
+
</div>
|
|
235
|
+
`}function ge(e){const{workspaceId:t,entry:s,pinned:n,onOpen:i,onPinToggle:l}=e,r=fe(s);return a`
|
|
236
|
+
<div class="ws-list-row" role="listitem">
|
|
237
|
+
<button class="ws-list-main" @click=${()=>i?.(s)} aria-label="Open file: ${s.name}">
|
|
238
|
+
<span class="ws-list-icon" aria-hidden="true">${z(s.type)}</span>
|
|
239
|
+
<span class="ws-list-title">${s.name}</span>
|
|
240
|
+
<span class="ws-list-meta">${P(s.modified.getTime())}</span>
|
|
241
|
+
${r?a`<span class="ws-list-desc">${r}</span>`:c}
|
|
242
|
+
</button>
|
|
243
|
+
<button
|
|
244
|
+
class="ws-pin-btn ${n?"active":""}"
|
|
245
|
+
@click=${()=>l?.(t,s.path,n)}
|
|
246
|
+
title=${n?"Unpin":"Pin"}
|
|
247
|
+
aria-label="${n?"Unpin":"Pin"} file: ${s.name}"
|
|
248
|
+
>
|
|
249
|
+
${n?"Unpin":"Pin"}
|
|
250
|
+
</button>
|
|
251
|
+
</div>
|
|
252
|
+
`}function ye(e,t){return a`
|
|
253
|
+
<nav class="workspace-breadcrumbs" aria-label="File browser breadcrumb">
|
|
254
|
+
${e.map((s,n)=>a`
|
|
255
|
+
${n>0?a`<span class="breadcrumb-sep" aria-hidden="true">/</span>`:c}
|
|
256
|
+
<button
|
|
257
|
+
class="breadcrumb-item ${n===e.length-1?"breadcrumb-current":""}"
|
|
258
|
+
@click=${()=>t(s.path)}
|
|
259
|
+
aria-current=${n===e.length-1?"location":c}
|
|
260
|
+
>${s.name}</button>
|
|
261
|
+
`)}
|
|
262
|
+
</nav>
|
|
263
|
+
`}function Te(e){const{browseEntries:t,breadcrumbs:s,browseSearchQuery:n,browseSearchResults:i,onBrowseFolder:l,onBrowseSearch:r,onBrowseBack:p,onCreateFolder:$,onItemClick:d}=e,m=i??t??[];return a`
|
|
264
|
+
<div class="workspace-browser" role="region" aria-label="File browser">
|
|
265
|
+
<div class="workspace-browser-toolbar">
|
|
266
|
+
<button class="workspace-browse-back" @click=${()=>p?.()} aria-label="Go back to workspace">
|
|
267
|
+
← Back
|
|
268
|
+
</button>
|
|
269
|
+
${s?ye(s,u=>l?.(u)):c}
|
|
270
|
+
<input
|
|
271
|
+
type="text"
|
|
272
|
+
class="workspace-browse-search"
|
|
273
|
+
placeholder="Search files..."
|
|
274
|
+
aria-label="Search files in workspace"
|
|
275
|
+
.value=${n??""}
|
|
276
|
+
@input=${u=>{const k=u.target;r?.(k.value)}}
|
|
277
|
+
/>
|
|
278
|
+
<button
|
|
279
|
+
class="workspace-browse-new-folder"
|
|
280
|
+
aria-label="Create new folder"
|
|
281
|
+
@click=${()=>{const u=prompt("New folder name:");if(u?.trim()){const k=s?.[s.length-1]?.path??".";$?.(`${k}/${u.trim()}`)}}}
|
|
282
|
+
>+ Folder</button>
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
<div class="workspace-browse-list" role="list" aria-label="File listing">
|
|
286
|
+
${m.length===0?a`<div class="workspace-browse-empty">No files found</div>`:m.map(u=>a`
|
|
287
|
+
<button
|
|
288
|
+
class="workspace-browse-entry"
|
|
289
|
+
@click=${()=>{u.type==="folder"?l?.(u.path):d&&d({path:u.path,name:u.name,type:u.fileType??"text",size:u.size??0,modified:new Date})}}
|
|
290
|
+
>
|
|
291
|
+
<span class="browse-entry-icon">${u.type==="folder"?"📁":"📄"}</span>
|
|
292
|
+
<span class="browse-entry-name">${u.name}</span>
|
|
293
|
+
${u.excerpt?a`<span class="browse-entry-excerpt">${u.excerpt}</span>`:c}
|
|
294
|
+
</button>
|
|
295
|
+
`)}
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
`}function Se(e){const{workspace:t,itemSearchQuery:s,expandedFolders:n=new Set,showCompletedTasks:i=!1,onItemSearch:l,onBack:r,onItemClick:p,onSessionClick:$,onPinToggle:d,onPinSessionToggle:m,onToggleFolder:u,onToggleTaskComplete:k,onCreateTask:b,onToggleCompletedTasks:f,onStartTask:D,editingTaskId:h,onEditTask:T,onUpdateTask:w,onBatchPushToDrive:v}=e,S=ae(s,t.pinned).toSorted((o,C)=>C.modified.getTime()-o.modified.getTime()),F=ne(s,t.pinnedSessions),g=ae(s,t.outputs).filter(o=>!t.pinned.some(C=>C.path===o.path)),x=(t.folderTree?.length??0)>0,L=x?pe(s,t.folderTree):[],O=ne(s,t.sessions),B=new Set(t.pinnedSessions.map(o=>o.key)),R=new Set(t.pinned.map(o=>o.path)),A=s.trim().length>0,_=S.length>0||F.length>0,N=O.length>0||t.sessions.length===0||A,I=he(t.outputs),W=I.length>0&&!A,M={expandedFolders:n,pinnedPaths:R,workspaceId:t.id,onToggleFolder:u,onItemClick:p,onPinToggle:d};return a`
|
|
299
|
+
<div class="workspaces-container" role="region" aria-label="Workspace: ${t.name}">
|
|
300
|
+
<div class="workspaces-header">
|
|
301
|
+
<div class="workspaces-title">
|
|
302
|
+
<button class="workspace-back-btn" @click=${r} aria-label="Back to workspace list">←</button>
|
|
303
|
+
<span class="workspaces-icon" aria-hidden="true">${t.emoji}</span>
|
|
304
|
+
<div class="workspace-header-text">
|
|
305
|
+
<span class="workspace-header-name">${t.name}</span>
|
|
306
|
+
<span class="workspace-header-desc">${t.path}</span>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
<div class="workspace-detail-search">
|
|
310
|
+
<input
|
|
311
|
+
type="text"
|
|
312
|
+
class="workspaces-search-input"
|
|
313
|
+
placeholder="Search workspace..."
|
|
314
|
+
aria-label="Search within ${t.name}"
|
|
315
|
+
.value=${s}
|
|
316
|
+
@input=${o=>l?.(o.target.value)}
|
|
317
|
+
/>
|
|
318
|
+
<button
|
|
319
|
+
class="workspace-browse-btn"
|
|
320
|
+
aria-label="Browse files in ${t.name}"
|
|
321
|
+
@click=${()=>e.onBrowseFolder?.(".")}
|
|
322
|
+
>Browse Files</button>
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
<div class="workspace-content">
|
|
327
|
+
${e.browsePath!=null?Te(e):c}
|
|
328
|
+
|
|
329
|
+
${_?a`
|
|
330
|
+
<section class="ws-section" aria-label="Pinned items">
|
|
331
|
+
<div class="ws-section__header">
|
|
332
|
+
<h3>Pinned</h3>
|
|
333
|
+
<span>${S.length+F.length}</span>
|
|
334
|
+
</div>
|
|
335
|
+
<div class="ws-list" role="list" aria-label="Pinned items list">
|
|
336
|
+
${F.map(o=>a`
|
|
337
|
+
<div class="ws-list-row" role="listitem">
|
|
338
|
+
<button class="ws-list-main" @click=${()=>$?.(o)} aria-label="Open session: ${o.title}">
|
|
339
|
+
<span class=${te(o.status)} aria-label="Status: ${o.status}"></span>
|
|
340
|
+
<span class="ws-list-title">${o.title}</span>
|
|
341
|
+
<span class="ws-list-meta">${P(o.created.getTime())}</span>
|
|
342
|
+
</button>
|
|
343
|
+
<button
|
|
344
|
+
class="ws-pin-btn active"
|
|
345
|
+
@click=${()=>m?.(t.id,o.key,!0)}
|
|
346
|
+
title="Unpin"
|
|
347
|
+
aria-label="Unpin session: ${o.title}"
|
|
348
|
+
>
|
|
349
|
+
Unpin
|
|
350
|
+
</button>
|
|
351
|
+
</div>
|
|
352
|
+
`)}
|
|
353
|
+
${S.map(o=>j({workspaceId:t.id,entry:o,pinned:!0,onOpen:p,onPinToggle:d}))}
|
|
354
|
+
</div>
|
|
355
|
+
</section>
|
|
356
|
+
`:c}
|
|
357
|
+
|
|
358
|
+
${Fe({tasks:t.tasks??[],workspaceName:t.name,showCompleted:i,onToggleTaskComplete:k,onCreateTask:b,onToggleCompletedTasks:f,onStartTask:D,onViewTaskOutput,editingTaskId:h,onEditTask:T,onUpdateTask:w})}
|
|
359
|
+
|
|
360
|
+
${W?a`
|
|
361
|
+
<section class="ws-section" aria-label="Recent files">
|
|
362
|
+
<div class="ws-section__header">
|
|
363
|
+
<h3>Recent</h3>
|
|
364
|
+
<span>${I.length}</span>
|
|
365
|
+
</div>
|
|
366
|
+
<div class="ws-list" role="list" aria-label="Recent files list">
|
|
367
|
+
${I.map(o=>ge({workspaceId:t.id,entry:o,pinned:R.has(o.path),onOpen:p,onPinToggle:d}))}
|
|
368
|
+
</div>
|
|
369
|
+
</section>
|
|
370
|
+
`:c}
|
|
371
|
+
|
|
372
|
+
<section class="ws-section" aria-label="Artifacts">
|
|
373
|
+
<div class="ws-section__header">
|
|
374
|
+
<h3>Artifacts</h3>
|
|
375
|
+
<span>${x?L.length:g.length}</span>
|
|
376
|
+
${v&&g.length>0?a`<button class="ws-export-drive-btn" aria-label="Export all artifacts to Google Drive" @click=${()=>{const o=g.map(C=>C.path);v(o)}}>Export to Drive</button>`:c}
|
|
377
|
+
</div>
|
|
378
|
+
<div class="ws-list ws-list--scroll" role="list" aria-label="Artifacts list">
|
|
379
|
+
${x?L.length===0?a`<div class="ws-empty">
|
|
380
|
+
<span class="ws-empty-hint">No artifacts yet. Ask your ally to create a document, plan, or analysis — it'll appear here.</span>
|
|
381
|
+
</div>`:L.map(o=>ue(o,0,M)):g.length===0?a`<div class="ws-empty">
|
|
382
|
+
<span class="ws-empty-hint">No artifacts yet. Ask your ally to create a document, plan, or analysis — it'll appear here.</span>
|
|
383
|
+
</div>`:g.map(o=>j({workspaceId:t.id,entry:o,pinned:!1,onOpen:p,onPinToggle:d}))}
|
|
384
|
+
</div>
|
|
385
|
+
</section>
|
|
386
|
+
|
|
387
|
+
${N?a`
|
|
388
|
+
<section class="ws-section" aria-label="Sessions">
|
|
389
|
+
<div class="ws-section__header">
|
|
390
|
+
<h3>Sessions</h3>
|
|
391
|
+
<span>${O.length}</span>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="ws-list ws-list--scroll" role="list" aria-label="Sessions list">
|
|
394
|
+
${O.length===0?a`
|
|
395
|
+
<div class="ws-empty">
|
|
396
|
+
<span class="ws-empty-hint">No sessions yet. Sessions are saved conversations with your ally — start a chat to create one.</span>
|
|
397
|
+
</div>
|
|
398
|
+
`:O.map(o=>a`
|
|
399
|
+
<div class="ws-list-row" role="listitem">
|
|
400
|
+
<button class="ws-list-main ws-list-row--button" @click=${()=>$?.(o)} aria-label="Open session: ${o.title}">
|
|
401
|
+
<span class=${te(o.status)} aria-label="Status: ${o.status}"></span>
|
|
402
|
+
<span class="ws-list-title">${o.title}</span>
|
|
403
|
+
<span class="ws-list-meta">${P(o.created.getTime())}</span>
|
|
404
|
+
</button>
|
|
405
|
+
<button
|
|
406
|
+
class="ws-pin-btn ${B.has(o.key)?"active":""}"
|
|
407
|
+
@click=${()=>m?.(t.id,o.key,B.has(o.key))}
|
|
408
|
+
title=${B.has(o.key)?"Unpin":"Pin"}
|
|
409
|
+
aria-label="${B.has(o.key)?"Unpin":"Pin"} session: ${o.title}"
|
|
410
|
+
>
|
|
411
|
+
${B.has(o.key)?"Unpin":"Pin"}
|
|
412
|
+
</button>
|
|
413
|
+
</div>
|
|
414
|
+
`)}
|
|
415
|
+
</div>
|
|
416
|
+
</section>
|
|
417
|
+
`:c}
|
|
418
|
+
|
|
419
|
+
${(t.memory?.length??0)>0?a`
|
|
420
|
+
<section class="ws-section" aria-label="Workspace memory">
|
|
421
|
+
<div class="ws-section__header">
|
|
422
|
+
<h3>Memory</h3>
|
|
423
|
+
<span>${t.memory.length}</span>
|
|
424
|
+
</div>
|
|
425
|
+
<div class="ws-list ws-list--scroll" role="list" aria-label="Memory files list">
|
|
426
|
+
${t.memory.map(o=>j({workspaceId:t.id,entry:o,pinned:R.has(o.path),onOpen:p,onPinToggle:d}))}
|
|
427
|
+
</div>
|
|
428
|
+
</section>
|
|
429
|
+
`:c}
|
|
430
|
+
|
|
431
|
+
${Ce({entries:t.feedEntries??[],onPost:e.onPostToFeed,onLoadMore:e.onLoadMoreFeed})}
|
|
432
|
+
|
|
433
|
+
${Pe({connections:t.connections??[],onTest:e.onTestConnection,onRemove:e.onRemoveConnection})}
|
|
434
|
+
|
|
435
|
+
${De(t.members??[])}
|
|
436
|
+
</div>
|
|
437
|
+
</div>
|
|
438
|
+
`}function Ce(e){const{entries:t,onPost:s,onLoadMore:n}=e;function i(r){switch(r){case"decision":return"📝";case"request":return"❓";case"artifact":return"📦";case"sop":return"📋";case"alert":return"🚨";default:return"💬"}}function l(r){return r.includes("agent")||r.includes(":agent")?"🤖":r==="system"?"⚙️":"👤"}return a`
|
|
439
|
+
<section class="ws-section" aria-label="Activity feed">
|
|
440
|
+
<div class="ws-section__header">
|
|
441
|
+
<h3>Activity Feed</h3>
|
|
442
|
+
<span>${t.length}</span>
|
|
443
|
+
</div>
|
|
444
|
+
<div class="ws-list ws-list--scroll" role="list" aria-live="polite" aria-label="Feed entries" style="max-height: 400px;">
|
|
445
|
+
${t.length===0?a`<div class="ws-empty">
|
|
446
|
+
<span class="ws-empty-hint">No activity yet. Post updates, decisions, or requests to the feed.</span>
|
|
447
|
+
</div>`:t.map(r=>a`
|
|
448
|
+
<div class="ws-list-row ws-feed-entry">
|
|
449
|
+
<div class="ws-list-main" style="flex-direction: column; align-items: flex-start; gap: 4px; padding: 8px 12px;">
|
|
450
|
+
<div style="display: flex; align-items: center; gap: 8px; width: 100%;">
|
|
451
|
+
<span>${l(r.author)}</span>
|
|
452
|
+
<span class="ws-list-title" style="font-weight: 500;">${r.author}</span>
|
|
453
|
+
<span style="margin-left: auto;">${i(r.type)}</span>
|
|
454
|
+
<span class="ws-list-meta">${P(new Date(r.ts).getTime())}</span>
|
|
455
|
+
</div>
|
|
456
|
+
<div style="padding-left: 28px; opacity: 0.9; font-size: 0.9em;">${r.text}</div>
|
|
457
|
+
</div>
|
|
458
|
+
</div>
|
|
459
|
+
`)}
|
|
460
|
+
</div>
|
|
461
|
+
${t.length>=50&&n?a`<button class="ws-task-completed-toggle" aria-label="Load more feed entries" @click=${()=>n()}>Load more...</button>`:c}
|
|
462
|
+
${s?a`
|
|
463
|
+
<form
|
|
464
|
+
class="ws-task-create-form"
|
|
465
|
+
aria-label="Post to activity feed"
|
|
466
|
+
@submit=${r=>{r.preventDefault();const p=r.currentTarget,$=p.querySelector(".ws-feed-input"),d=p.querySelector(".ws-feed-type"),m=$.value.trim();m&&(s(m,d.value),$.value="")}}
|
|
467
|
+
>
|
|
468
|
+
<input
|
|
469
|
+
type="text"
|
|
470
|
+
class="ws-task-create-input ws-feed-input"
|
|
471
|
+
placeholder="Post to feed..."
|
|
472
|
+
aria-label="Feed post content"
|
|
473
|
+
/>
|
|
474
|
+
<select class="ws-task-create-project ws-feed-type" aria-label="Post type">
|
|
475
|
+
<option value="update">Update</option>
|
|
476
|
+
<option value="decision">Decision</option>
|
|
477
|
+
<option value="request">Request</option>
|
|
478
|
+
<option value="sop">SOP</option>
|
|
479
|
+
<option value="artifact">Artifact</option>
|
|
480
|
+
</select>
|
|
481
|
+
<button type="submit" class="ws-task-create-btn" aria-label="Submit post">Post</button>
|
|
482
|
+
</form>
|
|
483
|
+
`:c}
|
|
484
|
+
</section>
|
|
485
|
+
`}function Pe(e){const{connections:t,onTest:s,onRemove:n}=e;function i(l){return l==="connected"?a`<span class="ws-conn-status ws-conn-status--ok">Connected</span>`:l==="error"?a`<span class="ws-conn-status ws-conn-status--error">Error</span>`:a`<span class="ws-conn-status ws-conn-status--unconfigured">Not configured</span>`}return t.length===0?a`
|
|
486
|
+
<section class="ws-section" aria-label="Connections">
|
|
487
|
+
<div class="ws-section__header">
|
|
488
|
+
<h3>Connections</h3>
|
|
489
|
+
<span>0</span>
|
|
490
|
+
</div>
|
|
491
|
+
<div class="ws-empty">
|
|
492
|
+
<span class="ws-empty-hint">No tools connected. Connect Google Drive, ClickUp, HubSpot, or other shared tools via Settings.</span>
|
|
493
|
+
</div>
|
|
494
|
+
</section>
|
|
495
|
+
`:a`
|
|
496
|
+
<section class="ws-section" aria-label="Connections">
|
|
497
|
+
<div class="ws-section__header">
|
|
498
|
+
<h3>Connections</h3>
|
|
499
|
+
<span>${t.length}</span>
|
|
500
|
+
</div>
|
|
501
|
+
<div class="ws-list" role="list" aria-label="Connection list">
|
|
502
|
+
${t.map(l=>a`
|
|
503
|
+
<div class="ws-list-row" role="listitem">
|
|
504
|
+
<div class="ws-list-main" style="gap: 8px;">
|
|
505
|
+
<span class="ws-list-title">${l.name}</span>
|
|
506
|
+
${i(l.status)}
|
|
507
|
+
${l.lastSync?a`<span class="ws-list-meta">Synced ${P(new Date(l.lastSync).getTime())}</span>`:c}
|
|
508
|
+
${l.error?a`<span class="ws-list-meta" style="color: var(--danger-color, #e74c3c);">${l.error}</span>`:c}
|
|
509
|
+
</div>
|
|
510
|
+
<div style="display: flex; gap: 4px;">
|
|
511
|
+
${s?a`<button class="ws-pin-btn" @click=${()=>s(l.id)} title="Test connection" aria-label="Test connection: ${l.name}">Test</button>`:c}
|
|
512
|
+
${n?a`<button class="ws-pin-btn" @click=${()=>{confirm(`Remove connection "${l.name}"?`)&&n(l.id)}} title="Remove connection" aria-label="Remove connection: ${l.name}">Remove</button>`:c}
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
`)}
|
|
516
|
+
</div>
|
|
517
|
+
</section>
|
|
518
|
+
`}function De(e){return e.length===0?a``:a`
|
|
519
|
+
<section class="ws-section" aria-label="Workspace members">
|
|
520
|
+
<div class="ws-section__header">
|
|
521
|
+
<h3>Members</h3>
|
|
522
|
+
<span>${e.length}</span>
|
|
523
|
+
</div>
|
|
524
|
+
<div class="ws-list" role="list" aria-label="Members list">
|
|
525
|
+
${e.map(t=>a`
|
|
526
|
+
<div class="ws-list-row" role="listitem">
|
|
527
|
+
<div class="ws-list-main">
|
|
528
|
+
<span aria-hidden="true">\u{1F464}</span>
|
|
529
|
+
<span class="ws-list-title">${t.name}</span>
|
|
530
|
+
<span class="ws-list-meta">${t.role}</span>
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
`)}
|
|
534
|
+
</div>
|
|
535
|
+
</section>
|
|
536
|
+
`}function Fe(e){const{tasks:t,workspaceName:s,showCompleted:n,onToggleTaskComplete:i,onCreateTask:l,onToggleCompletedTasks:r,onStartTask:p,onViewTaskOutput:$,editingTaskId:d,onEditTask:m,onUpdateTask:u}=e,k=V(t.filter(f=>f.status==="pending")),b=V(t.filter(f=>f.status==="complete"));return a`
|
|
537
|
+
<section class="ws-section" aria-label="Workspace tasks">
|
|
538
|
+
<div class="ws-section__header">
|
|
539
|
+
<h3>Tasks</h3>
|
|
540
|
+
<span>${k.length} open${b.length>0?`, ${b.length} done`:""}</span>
|
|
541
|
+
</div>
|
|
542
|
+
<div class="ws-list ws-list--scroll" role="list" aria-live="polite" aria-label="Task list">
|
|
543
|
+
${k.length===0&&b.length===0?a`<div class="ws-empty">No tasks</div>`:c}
|
|
544
|
+
${k.map(f=>se(f,i,p,d,m,u,$))}
|
|
545
|
+
${b.length>0?a`
|
|
546
|
+
<button class="ws-task-completed-toggle" aria-expanded=${n} @click=${()=>r?.()}>
|
|
547
|
+
${n?"Hide":"Show"} ${b.length} completed
|
|
548
|
+
</button>
|
|
549
|
+
${n?b.map(f=>se(f,i,p,d,m,u,$)):c}
|
|
550
|
+
`:c}
|
|
551
|
+
</div>
|
|
552
|
+
${l?a`
|
|
553
|
+
<form
|
|
554
|
+
class="ws-task-create-form"
|
|
555
|
+
aria-label="Create new task"
|
|
556
|
+
@submit=${f=>{f.preventDefault();const h=f.currentTarget.querySelector("input"),T=h.value.trim();T&&(l(T,s),h.value="")}}
|
|
557
|
+
>
|
|
558
|
+
<input
|
|
559
|
+
type="text"
|
|
560
|
+
class="ws-task-create-input"
|
|
561
|
+
placeholder="Add a task..."
|
|
562
|
+
aria-label="New task title"
|
|
563
|
+
/>
|
|
564
|
+
<button type="submit" class="ws-task-create-btn" aria-label="Add task">Add</button>
|
|
565
|
+
</form>
|
|
566
|
+
`:c}
|
|
567
|
+
</section>
|
|
568
|
+
`}function Re(e){const{connected:t,workspaces:s,selectedWorkspace:n,searchQuery:i,itemSearchQuery:l,expandedFolders:r,loading:p,createLoading:$,error:d,allTasks:m=[],taskFilter:u="outstanding",taskSort:k="due",taskSearch:b="",showCompletedTasks:f=!1,editingTaskId:D,workspaceNames:h=[],onSearch:T,onItemSearch:w,onSelectWorkspace:v,onBack:S,onItemClick:F,onSessionClick:g,onPinToggle:x,onPinSessionToggle:L,onCreateWorkspace:O,onDeleteWorkspace:B,onToggleFolder:R,onTeamSetup:A,onToggleTaskComplete:_,onCreateTask:N,onSetTaskFilter:I,onSetTaskSort:W,onSetTaskSearch:M,onToggleCompletedTasks:o,onStartTask:C,onViewTaskOutput:we,onEditTask:G,onUpdateTask:H}=e,U=s.filter(y=>be(i,`${y.name} ${y.path} ${y.type}`));return n?Se({workspace:n,itemSearchQuery:l??"",expandedFolders:r,showCompletedTasks:f,onItemSearch:w,onBack:S,onItemClick:F,onSessionClick:g,onPinToggle:x,onPinSessionToggle:L,onToggleFolder:R,onToggleTaskComplete:_,onCreateTask:N,onToggleCompletedTasks:o,onStartTask:C,editingTaskId:D,onEditTask:G,onUpdateTask:H,browsePath:e.browsePath,browseEntries:e.browseEntries,breadcrumbs:e.breadcrumbs,browseSearchQuery:e.browseSearchQuery,browseSearchResults:e.browseSearchResults,onBrowseFolder:e.onBrowseFolder,onBrowseSearch:e.onBrowseSearch,onBrowseBack:e.onBrowseBack,onCreateFolder:e.onCreateFolder,onBatchPushToDrive:e.onBatchPushToDrive,onPostToFeed:e.onPostToFeed,onLoadMoreFeed:e.onLoadMoreFeed,onTestConnection:e.onTestConnection,onRemoveConnection:e.onRemoveConnection}):a`
|
|
569
|
+
<div class="workspaces-container" role="region" aria-label="Workspaces">
|
|
570
|
+
<div class="workspaces-toolbar" role="toolbar" aria-label="Workspace controls">
|
|
571
|
+
<form
|
|
572
|
+
class="workspaces-create-form"
|
|
573
|
+
aria-label="Create new workspace"
|
|
574
|
+
@submit=${async y=>{if(y.preventDefault(),$||!O)return;const K=y.currentTarget,q=new FormData(K),X=q.get("name"),J=(typeof X=="string"?X:"").trim();if(!J)return;const Y=q.get("type"),E=(typeof Y=="string"?Y:"project").trim().toLowerCase(),me=E==="team"||E==="personal"?E:"project",Z=q.get("path"),ee=(typeof Z=="string"?Z:"").trim();await O({name:J,type:me,...ee?{path:ee}:{}})!==!1&&K.reset()}}
|
|
575
|
+
>
|
|
576
|
+
<input
|
|
577
|
+
type="text"
|
|
578
|
+
name="name"
|
|
579
|
+
class="workspaces-create-input"
|
|
580
|
+
placeholder="New workspace name (e.g. Acme Corp)"
|
|
581
|
+
aria-label="Workspace name"
|
|
582
|
+
required
|
|
583
|
+
/>
|
|
584
|
+
<select name="type" class="workspaces-create-select" aria-label="Workspace type">
|
|
585
|
+
<option value="project">Project</option>
|
|
586
|
+
<option value="team">Team</option>
|
|
587
|
+
<option value="personal">Personal</option>
|
|
588
|
+
</select>
|
|
589
|
+
<input
|
|
590
|
+
type="text"
|
|
591
|
+
name="path"
|
|
592
|
+
class="workspaces-create-input workspaces-create-input--path"
|
|
593
|
+
placeholder="Optional path (auto-created if blank)"
|
|
594
|
+
aria-label="Workspace path (optional)"
|
|
595
|
+
/>
|
|
596
|
+
<button
|
|
597
|
+
type="submit"
|
|
598
|
+
class="workspaces-add-btn"
|
|
599
|
+
aria-label="Create workspace"
|
|
600
|
+
?disabled=${!!$}
|
|
601
|
+
>
|
|
602
|
+
${$?"Adding...":"Add Workspace"}
|
|
603
|
+
</button>
|
|
604
|
+
</form>
|
|
605
|
+
<input
|
|
606
|
+
type="text"
|
|
607
|
+
class="workspaces-search-input"
|
|
608
|
+
placeholder="Search workspaces..."
|
|
609
|
+
aria-label="Search workspaces"
|
|
610
|
+
.value=${i}
|
|
611
|
+
@input=${y=>T?.(y.target.value)}
|
|
612
|
+
/>
|
|
613
|
+
<span class="workspaces-count" aria-live="polite">${U.length} workspaces</span>
|
|
614
|
+
<span class="workspaces-status ${t?"online":"offline"}" role="status">
|
|
615
|
+
${t?"Online":"Offline"}
|
|
616
|
+
</span>
|
|
617
|
+
${A?a`<button class="ws-team-setup-btn" aria-label="Start team workspace setup" @click=${()=>A()}>Team Setup</button>`:c}
|
|
618
|
+
</div>
|
|
619
|
+
|
|
620
|
+
${d?a`<div class="callout danger" role="alert" style="margin: 16px;">${d}</div>`:c}
|
|
621
|
+
|
|
622
|
+
${p?a`
|
|
623
|
+
<div class="workspaces-loading" role="status" aria-label="Loading workspaces">
|
|
624
|
+
<div class="spinner" aria-hidden="true"></div>
|
|
625
|
+
<span>Loading workspaces...</span>
|
|
626
|
+
</div>
|
|
627
|
+
`:a`
|
|
628
|
+
<div class="workspaces-body">
|
|
629
|
+
<div class="workspace-grid" role="list" aria-label="Workspace list">
|
|
630
|
+
${U.length===0?a`
|
|
631
|
+
<div class="workspaces-empty">
|
|
632
|
+
<span class="workspaces-empty-icon" aria-hidden="true">${t?"📭":"🔌"}</span>
|
|
633
|
+
<span>${t?"No workspaces yet":"Connect to gateway to see workspaces"}</span>
|
|
634
|
+
${t?a`<span class="workspaces-empty-hint">Workspaces organize your projects. Ask your ally to create one, or start a focused session in chat.</span>`:c}
|
|
635
|
+
</div>
|
|
636
|
+
`:U.map(y=>ve(y,v,B))}
|
|
637
|
+
</div>
|
|
638
|
+
|
|
639
|
+
${xe({tasks:m,taskFilter:u,taskSort:k,taskSearch:b,onToggleTaskComplete:_,onSetTaskFilter:I,onSetTaskSort:W,onSetTaskSearch:M,onCreateTask:N,workspaceNames:h,onStartTask:C,editingTaskId:D,onEditTask:G,onUpdateTask:H,onViewTaskOutput:we})}
|
|
640
|
+
</div>
|
|
641
|
+
`}
|
|
642
|
+
</div>
|
|
643
|
+
`}function xe(e){const{tasks:t,taskFilter:s,taskSort:n="due",taskSearch:i="",onToggleTaskComplete:l,onSetTaskFilter:r,onSetTaskSort:p,onSetTaskSearch:$,onCreateTask:d,workspaceNames:m=[],onStartTask:u,editingTaskId:k,onEditTask:b,onUpdateTask:f,onViewTaskOutput:D}=e;if(t.length===0&&!d)return a``;let h;if(s==="outstanding")h=t.filter(w=>w.status==="pending");else if(s==="today"){const w=Q();h=t.filter(v=>v.status==="pending"&&v.dueDate!=null&&v.dueDate<=w)}else s==="complete"?h=t.filter(w=>w.status==="complete"):h=t;if(i){const w=i.toLowerCase();h=h.filter(v=>v.title.toLowerCase().includes(w)||v.project?.toLowerCase().includes(w))}const T=V(h,n);return a`
|
|
644
|
+
<div class="ws-all-tasks-section">
|
|
645
|
+
<section class="ws-section" aria-label="All tasks">
|
|
646
|
+
<div class="ws-section__header">
|
|
647
|
+
<div class="ws-section__header-left">
|
|
648
|
+
<h3>All Tasks</h3>
|
|
649
|
+
${$?a`<input
|
|
650
|
+
type="text"
|
|
651
|
+
class="ws-task-search"
|
|
652
|
+
placeholder="Search tasks..."
|
|
653
|
+
aria-label="Search tasks"
|
|
654
|
+
.value=${i}
|
|
655
|
+
@input=${w=>$(w.target.value)}
|
|
656
|
+
/>`:c}
|
|
657
|
+
</div>
|
|
658
|
+
<div class="ws-task-controls">
|
|
659
|
+
<div class="ws-task-filters" role="group" aria-label="Task filters">
|
|
660
|
+
<button
|
|
661
|
+
class="ws-task-filter-btn ${s==="all"?"active":""}"
|
|
662
|
+
@click=${()=>r?.("all")}
|
|
663
|
+
aria-pressed=${s==="all"}
|
|
664
|
+
>All</button>
|
|
665
|
+
<button
|
|
666
|
+
class="ws-task-filter-btn ${s==="outstanding"?"active":""}"
|
|
667
|
+
@click=${()=>r?.("outstanding")}
|
|
668
|
+
aria-pressed=${s==="outstanding"}
|
|
669
|
+
>To Do</button>
|
|
670
|
+
<button
|
|
671
|
+
class="ws-task-filter-btn ${s==="today"?"active":""}"
|
|
672
|
+
@click=${()=>r?.("today")}
|
|
673
|
+
aria-pressed=${s==="today"}
|
|
674
|
+
>Today</button>
|
|
675
|
+
<button
|
|
676
|
+
class="ws-task-filter-btn ${s==="complete"?"active":""}"
|
|
677
|
+
@click=${()=>r?.("complete")}
|
|
678
|
+
aria-pressed=${s==="complete"}
|
|
679
|
+
>Done</button>
|
|
680
|
+
</div>
|
|
681
|
+
<select
|
|
682
|
+
class="ws-task-sort"
|
|
683
|
+
aria-label="Sort tasks by"
|
|
684
|
+
.value=${n}
|
|
685
|
+
@change=${w=>p?.(w.target.value)}
|
|
686
|
+
>
|
|
687
|
+
<option value="due">Due Date</option>
|
|
688
|
+
<option value="priority">Priority</option>
|
|
689
|
+
<option value="newest">Newest</option>
|
|
690
|
+
</select>
|
|
691
|
+
</div>
|
|
692
|
+
</div>
|
|
693
|
+
${d?a`
|
|
694
|
+
<form
|
|
695
|
+
class="ws-task-create-form"
|
|
696
|
+
aria-label="Create new task"
|
|
697
|
+
@submit=${w=>{w.preventDefault();const v=w.currentTarget,S=v.querySelector(".ws-task-create-input"),F=v.querySelector(".ws-task-create-project"),g=S.value.trim();if(!g)return;const x=F?.value||m[0]||"";d(g,x),S.value=""}}
|
|
698
|
+
>
|
|
699
|
+
<input
|
|
700
|
+
type="text"
|
|
701
|
+
class="ws-task-create-input"
|
|
702
|
+
placeholder="Add a task..."
|
|
703
|
+
aria-label="New task title"
|
|
704
|
+
/>
|
|
705
|
+
${m.length>0?a`
|
|
706
|
+
<select class="ws-task-create-project" aria-label="Task workspace">
|
|
707
|
+
${m.map(w=>a`<option value=${w}>${w}</option>`)}
|
|
708
|
+
</select>
|
|
709
|
+
`:c}
|
|
710
|
+
<button type="submit" class="ws-task-create-btn" aria-label="Add task">Add</button>
|
|
711
|
+
</form>
|
|
712
|
+
`:c}
|
|
713
|
+
<div class="ws-list ws-list--scroll" role="list" aria-live="polite" aria-label="Task list">
|
|
714
|
+
${T.length===0?a`<div class="ws-empty">No tasks</div>`:T.map(w=>$e(w,l,u,k,b,f,D))}
|
|
715
|
+
</div>
|
|
716
|
+
</section>
|
|
717
|
+
</div>
|
|
718
|
+
`}export{$e as a,Re as r,V as s};
|