botnote 0.1.16 → 0.1.19
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/README.md
CHANGED
|
@@ -145,7 +145,7 @@ setup is required.
|
|
|
145
145
|
|
|
146
146
|
```text
|
|
147
147
|
# In Claude Code
|
|
148
|
-
/plugin marketplace add
|
|
148
|
+
/plugin marketplace add jianhua-wang/botnote
|
|
149
149
|
/plugin install botnote@botnote
|
|
150
150
|
|
|
151
151
|
# Claude Code will prompt for:
|
|
@@ -167,9 +167,10 @@ Slash commands:
|
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
Plugin distribution lives at
|
|
170
|
-
[
|
|
171
|
-
inside the plugin uses the URL + token from the install prompt
|
|
172
|
-
`botnote` CLI
|
|
170
|
+
[jianhua-wang/botnote](https://github.com/jianhua-wang/botnote). The MCP server
|
|
171
|
+
inside the plugin uses the URL + token from the install prompt. A global
|
|
172
|
+
`botnote` CLI install is optional: the plugin runs `npx -y botnote@<plugin-version> mcp`
|
|
173
|
+
when no matching local CLI is available.
|
|
173
174
|
|
|
174
175
|
### Codex
|
|
175
176
|
|
|
@@ -177,8 +178,8 @@ Add the plugin through `/settings -> plugin` in Codex, or add this marketplace
|
|
|
177
178
|
from the public repository without a full source checkout:
|
|
178
179
|
|
|
179
180
|
```bash
|
|
180
|
-
codex plugin marketplace add https://github.com/
|
|
181
|
-
--sparse .
|
|
181
|
+
codex plugin marketplace add https://github.com/jianhua-wang/botnote.git \
|
|
182
|
+
--sparse marketplace.json \
|
|
182
183
|
--sparse plugins/botnote
|
|
183
184
|
|
|
184
185
|
codex plugin add botnote@botnote-plugins
|
|
@@ -225,9 +226,10 @@ source = "/absolute/path/to/botnote"
|
|
|
225
226
|
```
|
|
226
227
|
|
|
227
228
|
The Codex plugin starts `./scripts/run-mcp.sh`. It defaults to
|
|
228
|
-
`BOTNOTE_URL=
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
`BOTNOTE_URL=https://botnote.net`, reads `~/.config/botnote/config.json` when
|
|
230
|
+
available, uses a matching `botnote` CLI from PATH when present, and otherwise
|
|
231
|
+
runs the exact plugin version with `npx -y botnote@<plugin-version> mcp`. Set
|
|
232
|
+
`BOTNOTE_URL` and `BOTNOTE_TOKEN` only when using a custom daemon.
|
|
231
233
|
|
|
232
234
|
### Cursor
|
|
233
235
|
|
|
@@ -237,7 +239,7 @@ same MCP server and workflow skills without a second plugin implementation.
|
|
|
237
239
|
|
|
238
240
|
```bash
|
|
239
241
|
# Marketplace root for Cursor plugin clients:
|
|
240
|
-
https://github.com/
|
|
242
|
+
https://github.com/jianhua-wang/botnote
|
|
241
243
|
```
|
|
242
244
|
|
|
243
245
|
The Cursor plugin manifest is `plugins/botnote/.cursor-plugin/plugin.json` and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botnote",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "Notion for bots. Lightweight project + notes + memory store, agent-first.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.33.0",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"homepage": "https://botnote.net",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "
|
|
11
|
+
"url": "https://github.com/Jianhua-Wang/botnote"
|
|
12
12
|
},
|
|
13
13
|
"bugs": {
|
|
14
14
|
"url": "https://github.com/Jianhua-Wang/botnote/issues"
|
|
@@ -482,7 +482,8 @@ BOTNOTE_URL=http://127.0.0.1:4280 botnote today
|
|
|
482
482
|
|
|
483
483
|
# Config file (preferred for the daemon host):
|
|
484
484
|
# ~/.config/botnote/config.json
|
|
485
|
-
# { "baseUrl": "http://127.0.0.1:4280" }`})]})}function rU(){return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"Plugin",blurb:"Install the botnote runtime once, then add the plugin for each agent client. The plugin bundles MCP, slash commands, and workflow skills, so Letheia / Plane MCP setup should stay retired."}),O.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-2",children:[O.jsx(kO,{icon:zS,title:"1. Runtime",body:"Install or update the npm binary on every device. Plugins call this binary for MCP."}),O.jsx(kO,{icon:LB,title:"2. Client plugin",body:"Install the marketplace plugin in Claude Code, Codex, Cursor, or another agent client."}),O.jsx(kO,{icon:FT,title:"3. Update both",body:"Runtime and plugin cache update separately. Refresh the client after updating."})]}),O.jsxs("div",{className:"border border-accent/20 bg-accentSoft/50 rounded-md px-4 py-3 text-xs text-accentText leading-relaxed",children:["Use ",O.jsx("code",{className:"text-ink",children:"https://botnote.net"})," with an API token from this settings page on remote devices. On the daemon host, use"," ",O.jsx("code",{className:"text-ink",children:"http://127.0.0.1:4280"})," and skip the token."]}),O.jsx(xo,{icon:zS,title:"Runtime",subtitle:"Required first. Claude Code, Codex, and Cursor all launch this binary for MCP."}),O.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3",children:[O.jsx(on,{title:"Install runtime",code:`#
|
|
485
|
+
# { "baseUrl": "http://127.0.0.1:4280" }`})]})}function rU(){return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"Plugin",blurb:"Install the botnote runtime once, then add the plugin for each agent client. The plugin bundles MCP, slash commands, and workflow skills, so Letheia / Plane MCP setup should stay retired."}),O.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-2",children:[O.jsx(kO,{icon:zS,title:"1. Runtime",body:"Install or update the npm binary on every device. Plugins call this binary for MCP."}),O.jsx(kO,{icon:LB,title:"2. Client plugin",body:"Install the marketplace plugin in Claude Code, Codex, Cursor, or another agent client."}),O.jsx(kO,{icon:FT,title:"3. Update both",body:"Runtime and plugin cache update separately. Refresh the client after updating."})]}),O.jsxs("div",{className:"border border-accent/20 bg-accentSoft/50 rounded-md px-4 py-3 text-xs text-accentText leading-relaxed",children:["Use ",O.jsx("code",{className:"text-ink",children:"https://botnote.net"})," with an API token from this settings page on remote devices. On the daemon host, use"," ",O.jsx("code",{className:"text-ink",children:"http://127.0.0.1:4280"})," and skip the token."]}),O.jsx(xo,{icon:zS,title:"Runtime",subtitle:"Required first. Claude Code, Codex, and Cursor all launch this binary for MCP."}),O.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3",children:[O.jsx(on,{title:"Install runtime",code:`# Optional helper CLI for login and manual commands.
|
|
486
|
+
# Plugins can run without a global CLI by using npx.
|
|
486
487
|
npm i -g botnote@latest
|
|
487
488
|
|
|
488
489
|
# Remote clients: save https://botnote.net + a bearer token.
|
|
@@ -505,7 +506,7 @@ botnote --version`})]}),O.jsx(xo,{icon:NB,title:"Claude Code",subtitle:"Recommen
|
|
|
505
506
|
# Manual update, if available in your Claude Code build:
|
|
506
507
|
claude plugin update botnote@botnote`})]}),O.jsx(xo,{icon:GT,title:"Codex",subtitle:"Use the Git marketplace flow; sparse checkout means no full botnote source checkout."}),O.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3",children:[O.jsx(on,{title:"Install",code:`# No full source checkout required.
|
|
507
508
|
codex plugin marketplace add https://github.com/jianhua-wang/botnote.git \\
|
|
508
|
-
--sparse .
|
|
509
|
+
--sparse marketplace.json \\
|
|
509
510
|
--sparse plugins/botnote
|
|
510
511
|
|
|
511
512
|
codex plugin add botnote@botnote-plugins`}),O.jsx(on,{title:"Update",code:`# Codex refreshes Git marketplaces, then installs from the fresh snapshot.
|
|
@@ -583,4 +584,4 @@ curl -X POST '${Vf}/v1/notes' \\
|
|
|
583
584
|
curl -X POST '${Vf}/v1/search' \\
|
|
584
585
|
-H 'authorization: Bearer bn_...' \\
|
|
585
586
|
-H 'content-type: application/json' \\
|
|
586
|
-
-d '{ "query": "deployment", "limit": 10 }'`;return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"MCP (raw integration)",blurb:"Skip the Claude Code plugin and wire the MCP server in by hand — for Codex, custom agents, or any MCP-aware client. The botnote binary doubles as the MCP stdio server."}),O.jsx(on,{title:"Claude Code (~/.claude.json or project-local .mcp.json)",code:n}),O.jsx(on,{title:"Codex (~/.codex/config.toml)",code:e}),O.jsx(on,{title:"REST · curl",code:t}),O.jsxs("div",{className:"border border-line rounded-md bg-surface px-4 py-3 text-xs text-muted leading-relaxed",children:["Requires the ",O.jsx("code",{className:"text-ink",children:"botnote"})," binary in",O.jsx("code",{className:"text-ink",children:" PATH"})," ","(",O.jsx("code",{className:"text-ink",children:"npm i -g botnote"}),"). The MCP server has no DB connection of its own; it speaks HTTP to whichever ",O.jsx("code",{className:"text-ink",children:"BOTNOTE_URL"})," you set."]})]})}function oU(){const{data:n,isLoading:e}=Lq(),t=n!=null&&n.version?`v${n.version}`:e?"loading...":"unknown";return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"About",blurb:"Build + runtime info for this daemon."}),O.jsxs("div",{className:"border border-line rounded-md bg-surface px-4 py-3 text-xs text-muted space-y-2",children:[O.jsxs("div",{children:[O.jsxs("span",{className:"text-ink",children:["botnote ",t]})," — Postgres 16 + pgvector + Fastify 5 + MCP SDK"]}),O.jsxs("div",{children:["REST: ",O.jsx("code",{className:"text-ink",children:Vf})," · docs:"," ",O.jsx("a",{className:"text-accent hover:underline",href:"/docs",target:"_blank",rel:"noreferrer",children:"/docs"})]}),O.jsxs("div",{className:"pt-1 border-t border-lineSoft",children:["Auth is enforced when ",O.jsx("code",{className:"text-ink",children:"BOTNOTE_REQUIRE_AUTH=1"})," on the daemon. Direct connections from loopback or private networks are trusted; requests via Cloudflare Tunnel (or any proxy that sets ",O.jsx("code",{children:"cf-connecting-ip"})," /"," ",O.jsx("code",{children:"x-forwarded-for"}),") require a bearer token or a browser session cookie."]})]})]})}function on({title:n,code:e}){const[t,r]=N.useState(!1);function i(){navigator.clipboard.writeText(e).then(()=>{r(!0),setTimeout(()=>r(!1),1400)})}return O.jsxs("div",{className:"border border-line rounded-md bg-surface overflow-hidden",children:[O.jsxs("div",{className:"px-3 py-1.5 border-b border-lineSoft flex items-center justify-between bg-sidebar/40",children:[O.jsx("span",{className:"text-xxs uppercase tracking-wider text-muted font-medium",children:n}),O.jsxs("button",{onClick:i,className:"text-xxs text-muted hover:text-ink flex items-center gap-1",children:[t?O.jsx(Nc,{size:11}):O.jsx(Wy,{size:11}),t?"Copied":"Copy"]})]}),O.jsx("pre",{className:"px-3 py-2 text-xs font-mono leading-relaxed overflow-x-auto whitespace-pre bg-sidebar/20 text-ink2",children:e})]})}function aU(){const{data:n,isLoading:e}=qq(),t=Fq(),r=Yq(),[i,s]=N.useState(""),[l,o]=N.useState(null),[u,h]=N.useState(null),[f,p]=N.useState(null),[m,y]=N.useState(null);function k(S){navigator.clipboard.writeText(S.plaintext).then(()=>{y(S.id),setTimeout(()=>y(C=>C===S.id?null:C),1400)})}async function b(S){if(S.preventDefault(),!i.trim())return;const C=await t.mutateAsync(i.trim());o(C),s("")}async function w(S,C){if(!u&&confirm(`Revoke token "${C}"? Any client using it stops working.`)){h(S),p(null);try{await r.mutateAsync(S),(l==null?void 0:l.id)===S&&o(null)}catch(Q){const A=Q instanceof Error?Q.message:String(Q);p(`Could not revoke "${C}": ${A}`)}finally{h(Q=>Q===S?null:Q)}}}return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"API tokens",blurb:"Bearer tokens for the CLI, MCP server, and direct REST calls. New tokens keep their full value available for copying here; older tokens created before this change only have a prefix and must be regenerated if the full value was lost."}),l&&O.jsxs("div",{className:"border border-warn rounded-md bg-warn/10 p-3 space-y-2",children:[O.jsxs("div",{className:"flex items-center gap-2 text-xs font-medium text-warn",children:[O.jsx(o6,{size:13}),"Copy this token now, or later from the token list."]}),O.jsxs("div",{className:"flex items-center gap-2",children:[O.jsx("code",{className:"flex-1 text-xs font-mono bg-surface border border-line rounded px-2 py-1 overflow-x-auto whitespace-nowrap",children:l.plaintext}),O.jsxs("button",{className:"btn",onClick:()=>navigator.clipboard.writeText(l.plaintext),children:[O.jsx(Wy,{size:11})," Copy"]}),O.jsx("button",{className:"btn",onClick:()=>o(null),children:"Done"})]})]}),f&&O.jsx("div",{className:"border border-danger/30 rounded-md bg-danger/10 px-3 py-2 text-xs text-danger",children:f}),O.jsxs("form",{onSubmit:b,className:"flex gap-2",children:[O.jsx("input",{className:"input flex-1",placeholder:"Token name (e.g. claude-code-laptop)",value:i,onChange:S=>s(S.target.value)}),O.jsxs("button",{type:"submit",className:"btn btn-primary",disabled:!i.trim()||t.isPending,children:[O.jsx(rp,{size:11})," ",t.isPending?"Generating…":"Generate"]})]}),O.jsxs("div",{className:"border border-line rounded-md bg-surface divide-y divide-lineSoft overflow-hidden",children:[e&&O.jsx("div",{className:"p-3 text-xs text-muted",children:"Loading…"}),!e&&(!n||n.length===0)&&O.jsx("div",{className:"p-4 text-xs text-faint text-center",children:"No tokens yet."}),n==null?void 0:n.map(S=>{const C=m===S.id;return O.jsxs("div",{className:"flex items-center gap-3 px-3 py-2",children:[O.jsxs("div",{className:"flex-1 min-w-0",children:[O.jsx("div",{className:"text-sm text-ink truncate",children:S.name}),O.jsxs("div",{className:"text-xxs text-muted flex items-center gap-3 mt-0.5",children:[O.jsxs("code",{className:"font-mono text-faint",children:[S.prefix,"…"]}),O.jsxs("span",{children:["created ",s0(new Date(S.createdAt),{addSuffix:!0})]}),O.jsx("span",{children:S.lastUsedAt?`used ${s0(new Date(S.lastUsedAt),{addSuffix:!0})}`:"never used"})]})]}),S.plaintext?O.jsxs("button",{type:"button",onClick:()=>k({id:S.id,plaintext:S.plaintext}),className:`btn gap-1.5 ${C?"!border-emerald-500/30 !text-emerald-600":""}`,title:"Copy full token",children:[C?O.jsx(Nc,{size:11}):O.jsx(Wy,{size:11}),C?"Copied":"Copy token"]}):O.jsx("span",{className:"text-xxs text-faint border border-line rounded px-2 py-1",title:"Full token is unavailable for tokens created before recoverable storage was enabled.",children:"Unavailable"}),O.jsx("button",{type:"button",className:"text-faint hover:text-danger p-1 -m-1",disabled:u!==null,onClick:()=>w(S.id,S.name),title:u===S.id?"Revoking":"Revoke",children:u===S.id?O.jsx("span",{className:"text-xxs text-muted",children:"Revoking…"}):O.jsx(KT,{size:12})})]},S.id)})]})]})}function uU({anchor:n,projectIds:e}){const t=Xx("day",n),{data:r}=Sa({from:t.from.toISOString(),to:t.to.toISOString(),projectIds:e??null,includeBacklog:!1,includeDone:!0}),{data:i}=sr(),s=N.useMemo(()=>Ca(i),[i]),{open:l}=Dt(),o=(r==null?void 0:r.overdue)??[],u=((r==null?void 0:r.scheduled)??[]).slice().sort(pp),h=fp(n);return O.jsx("div",{className:"h-full overflow-y-auto scrollbar-thin",children:O.jsxs("div",{className:"max-w-4xl mx-auto py-4",children:[h&&o.length>0&&O.jsx(ZP,{title:"Overdue",count:o.length,accent:"text-danger",tasks:o,projectMap:s}),O.jsx(ZP,{title:h?"Today":un(n,"EEEE"),count:u.length,accent:"text-ink",tasks:u,projectMap:s,emptyAction:O.jsx("button",{className:"text-accent text-xs hover:underline",onClick:()=>l({kind:"quick-create"}),children:"+ add a task for this day"})})]})})}function ZP({title:n,count:e,accent:t,tasks:r,projectMap:i,emptyAction:s}){return O.jsxs("section",{className:"mb-6",children:[O.jsxs("div",{className:"px-4 py-1.5 flex items-baseline gap-2 sticky top-0 bg-bg z-10",children:[O.jsx("h2",{className:`text-xs font-semibold ${t}`,children:n}),O.jsx("span",{className:"text-xxs text-faint tabular-nums",children:e})]}),r.length===0?O.jsx("div",{className:"px-4 py-2 text-xs text-muted",children:s??"Nothing here."}):O.jsx("div",{className:"bg-surface border-y border-lineSoft",children:r.map(l=>O.jsx(dp,{task:l,project:l.projectId?i.get(l.projectId):void 0},l.id))})]})}function cU({projectIds:n,collapsed:e,onToggle:t}){const{data:r}=Sa({projectIds:n??null,includeBacklog:!0,includeDone:!1}),{data:i}=sr(),s=N.useMemo(()=>Ca(i),[i]),l=((r==null?void 0:r.backlog)??[]).filter(o=>o.status!=="rejected");return e?O.jsxs("button",{className:"shrink-0 w-8 border-l border-line bg-sidebar/50 hover:bg-sidebar flex flex-col items-center pt-2 gap-2 group",onClick:t,title:"Expand Inbox",children:[O.jsx(Td,{size:14,className:"text-muted group-hover:text-ink"}),l.length>0&&O.jsx("div",{className:"text-xxs text-muted bg-surface border border-line rounded-full w-5 h-5 flex items-center justify-center",children:l.length})]}):O.jsxs("aside",{className:"shrink-0 w-72 border-l border-line bg-surface flex flex-col",children:[O.jsxs("div",{className:"px-3 h-9 flex items-center justify-between border-b border-lineSoft",children:[O.jsxs("div",{className:"flex items-center gap-2 text-muted",children:[O.jsx(Td,{size:12}),O.jsx("h2",{className:"text-xs font-medium text-ink2",children:"Inbox"}),O.jsx("span",{className:"text-xxs text-faint tabular-nums",children:l.length})]}),O.jsx("button",{onClick:t,className:"btn-ghost btn !h-6 !w-6 !p-0",title:"Collapse",children:"→"})]}),O.jsx("div",{className:"flex-1 overflow-y-auto scrollbar-thin",children:l.length===0?O.jsxs("div",{className:"text-xs text-muted text-center py-8 px-4",children:["No tasks without due date.",O.jsx("div",{className:"text-faint mt-1",children:"Tasks without due date appear here."})]}):l.map(o=>O.jsx(dp,{task:o,project:o.projectId?s.get(o.projectId):void 0,compact:!0},o.id))})]})}function PE({task:n,project:e}){const t=Vi(),r=n.dueAt&&new Date(n.dueAt).getTime()<Date.now()&&n.status!=="done"&&n.status!=="in_progress";return O.jsxs("div",{role:"button",tabIndex:0,draggable:!0,onDragStart:i=>{i.dataTransfer.setData("text/task-id",n.id),i.dataTransfer.effectAllowed="move",i.stopPropagation()},onClick:()=>t.open(n.id),onKeyDown:i=>{i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),t.open(n.id))},className:`group w-full text-left flex items-center gap-1.5 pl-1 pr-1.5 py-1 rounded text-xs hover:bg-sidebarHover transition-colors cursor-grab active:cursor-grabbing ${r?"bg-danger/5":""}`,title:e?`${e.key} · ${vn(n)}`:vn(n),children:[O.jsx("span",{className:"w-[2px] self-stretch rounded-sm shrink-0",style:{backgroundColor:(e==null?void 0:e.color)??"#a8a8af"}}),O.jsx(cp,{task:n,size:11}),O.jsx("span",{className:`truncate flex-1 min-w-0 ${n.status==="done"?"line-through text-muted":n.status==="rejected"?"text-muted":fi(n)?"italic text-muted":"text-ink2"}`,children:vn(n)}),n.priority!=="none"&&O.jsx(aa,{priority:n.priority,size:11})]})}const hU=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];function fU({anchor:n,projectIds:e}){const t=Xx("month",n),r=SE(t.from,t.to),{data:i}=Sa({from:t.from.toISOString(),to:t.to.toISOString(),projectIds:e??null,includeBacklog:!1,includeDone:!0}),{data:s}=sr(),l=N.useMemo(()=>Ca(s),[s]),o=N.useMemo(()=>bE((i==null?void 0:i.scheduled)??[]),[i]);return O.jsxs("div",{className:"h-full flex flex-col",children:[O.jsx("div",{className:"grid grid-cols-7 border-b border-lineSoft bg-sidebar/50",children:hU.map(u=>O.jsx("div",{className:"px-2 py-1 text-xxs uppercase tracking-wider text-muted text-center",children:u},u))}),O.jsx("div",{className:"flex-1 grid grid-cols-7 grid-rows-6 bg-line/30 gap-px overflow-y-auto scrollbar-thin",children:r.map(u=>{const h=o.get(wE(u))??[],f=!IY(u,n),p=fp(u);return O.jsx(dU,{day:u,tasks:h,projectMap:l,outOfMonth:f,today:p},u.toISOString())})})]})}function dU({day:n,tasks:e,projectMap:t,outOfMonth:r,today:i}){const{open:s}=Dt(),l=zl(),[o,u]=N.useState(!1),h=e.slice().sort(pp),f=h.filter(k=>k.status==="done").length,p=h.length,m=p>0&&f===p;function y(k){k.preventDefault(),u(!1);const b=k.dataTransfer.getData("text/task-id");if(!b)return;const w=new Date(n);w.setHours(12,0,0,0),l.mutate({id:b,fields:{dueAt:w.toISOString()}})}return O.jsxs("div",{className:`group bg-surface p-1 min-h-[112px] flex flex-col transition-colors ${r?"opacity-50":""} ${o?"ring-2 ring-accent ring-inset bg-accentSoft/40":i?"ring-1 ring-accent ring-inset bg-accentSoft/30":""}`,onDragOver:k=>{k.preventDefault(),o||u(!0)},onDragLeave:()=>u(!1),onDrop:y,children:[O.jsxs("div",{className:"flex items-center justify-between mb-1 px-1",children:[O.jsxs("div",{className:"flex items-baseline gap-1.5 min-w-0",children:[O.jsx("span",{className:`text-xs tabular-nums ${i?"font-semibold text-accent":"text-muted"}`,children:un(n,"d")}),p>0&&O.jsxs("span",{className:`text-xxs tabular-nums ${m?"text-statusDone font-medium":"text-faint"}`,title:`${f} done · ${p} total`,children:[f,"/",p]})]}),O.jsx("button",{className:"text-xs text-faint hover:text-accent opacity-0 group-hover:opacity-100 transition-opacity",onClick:()=>s({kind:"quick-create"}),title:"Add task",children:"+"})]}),O.jsxs("div",{className:"flex-1 space-y-0.5 min-h-0 overflow-hidden",children:[h.slice(0,4).map(k=>O.jsx(PE,{task:k,project:k.projectId?t.get(k.projectId):void 0},k.id)),h.length>4&&O.jsxs("div",{className:"text-xxs text-muted pl-1",children:["+",h.length-4]})]})]})}function pU({view:n,setView:e,anchor:t,setAnchor:r,projectIds:i,setProjectIds:s}){var h;const{data:l}=sr(),{open:o}=Dt(),u=i?i.length===1?((h=l==null?void 0:l.find(f=>f.id===i[0]))==null?void 0:h.key)??"1 project":`${i.length} projects`:"All projects";return O.jsx("div",{className:"border-b border-line bg-surface",children:O.jsxs("div",{className:"flex items-center justify-between h-11 px-3",children:[O.jsxs("div",{className:"flex items-center gap-3",children:[O.jsx("h1",{className:"text-xs font-semibold text-ink",children:"Tasks"}),O.jsx("div",{className:"seg",children:["day","week","month"].map(f=>O.jsx("button",{onClick:()=>e(f),"data-active":n===f,className:"capitalize",children:f},f))}),O.jsxs("div",{className:"flex items-center gap-1 ml-1",children:[O.jsx("button",{onClick:()=>r(OO(n,t,-1)),className:"btn btn-ghost !h-6 !w-6 !p-0",title:"Previous",children:O.jsx(zT,{size:12})}),O.jsx("button",{onClick:()=>r(OO(n,t,0)),className:"btn !h-6 px-2 text-xxs",title:"Today",children:"Today"}),O.jsx("button",{onClick:()=>r(OO(n,t,1)),className:"btn btn-ghost !h-6 !w-6 !p-0",title:"Next",children:O.jsx(ZT,{size:12})}),O.jsx("div",{className:"ml-2 text-xs font-medium text-ink2 tabular-nums",children:ZY(n,t)})]})]}),O.jsxs("div",{className:"flex items-center gap-1.5",children:[O.jsx(mU,{projects:l??[],projectIds:i,setProjectIds:s,label:u}),O.jsxs("button",{className:"btn btn-primary",onClick:()=>o({kind:"quick-create"}),title:"New task (c)",children:[O.jsx(rp,{size:11}),O.jsx("span",{className:"text-xs",children:"Task"}),O.jsx("kbd",{className:"!bg-white/15 !border-white/25 !text-white",children:"c"})]})]})]})})}function mU({projects:n,projectIds:e,setProjectIds:t,label:r}){return O.jsxs("details",{className:"relative",children:[O.jsxs("summary",{className:"btn list-none cursor-pointer",children:[O.jsx(zB,{size:11}),O.jsx("span",{className:"text-xs",children:r})]}),O.jsxs("div",{className:"popover top-9 right-0 w-56 px-1 py-1.5",children:[O.jsxs("button",{className:`popover-item ${e?"":"bg-accentSoft text-accentText"}`,onClick:()=>t(null),children:[O.jsx("span",{children:"All projects"}),!e&&O.jsx("span",{className:"ml-auto text-faint",children:"✓"})]}),O.jsx("div",{className:"divider my-1"}),n.map(i=>{const s=(e==null?void 0:e.includes(i.id))??!1;return O.jsxs("label",{className:"popover-item gap-2 cursor-pointer",children:[O.jsx("input",{type:"checkbox",className:"cursor-pointer",checked:s,onChange:()=>{if(!e)t([i.id]);else if(s){const l=e.filter(o=>o!==i.id);t(l.length?l:null)}else t([...e,i.id])}}),O.jsx("span",{className:"font-mono text-xxs text-faint tabular-nums",children:i.key}),O.jsx("span",{className:"text-ink2 truncate",children:i.name})]},i.id)})]})]})}function gU({anchor:n,projectIds:e}){const t=Xx("week",n),r=SE(t.from,t.to),i=hp(r[r.length-1],1),s=[...r,i],l=new Date(i);l.setHours(23,59,59,999);const{data:o}=Sa({from:t.from.toISOString(),to:l.toISOString(),projectIds:e??null,includeBacklog:!1,includeDone:!0}),{data:u}=sr(),h=N.useMemo(()=>Ca(u),[u]),f=N.useMemo(()=>bE((o==null?void 0:o.scheduled)??[]),[o]),p=s.slice(0,4),m=s.slice(4);return O.jsxs("div",{className:"h-full flex flex-col bg-bg",children:[O.jsx(XP,{days:p,byDay:f,projectMap:h,anchor:n}),O.jsx(XP,{days:m,byDay:f,projectMap:h,anchor:n})]})}function XP({days:n,byDay:e,projectMap:t,anchor:r}){return O.jsx("div",{className:"flex-1 min-h-0 flex border-b border-line last:border-b-0",children:n.map(i=>{const s=e.get(wE(i))??[],l=!DY(i,r,{weekStartsOn:1});return O.jsx(OU,{day:i,tasks:s,projectMap:t,outOfWeek:l},i.toISOString())})})}function OU({day:n,tasks:e,projectMap:t,outOfWeek:r}){const i=fp(n),{open:s}=Dt(),l=zl(),o=e.slice().sort(pp),u=o.filter(m=>m.status==="done").length,h=o.length,f=h>0&&u===h;function p(m){m.preventDefault();const y=m.dataTransfer.getData("text/task-id");if(!y)return;const k=new Date(n);k.setHours(12,0,0,0),l.mutate({id:y,fields:{dueAt:k.toISOString()}})}return O.jsxs("div",{className:`flex-1 min-w-0 border-r border-lineSoft last:border-r-0 flex flex-col group/col ${i?"bg-accentSoft/30":r?"bg-sidebar/40":"bg-surface"}`,onDragOver:m=>m.preventDefault(),onDrop:p,children:[O.jsxs("div",{className:"px-3 py-1.5 flex items-baseline justify-between border-b border-lineSoft",children:[O.jsxs("div",{className:"flex items-baseline gap-2 min-w-0",children:[O.jsx("span",{className:"text-xxs uppercase tracking-wider text-muted",children:un(n,"EEE")}),O.jsx("span",{className:`text-sm tabular-nums font-semibold ${i?"text-accent":r?"text-muted":"text-ink2"}`,children:un(n,"d")}),h>0&&O.jsxs("span",{className:`text-xxs tabular-nums ${f?"text-statusDone font-medium":"text-faint"}`,title:`${u} done · ${h} total`,children:[u,"/",h]}),r&&O.jsx("span",{className:"text-xxs text-faint italic",children:"next"})]}),O.jsx("button",{className:"text-faint hover:text-accent text-xs opacity-0 group-hover/col:opacity-100",title:"Add task",onClick:()=>s({kind:"quick-create"}),children:"+"})]}),O.jsx("div",{className:"flex-1 overflow-y-auto scrollbar-thin p-1.5 space-y-1",children:o.length===0?O.jsx("div",{className:"text-xxs text-faint px-1 py-0.5",children:"—"}):o.map(m=>O.jsx(PE,{task:m,project:m.projectId?t.get(m.projectId):void 0},m.id))})]})}function yU(){const[n,e]=N.useState("week"),[t,r]=N.useState(()=>new Date),[i,s]=N.useState(null),[l,o]=N.useState(!1);return O.jsxs("div",{className:"h-full flex flex-col",children:[O.jsx(pU,{view:n,setView:e,anchor:t,setAnchor:r,projectIds:i,setProjectIds:s}),O.jsxs("div",{className:"flex-1 min-h-0 flex",children:[O.jsxs("div",{className:"flex-1 min-w-0 overflow-hidden bg-bg",children:[n==="day"&&O.jsx(uU,{anchor:t,projectIds:i}),n==="week"&&O.jsx(gU,{anchor:t,projectIds:i}),n==="month"&&O.jsx(fU,{anchor:t,projectIds:i})]}),O.jsx(cU,{projectIds:i,collapsed:l,onToggle:()=>o(u=>!u)})]})]})}function xU(){const n=new Date,{data:e}=sr(),t=N.useMemo(()=>Ca(e),[e]),r=N.useMemo(()=>{const h=new Date(n);h.setHours(0,0,0,0);const f=new Date(n);return f.setHours(23,59,59,999),{from:h.toISOString(),to:f.toISOString()}},[]),{data:i,isLoading:s}=Sa({from:r.from,to:r.to,includeBacklog:!1,includeDone:!0}),{open:l}=Dt(),o=((i==null?void 0:i.overdue)??[]).filter(h=>h.status!=="rejected"),u=((i==null?void 0:i.scheduled)??[]).slice().sort(pp);return O.jsx("div",{className:"h-full overflow-y-auto scrollbar-thin",children:O.jsxs("div",{className:"max-w-3xl mx-auto px-6 py-6 space-y-6",children:[O.jsxs("header",{className:"flex items-baseline gap-3",children:[O.jsx(HT,{size:18,className:"text-accent"}),O.jsx("h1",{className:"text-lg font-semibold",children:"Today"}),O.jsx("span",{className:"text-xs text-muted",children:un(n,"EEEE, MMM d")})]}),s&&O.jsx("div",{className:"text-sm text-muted",children:"Loading…"}),!s&&O.jsxs(O.Fragment,{children:[O.jsx(BP,{title:"Overdue",count:o.length,accent:"text-danger",tasks:o,projectMap:t}),O.jsx(BP,{title:fp(n)?"Today":un(n,"EEEE"),count:u.length,accent:"text-ink",tasks:u,projectMap:t,emptyAction:O.jsx("button",{className:"text-accent text-xs hover:underline",onClick:()=>l({kind:"quick-create"}),children:"+ add a task"})})]})]})})}function BP({title:n,count:e,accent:t,tasks:r,projectMap:i,emptyAction:s}){if(r.length===0&&!s)return null;const l=new Map;for(const o of r){const u=o.projectId??null;l.has(u)||l.set(u,[]),l.get(u).push(o)}return O.jsxs("section",{className:"space-y-1.5",children:[O.jsxs("div",{className:"flex items-baseline gap-2",children:[O.jsx("h2",{className:`text-xs font-semibold ${t}`,children:n}),O.jsx("span",{className:"text-xxs text-faint tabular-nums",children:e})]}),r.length===0?O.jsx("div",{className:"text-xs text-muted py-1",children:s??"Nothing here."}):O.jsx("div",{className:"border border-line rounded-md overflow-hidden bg-surface",children:Array.from(l.entries()).map(([o,u])=>{const h=o?i.get(o):void 0;return O.jsxs("div",{children:[O.jsxs("div",{className:"px-3 py-1 border-b border-lineSoft bg-sidebar/40 flex items-center gap-1.5 text-xxs",children:[h?O.jsxs(O.Fragment,{children:[O.jsx(Fs,{color:h.color,icon:h.icon,size:10}),O.jsx("span",{className:"font-mono tabular-nums",style:{color:h.color},children:h.key}),O.jsx("span",{className:"text-muted truncate",children:h.name})]}):O.jsx("span",{className:"text-faint",children:"no project"}),O.jsx("span",{className:"text-faint ml-auto tabular-nums",children:u.length})]}),u.map(f=>O.jsx(dp,{task:f,project:h},f.id))]},o??"_none")})})]})}function kU(){return O.jsxs(w5,{children:[O.jsxs(a5,{children:[O.jsx(dr,{path:"/login",element:O.jsx(qY,{})}),O.jsxs(dr,{element:O.jsx(hF,{}),children:[O.jsx(dr,{path:"/",element:O.jsx(yU,{})}),O.jsx(dr,{path:"/today",element:O.jsx(xU,{})}),O.jsx(dr,{path:"/inbox",element:O.jsx(BY,{})}),O.jsx(dr,{path:"/dashboard",element:O.jsx(kF,{})}),O.jsx(dr,{path:"/settings",element:O.jsx(eU,{})}),O.jsx(dr,{path:"/p/:key",element:O.jsx(GY,{})}),O.jsx(dr,{path:"/p/:key/e/:id",element:O.jsx(bF,{})}),O.jsx(dr,{path:"/p/:key/agents-md",element:O.jsx(xF,{})}),O.jsx(dr,{path:"/search",element:O.jsx(KY,{})})]})]}),O.jsx(OF,{})]})}const vU=new UA({defaultOptions:{queries:{staleTime:1e4,gcTime:5*6e4,retry:1,refetchOnWindowFocus:!0}}});pR.createRoot(document.getElementById("root")).render(O.jsx(h2.StrictMode,{children:O.jsx(GA,{client:vU,children:O.jsx(O5,{children:O.jsx(kU,{})})})}));
|
|
587
|
+
-d '{ "query": "deployment", "limit": 10 }'`;return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"MCP (raw integration)",blurb:"Skip the Claude Code plugin and wire the MCP server in by hand — for Codex, custom agents, or any MCP-aware client. The botnote binary doubles as the MCP stdio server."}),O.jsx(on,{title:"Claude Code (~/.claude.json or project-local .mcp.json)",code:n}),O.jsx(on,{title:"Codex (~/.codex/config.toml)",code:e}),O.jsx(on,{title:"REST · curl",code:t}),O.jsxs("div",{className:"border border-line rounded-md bg-surface px-4 py-3 text-xs text-muted leading-relaxed",children:["Raw MCP configuration requires the ",O.jsx("code",{className:"text-ink",children:"botnote"})," binary in",O.jsx("code",{className:"text-ink",children:" PATH"})," ","(",O.jsx("code",{className:"text-ink",children:"npm i -g botnote"}),"). The Claude Code and Codex plugins do not require a global CLI install; they run the matching npm package version automatically. The MCP server has no DB connection of its own; it speaks HTTP to whichever"," ",O.jsx("code",{className:"text-ink",children:"BOTNOTE_URL"})," you set."]})]})}function oU(){const{data:n,isLoading:e}=Lq(),t=n!=null&&n.version?`v${n.version}`:e?"loading...":"unknown";return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"About",blurb:"Build + runtime info for this daemon."}),O.jsxs("div",{className:"border border-line rounded-md bg-surface px-4 py-3 text-xs text-muted space-y-2",children:[O.jsxs("div",{children:[O.jsxs("span",{className:"text-ink",children:["botnote ",t]})," — Postgres 16 + pgvector + Fastify 5 + MCP SDK"]}),O.jsxs("div",{children:["REST: ",O.jsx("code",{className:"text-ink",children:Vf})," · docs:"," ",O.jsx("a",{className:"text-accent hover:underline",href:"/docs",target:"_blank",rel:"noreferrer",children:"/docs"})]}),O.jsxs("div",{className:"pt-1 border-t border-lineSoft",children:["Auth is enforced when ",O.jsx("code",{className:"text-ink",children:"BOTNOTE_REQUIRE_AUTH=1"})," on the daemon. Direct connections from loopback or private networks are trusted; requests via Cloudflare Tunnel (or any proxy that sets ",O.jsx("code",{children:"cf-connecting-ip"})," /"," ",O.jsx("code",{children:"x-forwarded-for"}),") require a bearer token or a browser session cookie."]})]})]})}function on({title:n,code:e}){const[t,r]=N.useState(!1);function i(){navigator.clipboard.writeText(e).then(()=>{r(!0),setTimeout(()=>r(!1),1400)})}return O.jsxs("div",{className:"border border-line rounded-md bg-surface overflow-hidden",children:[O.jsxs("div",{className:"px-3 py-1.5 border-b border-lineSoft flex items-center justify-between bg-sidebar/40",children:[O.jsx("span",{className:"text-xxs uppercase tracking-wider text-muted font-medium",children:n}),O.jsxs("button",{onClick:i,className:"text-xxs text-muted hover:text-ink flex items-center gap-1",children:[t?O.jsx(Nc,{size:11}):O.jsx(Wy,{size:11}),t?"Copied":"Copy"]})]}),O.jsx("pre",{className:"px-3 py-2 text-xs font-mono leading-relaxed overflow-x-auto whitespace-pre bg-sidebar/20 text-ink2",children:e})]})}function aU(){const{data:n,isLoading:e}=qq(),t=Fq(),r=Yq(),[i,s]=N.useState(""),[l,o]=N.useState(null),[u,h]=N.useState(null),[f,p]=N.useState(null),[m,y]=N.useState(null);function k(S){navigator.clipboard.writeText(S.plaintext).then(()=>{y(S.id),setTimeout(()=>y(C=>C===S.id?null:C),1400)})}async function b(S){if(S.preventDefault(),!i.trim())return;const C=await t.mutateAsync(i.trim());o(C),s("")}async function w(S,C){if(!u&&confirm(`Revoke token "${C}"? Any client using it stops working.`)){h(S),p(null);try{await r.mutateAsync(S),(l==null?void 0:l.id)===S&&o(null)}catch(Q){const A=Q instanceof Error?Q.message:String(Q);p(`Could not revoke "${C}": ${A}`)}finally{h(Q=>Q===S?null:Q)}}}return O.jsxs(O.Fragment,{children:[O.jsx(Xl,{title:"API tokens",blurb:"Bearer tokens for the CLI, MCP server, and direct REST calls. New tokens keep their full value available for copying here; older tokens created before this change only have a prefix and must be regenerated if the full value was lost."}),l&&O.jsxs("div",{className:"border border-warn rounded-md bg-warn/10 p-3 space-y-2",children:[O.jsxs("div",{className:"flex items-center gap-2 text-xs font-medium text-warn",children:[O.jsx(o6,{size:13}),"Copy this token now, or later from the token list."]}),O.jsxs("div",{className:"flex items-center gap-2",children:[O.jsx("code",{className:"flex-1 text-xs font-mono bg-surface border border-line rounded px-2 py-1 overflow-x-auto whitespace-nowrap",children:l.plaintext}),O.jsxs("button",{className:"btn",onClick:()=>navigator.clipboard.writeText(l.plaintext),children:[O.jsx(Wy,{size:11})," Copy"]}),O.jsx("button",{className:"btn",onClick:()=>o(null),children:"Done"})]})]}),f&&O.jsx("div",{className:"border border-danger/30 rounded-md bg-danger/10 px-3 py-2 text-xs text-danger",children:f}),O.jsxs("form",{onSubmit:b,className:"flex gap-2",children:[O.jsx("input",{className:"input flex-1",placeholder:"Token name (e.g. claude-code-laptop)",value:i,onChange:S=>s(S.target.value)}),O.jsxs("button",{type:"submit",className:"btn btn-primary",disabled:!i.trim()||t.isPending,children:[O.jsx(rp,{size:11})," ",t.isPending?"Generating…":"Generate"]})]}),O.jsxs("div",{className:"border border-line rounded-md bg-surface divide-y divide-lineSoft overflow-hidden",children:[e&&O.jsx("div",{className:"p-3 text-xs text-muted",children:"Loading…"}),!e&&(!n||n.length===0)&&O.jsx("div",{className:"p-4 text-xs text-faint text-center",children:"No tokens yet."}),n==null?void 0:n.map(S=>{const C=m===S.id;return O.jsxs("div",{className:"flex items-center gap-3 px-3 py-2",children:[O.jsxs("div",{className:"flex-1 min-w-0",children:[O.jsx("div",{className:"text-sm text-ink truncate",children:S.name}),O.jsxs("div",{className:"text-xxs text-muted flex items-center gap-3 mt-0.5",children:[O.jsxs("code",{className:"font-mono text-faint",children:[S.prefix,"…"]}),O.jsxs("span",{children:["created ",s0(new Date(S.createdAt),{addSuffix:!0})]}),O.jsx("span",{children:S.lastUsedAt?`used ${s0(new Date(S.lastUsedAt),{addSuffix:!0})}`:"never used"})]})]}),S.plaintext?O.jsxs("button",{type:"button",onClick:()=>k({id:S.id,plaintext:S.plaintext}),className:`btn gap-1.5 ${C?"!border-emerald-500/30 !text-emerald-600":""}`,title:"Copy full token",children:[C?O.jsx(Nc,{size:11}):O.jsx(Wy,{size:11}),C?"Copied":"Copy token"]}):O.jsx("span",{className:"text-xxs text-faint border border-line rounded px-2 py-1",title:"Full token is unavailable for tokens created before recoverable storage was enabled.",children:"Unavailable"}),O.jsx("button",{type:"button",className:"text-faint hover:text-danger p-1 -m-1",disabled:u!==null,onClick:()=>w(S.id,S.name),title:u===S.id?"Revoking":"Revoke",children:u===S.id?O.jsx("span",{className:"text-xxs text-muted",children:"Revoking…"}):O.jsx(KT,{size:12})})]},S.id)})]})]})}function uU({anchor:n,projectIds:e}){const t=Xx("day",n),{data:r}=Sa({from:t.from.toISOString(),to:t.to.toISOString(),projectIds:e??null,includeBacklog:!1,includeDone:!0}),{data:i}=sr(),s=N.useMemo(()=>Ca(i),[i]),{open:l}=Dt(),o=(r==null?void 0:r.overdue)??[],u=((r==null?void 0:r.scheduled)??[]).slice().sort(pp),h=fp(n);return O.jsx("div",{className:"h-full overflow-y-auto scrollbar-thin",children:O.jsxs("div",{className:"max-w-4xl mx-auto py-4",children:[h&&o.length>0&&O.jsx(ZP,{title:"Overdue",count:o.length,accent:"text-danger",tasks:o,projectMap:s}),O.jsx(ZP,{title:h?"Today":un(n,"EEEE"),count:u.length,accent:"text-ink",tasks:u,projectMap:s,emptyAction:O.jsx("button",{className:"text-accent text-xs hover:underline",onClick:()=>l({kind:"quick-create"}),children:"+ add a task for this day"})})]})})}function ZP({title:n,count:e,accent:t,tasks:r,projectMap:i,emptyAction:s}){return O.jsxs("section",{className:"mb-6",children:[O.jsxs("div",{className:"px-4 py-1.5 flex items-baseline gap-2 sticky top-0 bg-bg z-10",children:[O.jsx("h2",{className:`text-xs font-semibold ${t}`,children:n}),O.jsx("span",{className:"text-xxs text-faint tabular-nums",children:e})]}),r.length===0?O.jsx("div",{className:"px-4 py-2 text-xs text-muted",children:s??"Nothing here."}):O.jsx("div",{className:"bg-surface border-y border-lineSoft",children:r.map(l=>O.jsx(dp,{task:l,project:l.projectId?i.get(l.projectId):void 0},l.id))})]})}function cU({projectIds:n,collapsed:e,onToggle:t}){const{data:r}=Sa({projectIds:n??null,includeBacklog:!0,includeDone:!1}),{data:i}=sr(),s=N.useMemo(()=>Ca(i),[i]),l=((r==null?void 0:r.backlog)??[]).filter(o=>o.status!=="rejected");return e?O.jsxs("button",{className:"shrink-0 w-8 border-l border-line bg-sidebar/50 hover:bg-sidebar flex flex-col items-center pt-2 gap-2 group",onClick:t,title:"Expand Inbox",children:[O.jsx(Td,{size:14,className:"text-muted group-hover:text-ink"}),l.length>0&&O.jsx("div",{className:"text-xxs text-muted bg-surface border border-line rounded-full w-5 h-5 flex items-center justify-center",children:l.length})]}):O.jsxs("aside",{className:"shrink-0 w-72 border-l border-line bg-surface flex flex-col",children:[O.jsxs("div",{className:"px-3 h-9 flex items-center justify-between border-b border-lineSoft",children:[O.jsxs("div",{className:"flex items-center gap-2 text-muted",children:[O.jsx(Td,{size:12}),O.jsx("h2",{className:"text-xs font-medium text-ink2",children:"Inbox"}),O.jsx("span",{className:"text-xxs text-faint tabular-nums",children:l.length})]}),O.jsx("button",{onClick:t,className:"btn-ghost btn !h-6 !w-6 !p-0",title:"Collapse",children:"→"})]}),O.jsx("div",{className:"flex-1 overflow-y-auto scrollbar-thin",children:l.length===0?O.jsxs("div",{className:"text-xs text-muted text-center py-8 px-4",children:["No tasks without due date.",O.jsx("div",{className:"text-faint mt-1",children:"Tasks without due date appear here."})]}):l.map(o=>O.jsx(dp,{task:o,project:o.projectId?s.get(o.projectId):void 0,compact:!0},o.id))})]})}function PE({task:n,project:e}){const t=Vi(),r=n.dueAt&&new Date(n.dueAt).getTime()<Date.now()&&n.status!=="done"&&n.status!=="in_progress";return O.jsxs("div",{role:"button",tabIndex:0,draggable:!0,onDragStart:i=>{i.dataTransfer.setData("text/task-id",n.id),i.dataTransfer.effectAllowed="move",i.stopPropagation()},onClick:()=>t.open(n.id),onKeyDown:i=>{i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),t.open(n.id))},className:`group w-full text-left flex items-center gap-1.5 pl-1 pr-1.5 py-1 rounded text-xs hover:bg-sidebarHover transition-colors cursor-grab active:cursor-grabbing ${r?"bg-danger/5":""}`,title:e?`${e.key} · ${vn(n)}`:vn(n),children:[O.jsx("span",{className:"w-[2px] self-stretch rounded-sm shrink-0",style:{backgroundColor:(e==null?void 0:e.color)??"#a8a8af"}}),O.jsx(cp,{task:n,size:11}),O.jsx("span",{className:`truncate flex-1 min-w-0 ${n.status==="done"?"line-through text-muted":n.status==="rejected"?"text-muted":fi(n)?"italic text-muted":"text-ink2"}`,children:vn(n)}),n.priority!=="none"&&O.jsx(aa,{priority:n.priority,size:11})]})}const hU=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];function fU({anchor:n,projectIds:e}){const t=Xx("month",n),r=SE(t.from,t.to),{data:i}=Sa({from:t.from.toISOString(),to:t.to.toISOString(),projectIds:e??null,includeBacklog:!1,includeDone:!0}),{data:s}=sr(),l=N.useMemo(()=>Ca(s),[s]),o=N.useMemo(()=>bE((i==null?void 0:i.scheduled)??[]),[i]);return O.jsxs("div",{className:"h-full flex flex-col",children:[O.jsx("div",{className:"grid grid-cols-7 border-b border-lineSoft bg-sidebar/50",children:hU.map(u=>O.jsx("div",{className:"px-2 py-1 text-xxs uppercase tracking-wider text-muted text-center",children:u},u))}),O.jsx("div",{className:"flex-1 grid grid-cols-7 grid-rows-6 bg-line/30 gap-px overflow-y-auto scrollbar-thin",children:r.map(u=>{const h=o.get(wE(u))??[],f=!IY(u,n),p=fp(u);return O.jsx(dU,{day:u,tasks:h,projectMap:l,outOfMonth:f,today:p},u.toISOString())})})]})}function dU({day:n,tasks:e,projectMap:t,outOfMonth:r,today:i}){const{open:s}=Dt(),l=zl(),[o,u]=N.useState(!1),h=e.slice().sort(pp),f=h.filter(k=>k.status==="done").length,p=h.length,m=p>0&&f===p;function y(k){k.preventDefault(),u(!1);const b=k.dataTransfer.getData("text/task-id");if(!b)return;const w=new Date(n);w.setHours(12,0,0,0),l.mutate({id:b,fields:{dueAt:w.toISOString()}})}return O.jsxs("div",{className:`group bg-surface p-1 min-h-[112px] flex flex-col transition-colors ${r?"opacity-50":""} ${o?"ring-2 ring-accent ring-inset bg-accentSoft/40":i?"ring-1 ring-accent ring-inset bg-accentSoft/30":""}`,onDragOver:k=>{k.preventDefault(),o||u(!0)},onDragLeave:()=>u(!1),onDrop:y,children:[O.jsxs("div",{className:"flex items-center justify-between mb-1 px-1",children:[O.jsxs("div",{className:"flex items-baseline gap-1.5 min-w-0",children:[O.jsx("span",{className:`text-xs tabular-nums ${i?"font-semibold text-accent":"text-muted"}`,children:un(n,"d")}),p>0&&O.jsxs("span",{className:`text-xxs tabular-nums ${m?"text-statusDone font-medium":"text-faint"}`,title:`${f} done · ${p} total`,children:[f,"/",p]})]}),O.jsx("button",{className:"text-xs text-faint hover:text-accent opacity-0 group-hover:opacity-100 transition-opacity",onClick:()=>s({kind:"quick-create"}),title:"Add task",children:"+"})]}),O.jsxs("div",{className:"flex-1 space-y-0.5 min-h-0 overflow-hidden",children:[h.slice(0,4).map(k=>O.jsx(PE,{task:k,project:k.projectId?t.get(k.projectId):void 0},k.id)),h.length>4&&O.jsxs("div",{className:"text-xxs text-muted pl-1",children:["+",h.length-4]})]})]})}function pU({view:n,setView:e,anchor:t,setAnchor:r,projectIds:i,setProjectIds:s}){var h;const{data:l}=sr(),{open:o}=Dt(),u=i?i.length===1?((h=l==null?void 0:l.find(f=>f.id===i[0]))==null?void 0:h.key)??"1 project":`${i.length} projects`:"All projects";return O.jsx("div",{className:"border-b border-line bg-surface",children:O.jsxs("div",{className:"flex items-center justify-between h-11 px-3",children:[O.jsxs("div",{className:"flex items-center gap-3",children:[O.jsx("h1",{className:"text-xs font-semibold text-ink",children:"Tasks"}),O.jsx("div",{className:"seg",children:["day","week","month"].map(f=>O.jsx("button",{onClick:()=>e(f),"data-active":n===f,className:"capitalize",children:f},f))}),O.jsxs("div",{className:"flex items-center gap-1 ml-1",children:[O.jsx("button",{onClick:()=>r(OO(n,t,-1)),className:"btn btn-ghost !h-6 !w-6 !p-0",title:"Previous",children:O.jsx(zT,{size:12})}),O.jsx("button",{onClick:()=>r(OO(n,t,0)),className:"btn !h-6 px-2 text-xxs",title:"Today",children:"Today"}),O.jsx("button",{onClick:()=>r(OO(n,t,1)),className:"btn btn-ghost !h-6 !w-6 !p-0",title:"Next",children:O.jsx(ZT,{size:12})}),O.jsx("div",{className:"ml-2 text-xs font-medium text-ink2 tabular-nums",children:ZY(n,t)})]})]}),O.jsxs("div",{className:"flex items-center gap-1.5",children:[O.jsx(mU,{projects:l??[],projectIds:i,setProjectIds:s,label:u}),O.jsxs("button",{className:"btn btn-primary",onClick:()=>o({kind:"quick-create"}),title:"New task (c)",children:[O.jsx(rp,{size:11}),O.jsx("span",{className:"text-xs",children:"Task"}),O.jsx("kbd",{className:"!bg-white/15 !border-white/25 !text-white",children:"c"})]})]})]})})}function mU({projects:n,projectIds:e,setProjectIds:t,label:r}){return O.jsxs("details",{className:"relative",children:[O.jsxs("summary",{className:"btn list-none cursor-pointer",children:[O.jsx(zB,{size:11}),O.jsx("span",{className:"text-xs",children:r})]}),O.jsxs("div",{className:"popover top-9 right-0 w-56 px-1 py-1.5",children:[O.jsxs("button",{className:`popover-item ${e?"":"bg-accentSoft text-accentText"}`,onClick:()=>t(null),children:[O.jsx("span",{children:"All projects"}),!e&&O.jsx("span",{className:"ml-auto text-faint",children:"✓"})]}),O.jsx("div",{className:"divider my-1"}),n.map(i=>{const s=(e==null?void 0:e.includes(i.id))??!1;return O.jsxs("label",{className:"popover-item gap-2 cursor-pointer",children:[O.jsx("input",{type:"checkbox",className:"cursor-pointer",checked:s,onChange:()=>{if(!e)t([i.id]);else if(s){const l=e.filter(o=>o!==i.id);t(l.length?l:null)}else t([...e,i.id])}}),O.jsx("span",{className:"font-mono text-xxs text-faint tabular-nums",children:i.key}),O.jsx("span",{className:"text-ink2 truncate",children:i.name})]},i.id)})]})]})}function gU({anchor:n,projectIds:e}){const t=Xx("week",n),r=SE(t.from,t.to),i=hp(r[r.length-1],1),s=[...r,i],l=new Date(i);l.setHours(23,59,59,999);const{data:o}=Sa({from:t.from.toISOString(),to:l.toISOString(),projectIds:e??null,includeBacklog:!1,includeDone:!0}),{data:u}=sr(),h=N.useMemo(()=>Ca(u),[u]),f=N.useMemo(()=>bE((o==null?void 0:o.scheduled)??[]),[o]),p=s.slice(0,4),m=s.slice(4);return O.jsxs("div",{className:"h-full flex flex-col bg-bg",children:[O.jsx(XP,{days:p,byDay:f,projectMap:h,anchor:n}),O.jsx(XP,{days:m,byDay:f,projectMap:h,anchor:n})]})}function XP({days:n,byDay:e,projectMap:t,anchor:r}){return O.jsx("div",{className:"flex-1 min-h-0 flex border-b border-line last:border-b-0",children:n.map(i=>{const s=e.get(wE(i))??[],l=!DY(i,r,{weekStartsOn:1});return O.jsx(OU,{day:i,tasks:s,projectMap:t,outOfWeek:l},i.toISOString())})})}function OU({day:n,tasks:e,projectMap:t,outOfWeek:r}){const i=fp(n),{open:s}=Dt(),l=zl(),o=e.slice().sort(pp),u=o.filter(m=>m.status==="done").length,h=o.length,f=h>0&&u===h;function p(m){m.preventDefault();const y=m.dataTransfer.getData("text/task-id");if(!y)return;const k=new Date(n);k.setHours(12,0,0,0),l.mutate({id:y,fields:{dueAt:k.toISOString()}})}return O.jsxs("div",{className:`flex-1 min-w-0 border-r border-lineSoft last:border-r-0 flex flex-col group/col ${i?"bg-accentSoft/30":r?"bg-sidebar/40":"bg-surface"}`,onDragOver:m=>m.preventDefault(),onDrop:p,children:[O.jsxs("div",{className:"px-3 py-1.5 flex items-baseline justify-between border-b border-lineSoft",children:[O.jsxs("div",{className:"flex items-baseline gap-2 min-w-0",children:[O.jsx("span",{className:"text-xxs uppercase tracking-wider text-muted",children:un(n,"EEE")}),O.jsx("span",{className:`text-sm tabular-nums font-semibold ${i?"text-accent":r?"text-muted":"text-ink2"}`,children:un(n,"d")}),h>0&&O.jsxs("span",{className:`text-xxs tabular-nums ${f?"text-statusDone font-medium":"text-faint"}`,title:`${u} done · ${h} total`,children:[u,"/",h]}),r&&O.jsx("span",{className:"text-xxs text-faint italic",children:"next"})]}),O.jsx("button",{className:"text-faint hover:text-accent text-xs opacity-0 group-hover/col:opacity-100",title:"Add task",onClick:()=>s({kind:"quick-create"}),children:"+"})]}),O.jsx("div",{className:"flex-1 overflow-y-auto scrollbar-thin p-1.5 space-y-1",children:o.length===0?O.jsx("div",{className:"text-xxs text-faint px-1 py-0.5",children:"—"}):o.map(m=>O.jsx(PE,{task:m,project:m.projectId?t.get(m.projectId):void 0},m.id))})]})}function yU(){const[n,e]=N.useState("week"),[t,r]=N.useState(()=>new Date),[i,s]=N.useState(null),[l,o]=N.useState(!1);return O.jsxs("div",{className:"h-full flex flex-col",children:[O.jsx(pU,{view:n,setView:e,anchor:t,setAnchor:r,projectIds:i,setProjectIds:s}),O.jsxs("div",{className:"flex-1 min-h-0 flex",children:[O.jsxs("div",{className:"flex-1 min-w-0 overflow-hidden bg-bg",children:[n==="day"&&O.jsx(uU,{anchor:t,projectIds:i}),n==="week"&&O.jsx(gU,{anchor:t,projectIds:i}),n==="month"&&O.jsx(fU,{anchor:t,projectIds:i})]}),O.jsx(cU,{projectIds:i,collapsed:l,onToggle:()=>o(u=>!u)})]})]})}function xU(){const n=new Date,{data:e}=sr(),t=N.useMemo(()=>Ca(e),[e]),r=N.useMemo(()=>{const h=new Date(n);h.setHours(0,0,0,0);const f=new Date(n);return f.setHours(23,59,59,999),{from:h.toISOString(),to:f.toISOString()}},[]),{data:i,isLoading:s}=Sa({from:r.from,to:r.to,includeBacklog:!1,includeDone:!0}),{open:l}=Dt(),o=((i==null?void 0:i.overdue)??[]).filter(h=>h.status!=="rejected"),u=((i==null?void 0:i.scheduled)??[]).slice().sort(pp);return O.jsx("div",{className:"h-full overflow-y-auto scrollbar-thin",children:O.jsxs("div",{className:"max-w-3xl mx-auto px-6 py-6 space-y-6",children:[O.jsxs("header",{className:"flex items-baseline gap-3",children:[O.jsx(HT,{size:18,className:"text-accent"}),O.jsx("h1",{className:"text-lg font-semibold",children:"Today"}),O.jsx("span",{className:"text-xs text-muted",children:un(n,"EEEE, MMM d")})]}),s&&O.jsx("div",{className:"text-sm text-muted",children:"Loading…"}),!s&&O.jsxs(O.Fragment,{children:[O.jsx(BP,{title:"Overdue",count:o.length,accent:"text-danger",tasks:o,projectMap:t}),O.jsx(BP,{title:fp(n)?"Today":un(n,"EEEE"),count:u.length,accent:"text-ink",tasks:u,projectMap:t,emptyAction:O.jsx("button",{className:"text-accent text-xs hover:underline",onClick:()=>l({kind:"quick-create"}),children:"+ add a task"})})]})]})})}function BP({title:n,count:e,accent:t,tasks:r,projectMap:i,emptyAction:s}){if(r.length===0&&!s)return null;const l=new Map;for(const o of r){const u=o.projectId??null;l.has(u)||l.set(u,[]),l.get(u).push(o)}return O.jsxs("section",{className:"space-y-1.5",children:[O.jsxs("div",{className:"flex items-baseline gap-2",children:[O.jsx("h2",{className:`text-xs font-semibold ${t}`,children:n}),O.jsx("span",{className:"text-xxs text-faint tabular-nums",children:e})]}),r.length===0?O.jsx("div",{className:"text-xs text-muted py-1",children:s??"Nothing here."}):O.jsx("div",{className:"border border-line rounded-md overflow-hidden bg-surface",children:Array.from(l.entries()).map(([o,u])=>{const h=o?i.get(o):void 0;return O.jsxs("div",{children:[O.jsxs("div",{className:"px-3 py-1 border-b border-lineSoft bg-sidebar/40 flex items-center gap-1.5 text-xxs",children:[h?O.jsxs(O.Fragment,{children:[O.jsx(Fs,{color:h.color,icon:h.icon,size:10}),O.jsx("span",{className:"font-mono tabular-nums",style:{color:h.color},children:h.key}),O.jsx("span",{className:"text-muted truncate",children:h.name})]}):O.jsx("span",{className:"text-faint",children:"no project"}),O.jsx("span",{className:"text-faint ml-auto tabular-nums",children:u.length})]}),u.map(f=>O.jsx(dp,{task:f,project:h},f.id))]},o??"_none")})})]})}function kU(){return O.jsxs(w5,{children:[O.jsxs(a5,{children:[O.jsx(dr,{path:"/login",element:O.jsx(qY,{})}),O.jsxs(dr,{element:O.jsx(hF,{}),children:[O.jsx(dr,{path:"/",element:O.jsx(yU,{})}),O.jsx(dr,{path:"/today",element:O.jsx(xU,{})}),O.jsx(dr,{path:"/inbox",element:O.jsx(BY,{})}),O.jsx(dr,{path:"/dashboard",element:O.jsx(kF,{})}),O.jsx(dr,{path:"/settings",element:O.jsx(eU,{})}),O.jsx(dr,{path:"/p/:key",element:O.jsx(GY,{})}),O.jsx(dr,{path:"/p/:key/e/:id",element:O.jsx(bF,{})}),O.jsx(dr,{path:"/p/:key/agents-md",element:O.jsx(xF,{})}),O.jsx(dr,{path:"/search",element:O.jsx(KY,{})})]})]}),O.jsx(OF,{})]})}const vU=new UA({defaultOptions:{queries:{staleTime:1e4,gcTime:5*6e4,retry:1,refetchOnWindowFocus:!0}}});pR.createRoot(document.getElementById("root")).render(O.jsx(h2.StrictMode,{children:O.jsx(GA,{client:vU,children:O.jsx(O5,{children:O.jsx(kU,{})})})}));
|
package/web/dist/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-D2D52jSx.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index-DBDF6wZm.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|