@2digits/tlo-mcp 0.1.0 → 0.1.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/dist/bin.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{T as e,_ as t,a as n,c as r,d as i,f as a,l as o,n as s,o as c,p as l,u,y as d}from"./TloLive-Cmf1D1FV.mjs";import*as f from"effect/Effect";import*as p from"effect/Layer";import*as m from"effect/Option";import*as h from"effect/Schema";import*as g from"@effect/platform/Command";import*as _ from"@effect/platform/CommandExecutor";import*as v from"@effect/platform/FileSystem";import*as y from"effect/Deferred";import{constUndefined as ee,constVoid as te,dual as ne,identity as re,pipe as b}from"effect/Function";import*as ie from"effect/Inspectable";import*as x from"effect/Sink";import*as S from"effect/Stream";import*as C from"node:child_process";import*as w from"@effect/platform/Error";import{BadArgument as T,SystemError as E}from"@effect/platform/Error";import*as D from"effect/Channel";import*as ae from"effect/Cause";import*as oe from"effect/Chunk";import*as O from"effect/Exit";import*as se from"effect/Fiber";import*as ce from"effect/MutableRef";import*as le from"effect/Runtime";import{Readable as ue}from"node:stream";import{effectify as k}from"@effect/platform/Effectify";import*as de from"node:crypto";import*as A from"node:fs";import*as fe from"node:os";import*as j from"node:path";import{Path as pe,TypeId as me}from"@effect/platform/Path";import*as he from"node:url";import*as ge from"@effect/platform/Terminal";import*as _e from"effect/Mailbox";import*as M from"effect/RcRef";import*as N from"node:readline";import*as P from"@effect/platform/Worker";import{WorkerError as F}from"@effect/platform/WorkerError";import*as ve from"effect/Scope";import{makeRunMain as ye}from"@effect/platform/Runtime";import*as I from"@effect/cli/Command";import*as L from"@effect/ai/McpServer";import*as R from"effect/Logger";import*as be from"@effect/ai/Toolkit";import*as z from"@effect/ai/Tool";const B=(e,t)=>(n,[r])=>{let i=`Unknown`;switch(n.code){case`ENOENT`:i=`NotFound`;break;case`EACCES`:i=`PermissionDenied`;break;case`EEXIST`:i=`AlreadyExists`;break;case`EISDIR`:i=`BadResource`;break;case`ENOTDIR`:i=`BadResource`;break;case`EBUSY`:i=`Busy`;break;case`ELOOP`:i=`BadResource`;break}return new E({reason:i,module:e,method:t,pathOrDescriptor:r,syscall:n.syscall,description:n.message,cause:n})},V=(e,t,n)=>S.fromChannel(xe(e,t,n)),xe=(e,t,n)=>D.suspend(()=>we(e(),t,ce.make(void 0),n)),Se=(e,t,{encoding:n,endOnDone:r=!0}={},i=f.void)=>{let a=Ce(e,n),o=r?f.async(t=>{`closed`in e&&e.closed?t(f.void):(e.once(`finish`,()=>t(f.void)),e.end())}):f.void;return{awaitRead:()=>f.void,emit:a,error:e=>f.zipRight(o,t(e)),done:e=>f.zipRight(o,i)}},Ce=(e,t)=>n=>n.length===0?f.void:f.async(r=>{let i=n[Symbol.iterator](),a=i.next();function o(){let n=a;a=i.next();let s=e.write(n.value,t);a.done?r(f.void):s?o():e.once(`drain`,o)}o()}),we=(e,t,n,r)=>{if(!e.readable)return D.void;let i=f.unsafeMakeLatch(!1);function a(){i.unsafeOpen()}function o(e){n.current=O.fail(t(e)),i.unsafeOpen()}function s(){n.current=O.void,i.unsafeOpen()}e.on(`readable`,a),e.on(`error`,o),e.on(`end`,s);let c=r?.chunkSize?Number(r.chunkSize):void 0,l=D.suspend(function t(){let r=e.read(c);if(r===null)return n.current?D.fromEffect(n.current):(i.unsafeClose(),D.flatMap(i.await,t));let a=[r];for(;;){if(r=e.read(c),r===null)return D.flatMap(D.write(oe.unsafeFromArray(a)),t);a.push(r)}});return D.ensuring(l,f.sync(()=>{e.off(`readable`,a),e.off(`error`,o),e.off(`end`,s),r?.closeOnDone!==!1&&`closed`in e&&!e.closed&&e.destroy()}))},H=(e,t,n)=>x.fromChannel(Te(e,t,n)),Te=(e,t,n)=>D.flatMap(f.zip(f.sync(()=>e()),y.make()),([e,r])=>D.embedInput(Ee(e,r,t),Se(e,e=>y.failCause(r,e),n,y.complete(r,f.void)))),Ee=(e,t,n)=>f.suspend(()=>{function r(e){y.unsafeDone(t,f.fail(n(e)))}return e.on(`error`,r),f.ensuring(y.await(t),f.sync(()=>{e.removeListener(`error`,r)}))}),De=e=>typeof e==`string`?e:`pipe`,U=e=>typeof e==`string`?e:`pipe`,W=e=>e instanceof globalThis.Error?e:new globalThis.Error(String(e)),G=(e,t,n)=>{let r=g.flatten(n).reduce((e,t)=>{let n=`${t.command} ${t.args.join(` `)}`;return e.length===0?n:`${e} | ${n}`},``);return B(`Command`,e)(t,[r])},Oe={[_.ProcessTypeId]:_.ProcessTypeId,...ie.BaseProto,toJSON(){return{_id:`@effect/platform/CommandExecutor/Process`,pid:this.pid}}},K=e=>t=>{switch(t._tag){case`StandardCommand`:{let n=f.flatMap(y.make(),e=>f.async(n=>{let r=C.spawn(t.command,t.args,{stdio:[De(t.stdin),U(t.stdout),U(t.stderr)],cwd:m.getOrElse(t.cwd,ee),shell:t.shell,env:{...process.env,...Object.fromEntries(t.env)},detached:process.platform!==`win32`});return r.on(`error`,e=>{n(f.fail(G(`spawn`,e,t)))}),r.on(`exit`,(...t)=>{y.unsafeDone(e,f.succeed(t))}),r.on(`spawn`,()=>{n(f.succeed([r,e]))}),f.sync(()=>{r.kill(`SIGTERM`)})})),r=process.platform===`win32`?(e,n)=>f.async(n=>{C.exec(`taskkill /pid ${e.pid} /T /F`,e=>{n(e?f.fail(G(`kill`,W(e),t)):f.void)})}):(e,n)=>f.try({try:()=>process.kill(-e.pid,n),catch:e=>G(`kill`,W(e),t)}),i=(e,n)=>f.suspend(()=>e.kill(n)?f.void:f.fail(G(`kill`,new globalThis.Error(`Failed to kill process`),t)));return b(m.match(t.cwd,{onNone:()=>f.void,onSome:t=>e.access(t)}),f.zipRight(f.acquireRelease(n,([e,t])=>f.flatMap(y.isDone(t),n=>n?f.flatMap(y.await(t),([t])=>t!==0&&t!==null?r(e,`SIGTERM`).pipe(f.ignore):f.void):r(e,`SIGTERM`).pipe(f.orElse(()=>i(e,`SIGTERM`)),f.zipRight(y.await(t)),f.ignore)))),f.map(([e,n])=>{let a=x.drain;e.stdin!==null&&(a=H(()=>e.stdin,e=>G(`toWritable`,W(e),t)));let o=f.flatMap(y.await(n),([e,n])=>e===null?f.fail(G(`exitCode`,new globalThis.Error(`Process interrupted due to receipt of signal: ${n}`),t)):f.succeed(_.ExitCode(e))),s=f.negate(y.isDone(n)),c=(t=`SIGTERM`)=>r(e,t).pipe(f.orElse(()=>i(e,t)),f.zipRight(f.asVoid(y.await(n)))),l=_.ProcessId(e.pid),u=V(()=>e.stderr,e=>G(`fromReadable(stderr)`,W(e),t)),d=V(()=>e.stdout,e=>G(`fromReadable(stdout)`,W(e),t));return typeof t.stdout!=`string`&&(d=S.transduce(d,t.stdout)),Object.assign(Object.create(Oe),{pid:l,exitCode:o,isRunning:s,kill:c,stdin:a,stderr:u,stdout:d})}),typeof t.stdin==`string`?re:f.tap(e=>f.forkDaemon(S.run(t.stdin,e.stdin))))}case`PipedCommand`:{let n=g.flatten(t);if(n.length===1)return b(n[0],K(e));let r=n[0],i=n.slice(1),a=i.slice(0,i.length-1),o=i[i.length-1],s=a.reduce((t,n)=>b(g.stdin(n,t),K(e),f.map(e=>e.stdout),S.unwrapScoped),b(K(e)(r),f.map(e=>e.stdout),S.unwrapScoped));return b(g.stdin(o,s),K(e))}}},ke=p.effect(_.CommandExecutor,b(v.FileSystem,f.map(e=>_.makeExecutor(K(e))))),q=e=>t=>new w.BadArgument({module:`FileSystem`,method:e,cause:t}),Ae=(()=>{let e=k(A.access,B(`FileSystem`,`access`),q(`access`));return(t,n)=>{let r=A.constants.F_OK;return n?.readable&&(r|=A.constants.R_OK),n?.writable&&(r|=A.constants.W_OK),e(t,r)}})(),je=(()=>{let e=k(A.cp,B(`FileSystem`,`copy`),q(`copy`));return(t,n,r)=>e(t,n,{force:r?.overwrite??!1,preserveTimestamps:r?.preserveTimestamps??!1,recursive:!0})})(),Me=(()=>{let e=k(A.copyFile,B(`FileSystem`,`copyFile`),q(`copyFile`));return(t,n)=>e(t,n)})(),Ne=(()=>{let e=k(A.chmod,B(`FileSystem`,`chmod`),q(`chmod`));return(t,n)=>e(t,n)})(),Pe=(()=>{let e=k(A.chown,B(`FileSystem`,`chown`),q(`chown`));return(t,n,r)=>e(t,n,r)})(),Fe=(()=>{let e=k(A.link,B(`FileSystem`,`link`),q(`link`));return(t,n)=>e(t,n)})(),Ie=(()=>{let e=k(A.mkdir,B(`FileSystem`,`makeDirectory`),q(`makeDirectory`));return(t,n)=>e(t,{recursive:n?.recursive??!1,mode:n?.mode})})(),J=e=>{let t=k(A.mkdtemp,B(`FileSystem`,e),q(e));return e=>f.suspend(()=>{let n=e?.prefix??``,r=typeof e?.directory==`string`?j.join(e.directory,`.`):fe.tmpdir();return t(n?j.join(r,n):r+`/`)})},Le=J(`makeTempDirectory`),Y=e=>{let t=k(A.rm,B(`FileSystem`,e),q(e));return(e,n)=>t(e,{recursive:n?.recursive??!1,force:n?.force??!1})},Re=Y(`remove`),ze=(()=>{let e=J(`makeTempDirectoryScoped`),t=Y(`makeTempDirectoryScoped`);return n=>f.acquireRelease(e(n),e=>f.orDie(t(e,{recursive:!0})))})(),Be=e=>{let t=k(A.open,B(`FileSystem`,e),q(e)),n=k(A.close,B(`FileSystem`,e),q(e));return(e,r)=>b(f.acquireRelease(t(e,r?.flag??`r`,r?.mode),e=>f.orDie(n(e))),f.map(e=>He(v.FileDescriptor(e),r?.flag?.startsWith(`a`)??!1)))},Ve=Be(`open`),He=(()=>{let e=e=>k(A.read,B(`FileSystem`,e),q(e)),t=e(`read`),n=e(`readAlloc`),r=k(A.fstat,B(`FileSystem`,`stat`),q(`stat`)),i=k(A.ftruncate,B(`FileSystem`,`truncate`),q(`truncate`)),a=k(A.fsync,B(`FileSystem`,`sync`),q(`sync`)),o=e=>k(A.write,B(`FileSystem`,e),q(e)),s=o(`write`),c=o(`writeAll`);class l{fd;append;[v.FileTypeId];semaphore=f.unsafeMakeSemaphore(1);position=0n;constructor(e,t){this.fd=e,this.append=t,this[v.FileTypeId]=v.FileTypeId}get stat(){return f.map(r(this.fd),Ze)}get sync(){return a(this.fd)}seek(e,t){let n=v.Size(e);return this.semaphore.withPermits(1)(f.sync(()=>(t===`start`?this.position=n:t===`current`&&(this.position+=n),this.position)))}read(e){return this.semaphore.withPermits(1)(f.map(f.suspend(()=>t(this.fd,{buffer:e,position:this.position})),e=>{let t=v.Size(e);return this.position+=t,t}))}readAlloc(e){let t=Number(e);return this.semaphore.withPermits(1)(f.flatMap(f.sync(()=>Buffer.allocUnsafeSlow(t)),e=>f.map(n(this.fd,{buffer:e,position:this.position}),n=>{if(n===0)return m.none();if(this.position+=BigInt(n),n===t)return m.some(e);let r=Buffer.allocUnsafeSlow(n);return e.copy(r,0,0,n),m.some(r)})))}truncate(e){return this.semaphore.withPermits(1)(f.map(i(this.fd,e?Number(e):void 0),()=>{if(!this.append){let t=BigInt(e??0);this.position>t&&(this.position=t)}}))}write(e){return this.semaphore.withPermits(1)(f.map(f.suspend(()=>s(this.fd,e,void 0,void 0,this.append?void 0:Number(this.position))),e=>{let t=v.Size(e);return this.append||(this.position+=t),t}))}writeAllChunk(e){return f.flatMap(f.suspend(()=>c(this.fd,e,void 0,void 0,this.append?void 0:Number(this.position))),t=>t===0?f.fail(new w.SystemError({module:`FileSystem`,method:`writeAll`,reason:`WriteZero`,pathOrDescriptor:this.fd,description:`write returned 0 bytes written`})):(this.append||(this.position+=BigInt(t)),t<e.length?this.writeAllChunk(e.subarray(t)):f.void))}writeAll(e){return this.semaphore.withPermits(1)(this.writeAllChunk(e))}}return(e,t)=>new l(e,t)})(),Ue=e=>{let t=J(e),n=Be(e),r=e=>f.sync(()=>de.randomBytes(e).toString(`hex`));return e=>b(f.zip(t(e),r(6)),f.map(([t,n])=>j.join(t,n+(e?.suffix??``))),f.tap(e=>f.scoped(n(e,{flag:`w+`}))))},We=Ue(`makeTempFile`),Ge=(()=>{let e=Ue(`makeTempFileScoped`),t=Y(`makeTempFileScoped`);return n=>f.acquireRelease(e(n),e=>f.orDie(t(j.dirname(e),{recursive:!0})))})(),Ke=(e,t)=>f.tryPromise({try:()=>A.promises.readdir(e,t),catch:t=>B(`FileSystem`,`readDirectory`)(t,[e])}),qe=e=>f.async((t,n)=>{try{A.readFile(e,{signal:n},(n,r)=>{t(n?f.fail(B(`FileSystem`,`readFile`)(n,[e])):f.succeed(r))})}catch(e){t(f.fail(q(`readFile`)(e)))}}),Je=(()=>{let e=k(A.readlink,B(`FileSystem`,`readLink`),q(`readLink`));return t=>e(t)})(),Ye=(()=>{let e=k(A.realpath,B(`FileSystem`,`realPath`),q(`realPath`));return t=>e(t)})(),Xe=(()=>{let e=k(A.rename,B(`FileSystem`,`rename`),q(`rename`));return(t,n)=>e(t,n)})(),Ze=e=>({type:e.isFile()?`File`:e.isDirectory()?`Directory`:e.isSymbolicLink()?`SymbolicLink`:e.isBlockDevice()?`BlockDevice`:e.isCharacterDevice()?`CharacterDevice`:e.isFIFO()?`FIFO`:e.isSocket()?`Socket`:`Unknown`,mtime:m.fromNullable(e.mtime),atime:m.fromNullable(e.atime),birthtime:m.fromNullable(e.birthtime),dev:e.dev,rdev:m.fromNullable(e.rdev),ino:m.fromNullable(e.ino),mode:e.mode,nlink:m.fromNullable(e.nlink),uid:m.fromNullable(e.uid),gid:m.fromNullable(e.gid),size:v.Size(e.size),blksize:m.map(m.fromNullable(e.blksize),v.Size),blocks:m.fromNullable(e.blocks)}),X=(()=>{let e=k(A.stat,B(`FileSystem`,`stat`),q(`stat`));return t=>f.map(e(t),Ze)})(),Qe=(()=>{let e=k(A.symlink,B(`FileSystem`,`symlink`),q(`symlink`));return(t,n)=>e(t,n)})(),$e=(()=>{let e=k(A.truncate,B(`FileSystem`,`truncate`),q(`truncate`));return(t,n)=>e(t,n===void 0?void 0:Number(n))})(),et=(()=>{let e=k(A.utimes,B(`FileSystem`,`utime`),q(`utime`));return(t,n,r)=>e(t,n,r)})(),tt=(e,t)=>S.asyncScoped(n=>f.acquireRelease(f.sync(()=>{let r=A.watch(e,{recursive:t?.recursive},(e,t)=>{if(t)switch(e){case`rename`:n.fromEffect(f.matchEffect(X(t),{onSuccess:e=>f.succeed(v.WatchEventCreate({path:t})),onFailure:e=>e._tag===`SystemError`&&e.reason===`NotFound`?f.succeed(v.WatchEventRemove({path:t})):f.fail(e)}));return;case`change`:n.single(v.WatchEventUpdate({path:t}));return}});return r.on(`error`,t=>{n.fail(new w.SystemError({module:`FileSystem`,reason:`Unknown`,method:`watch`,pathOrDescriptor:e,cause:t}))}),r.on(`close`,()=>{n.end()}),r}),e=>f.sync(()=>e.close()))),nt=(e,t,n)=>X(t).pipe(f.map(r=>e.pipe(m.flatMap(e=>e.register(t,r,n)),m.getOrElse(()=>tt(t,n)))),S.unwrap),rt=(e,t,n)=>f.async((r,i)=>{try{A.writeFile(e,t,{signal:i,flag:n?.flag,mode:n?.mode},t=>{r(t?f.fail(B(`FileSystem`,`writeFile`)(t,[e])):f.void)})}catch(e){r(f.fail(q(`writeFile`)(e)))}}),it=f.map(f.serviceOption(v.WatchBackend),e=>v.make({access:Ae,chmod:Ne,chown:Pe,copy:je,copyFile:Me,link:Fe,makeDirectory:Ie,makeTempDirectory:Le,makeTempDirectoryScoped:ze,makeTempFile:We,makeTempFileScoped:Ge,open:Ve,readDirectory:Ke,readFile:qe,readLink:Je,realPath:Ye,remove:Re,rename:Xe,stat:X,symlink:Qe,truncate:$e,utimes:et,watch(t,n){return nt(e,t,n)},writeFile:rt})),at=p.effect(v.FileSystem,it),ot=e=>f.try({try:()=>he.fileURLToPath(e),catch:t=>new T({module:`Path`,method:`fromFileUrl`,description:`Invalid file URL: ${e}`,cause:t})}),st=e=>f.try({try:()=>he.pathToFileURL(e),catch:t=>new T({module:`Path`,method:`toFileUrl`,description:`Invalid path: ${e}`,cause:t})});({...j.posix}),{...j.win32};const ct=p.succeed(pe,pe.of({[me]:me,...j,fromFileUrl:ot,toFileUrl:st})),lt=e=>e.key.ctrl&&(e.key.name===`c`||e.key.name===`d`),ut=f.fnUntraced(function*(e=lt){let t=process.stdin,n=process.stdout,r=yield*M.make({acquire:f.acquireRelease(f.sync(()=>{let e=N.createInterface({input:t,escapeCodeTimeout:50});return N.emitKeypressEvents(t,e),t.isTTY&&t.setRawMode(!0),e}),e=>f.sync(()=>{t.isTTY&&t.setRawMode(!1),e.close()}))}),i=f.sync(()=>n.columns??0),a=f.gen(function*(){yield*M.get(r);let n=yield*_e.make(),i=(t,r)=>{let i={input:m.fromNullable(t),key:{name:r.name??``,ctrl:!!r.ctrl,meta:!!r.meta,shift:!!r.shift}};n.unsafeOffer(i),e(i)&&n.unsafeDone(O.void)};return yield*f.addFinalizer(()=>f.sync(()=>t.off(`keypress`,i))),t.on(`keypress`,i),n}),o=M.get(r).pipe(f.flatMap(e=>f.async(t=>{let n=e=>t(f.succeed(e));return e.once(`line`,n),f.sync(()=>e.off(`line`,n))})),f.scoped);return ge.Terminal.of({columns:i,readInput:a,readLine:o,display:e=>f.uninterruptible(f.async(t=>{n.write(e,e=>t(e?f.fail(new w.BadArgument({module:`Terminal`,method:`display`,description:`Failed to write prompt to stdout`,cause:e})):f.void))}))})}),dt=p.scoped(ge.Terminal,ut(lt)),ft=P.makePlatform()({setup({scope:e,worker:t}){return f.flatMap(y.make(),n=>{let r=`postMessage`in t?{postMessage(e,n){t.postMessage(e,n)},kill:()=>t.terminate(),worker:t}:{postMessage(e,n){t.send(e)},kill:()=>t.kill(`SIGKILL`),worker:t};return t.on(`exit`,()=>{y.unsafeDone(n,O.void)}),f.as(ve.addFinalizer(e,f.suspend(()=>(r.postMessage([1]),y.await(n))).pipe(f.interruptible,f.timeout(5e3),f.catchAllCause(()=>f.sync(()=>r.kill())))),r)})},listen({deferred:e,emit:t,port:n}){return n.worker.on(`message`,e=>{t(e)}),n.worker.on(`messageerror`,t=>{y.unsafeDone(e,new F({reason:`decode`,cause:t}))}),n.worker.on(`error`,t=>{y.unsafeDone(e,new F({reason:`unknown`,cause:t}))}),n.worker.on(`exit`,t=>{y.unsafeDone(e,new F({reason:`unknown`,cause:Error(`exited with code ${t}`)}))}),f.void}}),pt=p.succeed(P.PlatformWorker,ft),mt=p.provide(P.layerManager,pt),ht=b(p.mergeAll(ct,ke,dt,mt),p.provideMerge(at)),gt=ye(({fiber:e,teardown:t})=>{let n=setInterval(te,2**31-1),r=!1;e.addObserver(e=>{r||(process.removeListener(`SIGINT`,i),process.removeListener(`SIGTERM`,i)),clearInterval(n),t(e,e=>{(r||e!==0)&&process.exit(e)})});function i(){r=!0,process.removeListener(`SIGINT`,i),process.removeListener(`SIGTERM`,i),e.unsafeInterruptAsFork(e.id())}process.on(`SIGINT`,i),process.on(`SIGTERM`,i)}),_t=H(()=>process.stdout,e=>new E({module:`Stream`,method:`stdout`,reason:`Unknown`,cause:e})),vt=V(()=>process.stdin,e=>e,{closeOnDone:!1}).pipe(S.orDie);S.orDie,S.orDie;const Z=h.Literal(`DRAFT`,`OPEN`,`COMPLETED`,`CLOSED`),yt=h.Literal(`TODO`,`BOARD`,`PROJECT`),Q=h.Date.annotations({description:`ISO 8601 date string (e.g., 2025-01-20T10:00:00Z)`}),bt=z.make(`get_projects`,{description:`List all projects. Returns projectId, folderId, client, owner, dates, and budget info. Use to discover projects before drilling into tasks or logging time. Data hierarchy: FOLDER → PROJECT → TASK → ACTIVITY.`,parameters:{states:h.optional(h.Array(Z)).annotations({description:`Filter by project states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:h.optional(h.Number).annotations({description:`Maximum number of projects to return. Defaults to 100`}),page:h.optional(h.Number).annotations({description:`Page number for pagination. Defaults to 1`})},success:h.Struct({projects:h.Array(o)}),failure:e,failureMode:`return`,dependencies:[c]}),xt=z.make(`get_project_details`,{description:`Get single project with full details including billing rates and folder info. Requires projectId from get_projects.`,parameters:{projectId:h.Number.annotations({description:`Project ID from get_projects response`})},success:h.Struct({project:o}),failure:e,failureMode:`return`,dependencies:[c]}),St=z.make(`get_messages`,{description:`Get comments/messages on a project, board, or todo. Use to read discussion history or context about work items.`,parameters:{objectType:yt.annotations({description:`Type of object: PROJECT (for project comments), BOARD (board-level), TODO (kanban card)`}),objectId:h.Number.annotations({description:`ID of the project, board, or todo`}),onlyComments:h.optional(h.Boolean).annotations({description:`Only return user comments (exclude system messages). Defaults to true`}),hideInternal:h.optional(h.Boolean).annotations({description:`Hide internal/private messages. Defaults to true`}),limit:h.optional(h.Number).annotations({description:`Maximum number of messages to return. Defaults to 100`})},success:h.Struct({messages:h.Array(r)}),failure:e,failureMode:`return`,dependencies:[c]}),Ct=z.make(`set_task_state`,{description:`Change task state. Typical flow: DRAFT → OPEN → COMPLETED → CLOSED. Requires both projectId and taskId from get_tasks.`,parameters:{projectId:h.Number.annotations({description:`Project ID containing the task (from get_projects)`}),taskId:h.Number.annotations({description:`Task ID to update (from get_tasks)`}),state:Z.annotations({description:`New state: DRAFT, OPEN, COMPLETED, or CLOSED`})},success:h.Void,failure:e,failureMode:`return`,dependencies:[c]}),wt=z.make(`get_tasks`,{description:`Get tasks within a project. Tasks have budget (workload), remaining hours, and state. Use taskId when logging time to attribute work to specific deliverables.`,parameters:{projectId:h.Number.annotations({description:`Project ID from get_projects`}),states:h.optional(h.Array(Z)).annotations({description:`Filter by task states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:h.optional(h.Number).annotations({description:`Maximum number of tasks to return. Defaults to 100`}),page:h.optional(h.Number).annotations({description:`Page number for pagination. Defaults to 1`})},success:h.Struct({tasks:h.Array(u)}),failure:e,failureMode:`return`,dependencies:[c]}),Tt=z.make(`get_tasks_for_user`,{description:`Get tasks assigned to a user for a date range. Returns tasks with REMAINING budget hours. Useful for finding what work is available to log time against.`,parameters:{contactId:h.String.annotations({description:`User/contact ID to get tasks for`}),startDate:Q.annotations({description:`Start date for the query (e.g., 2025-01-20T00:00:00Z)`}),period:h.Number.annotations({description:`Number of days to include in the query`})},success:h.Struct({tasks:h.Array(i)}),failure:e,failureMode:`return`,dependencies:[c]}),Et=z.make(`get_todo_detail`,{description:`Get kanban card details. Response includes: BOARDLISTS (all columns with IDs for move_todo), LINKS (connected tasks), ACTIVITIES (time logged against this todo).`,parameters:{id:h.Number.annotations({description:`Todo/card ID to retrieve`})},success:h.Struct({todo:a}),failure:e,failureMode:`return`,dependencies:[c]}),Dt=z.make(`get_board_todos`,{description:`List todos/cards from a kanban board. Use to find todo IDs by name for use with get_todo_detail. Get boardId from get_todo_detail BOARDID field or project board URL.`,parameters:{boardId:h.Number.annotations({description:`Board ID (from get_todo_detail TODO.BOARDID field or URL)`}),query:h.optional(h.String).annotations({description:`Filter todos by name (case-insensitive partial match)`}),boardListId:h.optional(h.Number).annotations({description:`Filter by column ID (from BOARDLISTS in get_todo_detail)`}),limit:h.optional(h.Number).annotations({description:`Maximum results. Defaults to 100`})},success:h.Struct({todos:h.Array(l)}),failure:e,failureMode:`return`,dependencies:[c]}),Ot=z.make(`move_todo`,{description:`Move kanban card between columns. Get boardId and boardListId from get_todo_detail response (BOARDLISTS array contains column IDs).`,parameters:{id:h.Number.annotations({description:`Todo/card ID to move`}),boardId:h.Number.annotations({description:`Board ID (from get_todo_detail)`}),boardListId:h.Number.annotations({description:`Target column ID (from BOARDLISTS in get_todo_detail)`}),sortIndex:h.Number.annotations({description:`Position within column (0 = top)`})},success:h.Void,failure:e,failureMode:`return`,dependencies:[c]}),kt=z.make(`post_message`,{description:`Add a comment to a project, board, or todo. Use to leave notes or updates on work items.`,parameters:{objectType:yt.annotations({description:`Type of object: PROJECT, BOARD, or TODO`}),objectId:h.Number.annotations({description:`ID of the project, board, or todo to comment on`}),content:h.String.annotations({description:`Comment text to post`})},success:h.Void,failure:e,failureMode:`return`,dependencies:[c]}),At=z.make(`get_week_activities`,{description:`Get all time entries for the week containing the given date. Returns project/task names, duration, and IDs. Use to review or summarize work. Response includes folderId which can be used for create_activity.`,parameters:{date:Q.annotations({description:`Any date within target week (e.g., 2025-01-20). Week is Mon-Sun.`}),contactId:h.String.annotations({description:`User/contact ID to get activities for`}),timezone:h.optional(h.String).annotations({description:`Timezone for week boundaries. Defaults to Europe/Amsterdam`})},success:h.Struct({activities:h.Array(d)}),failure:e,failureMode:`return`,dependencies:[t]}),jt=z.make(`create_activity`,{description:`Log time against a project/task. Get folderId from get_projects or get_week_activities. Duration examples: 60=1h, 90=1.5h, 120=2h. Optionally link to a taskId for specific work attribution or todoId for kanban card.`,parameters:{folderId:h.String.annotations({description:`Folder/project ID to log time against (from get_projects or get_week_activities)`}),startDate:Q.annotations({description:`Date and time of the activity (e.g., 2025-01-20T09:00:00Z). Time is for display.`}),durationMinutes:h.Number.annotations({description:`Duration in minutes. Examples: 30, 60 (1h), 90 (1.5h), 120 (2h)`}),contactId:h.String.annotations({description:`User/contact ID who performed the work`}),taskId:h.optional(h.String).annotations({description:`Task ID to attribute time to (from get_tasks). Links time to specific deliverable.`}),todoId:h.optional(h.String).annotations({description:`Todo/kanban card ID to link this time entry to`}),description:h.optional(h.String).annotations({description:`Description of work performed`}),clientColor:h.optional(h.String).annotations({description:`Hex color code for display (e.g., #eeeeee)`})},success:h.Struct({id:h.Number.annotations({description:`ID of the created activity`})}),failure:e,failureMode:`return`,dependencies:[t]}),Mt=z.make(`update_activity`,{description:`Modify an existing time entry. Get activity ID from get_week_activities. Only specify fields you want to change.`,parameters:{id:h.Number.annotations({description:`Activity ID to update (from get_week_activities)`}),startDate:h.optional(Q).annotations({description:`New date/time for the activity`}),durationMinutes:h.optional(h.Number).annotations({description:`New duration in minutes`}),description:h.optional(h.String).annotations({description:`New description`})},success:h.Void,failure:e,failureMode:`return`,dependencies:[t]}),Nt=z.make(`delete_activity`,{description:`Remove a time entry. Get activity ID from get_week_activities. This action cannot be undone.`,parameters:{id:h.Number.annotations({description:`Activity ID to delete (from get_week_activities)`})},success:h.Void,failure:e,failureMode:`return`,dependencies:[t]}),Pt=be.make(bt,xt,St,wt,Tt,Et,Dt,Ot,kt,Ct,At,jt,Mt,Nt),Ft=[`DRAFT`,`OPEN`,`CLOSED`],It=Pt.toLayer({get_projects:f.fn(`TloToolkitHandlers.get_projects`)(function*(e){return{projects:yield*(yield*c).getProjects({...e,states:e.states??[...Ft],limit:e.limit??100,page:e.page??1})}}),get_project_details:f.fn(`TloToolkitHandlers.get_project_details`)(function*(e){return{project:yield*(yield*c).getProjectDetails(e)}}),get_messages:f.fn(`TloToolkitHandlers.get_messages`)(function*(e){return{messages:yield*(yield*c).getMessages({...e,onlyComments:e.onlyComments??!0,hideInternal:e.hideInternal??!0,limit:e.limit??100})}}),set_task_state:f.fn(`TloToolkitHandlers.set_task_state`)(function*(e){yield*(yield*c).setTaskState(e)}),get_tasks:f.fn(`TloToolkitHandlers.get_tasks`)(function*(e){return{tasks:yield*(yield*c).getTasks({...e,states:e.states??[...Ft],limit:e.limit??100,page:e.page??1})}}),get_tasks_for_user:f.fn(`TloToolkitHandlers.get_tasks_for_user`)(function*(e){return{tasks:yield*(yield*c).getTasksForUser(e)}}),get_todo_detail:f.fn(`TloToolkitHandlers.get_todo_detail`)(function*(e){return{todo:yield*(yield*c).getTodoDetail(e)}}),get_board_todos:f.fn(`TloToolkitHandlers.get_board_todos`)(function*(e){return{todos:yield*(yield*c).getBoardTodos({...e,limit:e.limit??100})}}),move_todo:f.fn(`TloToolkitHandlers.move_todo`)(function*(e){yield*(yield*c).moveTodo(e)}),post_message:f.fn(`TloToolkitHandlers.post_message`)(function*(e){yield*(yield*c).postMessage(e)}),get_week_activities:f.fn(`TloToolkitHandlers.get_week_activities`)(function*(e){let n=yield*t,r=e.timezone??`Europe/Amsterdam`;return{activities:yield*n.getWeek(e.date,e.contactId,r)}}),create_activity:f.fn(`TloToolkitHandlers.create_activity`)(function*(e){return{id:yield*(yield*t).createActivity(e)}}),update_activity:f.fn(`TloToolkitHandlers.update_activity`)(function*(e){yield*(yield*t).updateActivity(e)}),delete_activity:f.fn(`TloToolkitHandlers.delete_activity`)(function*(e){yield*(yield*t).deleteActivity(e)})});function Lt(e){return L.toolkit(Pt).pipe(p.provide(It),p.provide(L.layerStdio({...e,stdin:vt,stdout:_t})),p.provide(R.add(R.prettyLogger({stderr:!0}))))}const $=`tlo-mcp`,Rt=`0.0.0`,zt=I.make($,{},f.fn(function*(){return yield*Lt({name:$,version:Rt}).pipe(p.provide(s),p.provide(n),p.launch)}));I.run(zt,{name:$,version:Rt})(process.argv).pipe(f.provide(ht),gt);export{};
2
+ import{T as e,_ as t,a as n,c as r,d as i,f as a,l as o,n as s,o as c,p as l,u,y as d}from"./TloLive-zcgFUY9N.mjs";import*as f from"effect/Effect";import*as p from"effect/Layer";import*as m from"effect/Schema";import*as h from"@effect/platform-node/NodeContext";import*as g from"@effect/platform-node/NodeRuntime";import*as _ from"@effect/cli/Command";import*as v from"@effect/ai/McpServer";import*as y from"@effect/platform-node/NodeSink";import*as b from"@effect/platform-node/NodeStream";import*as x from"effect/Logger";import*as S from"@effect/ai/Toolkit";import*as C from"@effect/ai/Tool";const w=m.Literal(`DRAFT`,`OPEN`,`COMPLETED`,`CLOSED`),T=m.Literal(`TODO`,`BOARD`,`PROJECT`),E=m.Date.annotations({description:`ISO 8601 date string (e.g., 2025-01-20T10:00:00Z)`}),D=C.make(`get_projects`,{description:`List all projects. Returns projectId, folderId, client, owner, dates, and budget info. Use to discover projects before drilling into tasks or logging time. Data hierarchy: FOLDER → PROJECT → TASK → ACTIVITY.`,parameters:{states:m.optional(m.Array(w)).annotations({description:`Filter by project states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:m.optional(m.Number).annotations({description:`Maximum number of projects to return. Defaults to 100`}),page:m.optional(m.Number).annotations({description:`Page number for pagination. Defaults to 1`})},success:m.Struct({projects:m.Array(o)}),failure:e,failureMode:`return`,dependencies:[c]}),O=C.make(`get_project_details`,{description:`Get single project with full details including billing rates and folder info. Requires projectId from get_projects.`,parameters:{projectId:m.Number.annotations({description:`Project ID from get_projects response`})},success:m.Struct({project:o}),failure:e,failureMode:`return`,dependencies:[c]}),k=C.make(`get_messages`,{description:`Get comments/messages on a project, board, or todo. Use to read discussion history or context about work items.`,parameters:{objectType:T.annotations({description:`Type of object: PROJECT (for project comments), BOARD (board-level), TODO (kanban card)`}),objectId:m.Number.annotations({description:`ID of the project, board, or todo`}),onlyComments:m.optional(m.Boolean).annotations({description:`Only return user comments (exclude system messages). Defaults to true`}),hideInternal:m.optional(m.Boolean).annotations({description:`Hide internal/private messages. Defaults to true`}),limit:m.optional(m.Number).annotations({description:`Maximum number of messages to return. Defaults to 100`})},success:m.Struct({messages:m.Array(r)}),failure:e,failureMode:`return`,dependencies:[c]}),A=C.make(`set_task_state`,{description:`Change task state. Typical flow: DRAFT → OPEN → COMPLETED → CLOSED. Requires both projectId and taskId from get_tasks.`,parameters:{projectId:m.Number.annotations({description:`Project ID containing the task (from get_projects)`}),taskId:m.Number.annotations({description:`Task ID to update (from get_tasks)`}),state:w.annotations({description:`New state: DRAFT, OPEN, COMPLETED, or CLOSED`})},success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),j=C.make(`get_tasks`,{description:`Get tasks within a project. Tasks have budget (workload), remaining hours, and state. Use taskId when logging time to attribute work to specific deliverables.`,parameters:{projectId:m.Number.annotations({description:`Project ID from get_projects`}),states:m.optional(m.Array(w)).annotations({description:`Filter by task states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:m.optional(m.Number).annotations({description:`Maximum number of tasks to return. Defaults to 100`}),page:m.optional(m.Number).annotations({description:`Page number for pagination. Defaults to 1`})},success:m.Struct({tasks:m.Array(u)}),failure:e,failureMode:`return`,dependencies:[c]}),M=C.make(`get_tasks_for_user`,{description:`Get tasks assigned to a user for a date range. Returns tasks with REMAINING budget hours. Useful for finding what work is available to log time against.`,parameters:{contactId:m.String.annotations({description:`User/contact ID to get tasks for`}),startDate:E.annotations({description:`Start date for the query (e.g., 2025-01-20T00:00:00Z)`}),period:m.Number.annotations({description:`Number of days to include in the query`})},success:m.Struct({tasks:m.Array(i)}),failure:e,failureMode:`return`,dependencies:[c]}),N=C.make(`get_todo_detail`,{description:`Get kanban card details. Response includes: BOARDLISTS (all columns with IDs for move_todo), LINKS (connected tasks), ACTIVITIES (time logged against this todo).`,parameters:{id:m.Number.annotations({description:`Todo/card ID to retrieve`})},success:m.Struct({todo:a}),failure:e,failureMode:`return`,dependencies:[c]}),P=C.make(`get_board_todos`,{description:`List todos/cards from a kanban board. Use to find todo IDs by name for use with get_todo_detail. Get boardId from get_todo_detail BOARDID field or project board URL.`,parameters:{boardId:m.Number.annotations({description:`Board ID (from get_todo_detail TODO.BOARDID field or URL)`}),query:m.optional(m.String).annotations({description:`Filter todos by name (case-insensitive partial match)`}),boardListId:m.optional(m.Number).annotations({description:`Filter by column ID (from BOARDLISTS in get_todo_detail)`}),limit:m.optional(m.Number).annotations({description:`Maximum results. Defaults to 100`})},success:m.Struct({todos:m.Array(l)}),failure:e,failureMode:`return`,dependencies:[c]}),F=C.make(`move_todo`,{description:`Move kanban card between columns. Get boardId and boardListId from get_todo_detail response (BOARDLISTS array contains column IDs).`,parameters:{id:m.Number.annotations({description:`Todo/card ID to move`}),boardId:m.Number.annotations({description:`Board ID (from get_todo_detail)`}),boardListId:m.Number.annotations({description:`Target column ID (from BOARDLISTS in get_todo_detail)`}),sortIndex:m.Number.annotations({description:`Position within column (0 = top)`})},success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),I=C.make(`post_message`,{description:`Add a comment to a project, board, or todo. Use to leave notes or updates on work items.`,parameters:{objectType:T.annotations({description:`Type of object: PROJECT, BOARD, or TODO`}),objectId:m.Number.annotations({description:`ID of the project, board, or todo to comment on`}),content:m.String.annotations({description:`Comment text to post`})},success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),L=C.make(`get_week_activities`,{description:`Get all time entries for the week containing the given date. Returns project/task names, duration, and IDs. Use to review or summarize work. Response includes folderId which can be used for create_activity.`,parameters:{date:E.annotations({description:`Any date within target week (e.g., 2025-01-20). Week is Mon-Sun.`}),contactId:m.String.annotations({description:`User/contact ID to get activities for`}),timezone:m.optional(m.String).annotations({description:`Timezone for week boundaries. Defaults to Europe/Amsterdam`})},success:m.Struct({activities:m.Array(d)}),failure:e,failureMode:`return`,dependencies:[t]}),R=C.make(`create_activity`,{description:`Log time against a project/task. Get folderId from get_projects or get_week_activities. Duration examples: 60=1h, 90=1.5h, 120=2h. Optionally link to a taskId for specific work attribution or todoId for kanban card.`,parameters:{folderId:m.String.annotations({description:`Folder/project ID to log time against (from get_projects or get_week_activities)`}),startDate:E.annotations({description:`Date and time of the activity (e.g., 2025-01-20T09:00:00Z). Time is for display.`}),durationMinutes:m.Number.annotations({description:`Duration in minutes. Examples: 30, 60 (1h), 90 (1.5h), 120 (2h)`}),contactId:m.String.annotations({description:`User/contact ID who performed the work`}),taskId:m.optional(m.String).annotations({description:`Task ID to attribute time to (from get_tasks). Links time to specific deliverable.`}),todoId:m.optional(m.String).annotations({description:`Todo/kanban card ID to link this time entry to`}),description:m.optional(m.String).annotations({description:`Description of work performed`}),clientColor:m.optional(m.String).annotations({description:`Hex color code for display (e.g., #eeeeee)`})},success:m.Struct({id:m.Number.annotations({description:`ID of the created activity`})}),failure:e,failureMode:`return`,dependencies:[t]}),z=C.make(`update_activity`,{description:`Modify an existing time entry. Get activity ID from get_week_activities. Only specify fields you want to change.`,parameters:{id:m.Number.annotations({description:`Activity ID to update (from get_week_activities)`}),startDate:m.optional(E).annotations({description:`New date/time for the activity`}),durationMinutes:m.optional(m.Number).annotations({description:`New duration in minutes`}),description:m.optional(m.String).annotations({description:`New description`})},success:m.Void,failure:e,failureMode:`return`,dependencies:[t]}),B=C.make(`delete_activity`,{description:`Remove a time entry. Get activity ID from get_week_activities. This action cannot be undone.`,parameters:{id:m.Number.annotations({description:`Activity ID to delete (from get_week_activities)`})},success:m.Void,failure:e,failureMode:`return`,dependencies:[t]}),V=S.make(D,O,k,j,M,N,P,F,I,A,L,R,z,B),H=[`DRAFT`,`OPEN`,`CLOSED`],U=V.toLayer({get_projects:f.fn(`TloToolkitHandlers.get_projects`)(function*(e){return{projects:yield*(yield*c).getProjects({...e,states:e.states??[...H],limit:e.limit??100,page:e.page??1})}}),get_project_details:f.fn(`TloToolkitHandlers.get_project_details`)(function*(e){return{project:yield*(yield*c).getProjectDetails(e)}}),get_messages:f.fn(`TloToolkitHandlers.get_messages`)(function*(e){return{messages:yield*(yield*c).getMessages({...e,onlyComments:e.onlyComments??!0,hideInternal:e.hideInternal??!0,limit:e.limit??100})}}),set_task_state:f.fn(`TloToolkitHandlers.set_task_state`)(function*(e){yield*(yield*c).setTaskState(e)}),get_tasks:f.fn(`TloToolkitHandlers.get_tasks`)(function*(e){return{tasks:yield*(yield*c).getTasks({...e,states:e.states??[...H],limit:e.limit??100,page:e.page??1})}}),get_tasks_for_user:f.fn(`TloToolkitHandlers.get_tasks_for_user`)(function*(e){return{tasks:yield*(yield*c).getTasksForUser(e)}}),get_todo_detail:f.fn(`TloToolkitHandlers.get_todo_detail`)(function*(e){return{todo:yield*(yield*c).getTodoDetail(e)}}),get_board_todos:f.fn(`TloToolkitHandlers.get_board_todos`)(function*(e){return{todos:yield*(yield*c).getBoardTodos({...e,limit:e.limit??100})}}),move_todo:f.fn(`TloToolkitHandlers.move_todo`)(function*(e){yield*(yield*c).moveTodo(e)}),post_message:f.fn(`TloToolkitHandlers.post_message`)(function*(e){yield*(yield*c).postMessage(e)}),get_week_activities:f.fn(`TloToolkitHandlers.get_week_activities`)(function*(e){let n=yield*t,r=e.timezone??`Europe/Amsterdam`;return{activities:yield*n.getWeek(e.date,e.contactId,r)}}),create_activity:f.fn(`TloToolkitHandlers.create_activity`)(function*(e){return{id:yield*(yield*t).createActivity(e)}}),update_activity:f.fn(`TloToolkitHandlers.update_activity`)(function*(e){yield*(yield*t).updateActivity(e)}),delete_activity:f.fn(`TloToolkitHandlers.delete_activity`)(function*(e){yield*(yield*t).deleteActivity(e)})});function W(e){return v.toolkit(V).pipe(p.provide(U),p.provide(v.layerStdio({...e,stdin:b.stdin,stdout:y.stdout})),p.provide(x.add(x.prettyLogger({stderr:!0}))))}const G=`tlo-mcp`,K=`0.0.0`,q=_.make(G,{},f.fn(function*(){return yield*W({name:G,version:K}).pipe(p.provide(s),p.provide(n),p.launch)}));_.run(q,{name:G,version:K})(process.argv).pipe(f.provide(h.layer),g.runMain);export{};
package/dist/index.d.mts CHANGED
@@ -185,69 +185,69 @@ declare const Activity_base: Schema.Class<Activity, {
185
185
  projectColor: Schema.optional<typeof Schema.String>;
186
186
  clientColor: Schema.optional<typeof Schema.String>;
187
187
  }>, never, {
188
- readonly description: string | null;
188
+ readonly billingMode?: string | null | undefined;
189
189
  } & {
190
- readonly id: number;
190
+ readonly clientColor?: string | undefined;
191
191
  } & {
192
- readonly startDate: string;
192
+ readonly clientName?: string | null | undefined;
193
193
  } & {
194
- readonly durationMinutes: number;
194
+ readonly endDate?: string | undefined;
195
195
  } & {
196
- readonly projectId?: string | undefined;
196
+ readonly entityName?: string | null | undefined;
197
197
  } & {
198
198
  readonly folderId?: string | undefined;
199
199
  } & {
200
- readonly taskId?: string | null | undefined;
200
+ readonly folderName?: string | null | undefined;
201
201
  } & {
202
- readonly todoId?: string | null | undefined;
202
+ readonly nonBillable?: number | null | undefined;
203
203
  } & {
204
- readonly ticketId?: string | null | undefined;
204
+ readonly projectColor?: string | undefined;
205
205
  } & {
206
- readonly userId?: string | undefined;
206
+ readonly projectEndDate?: string | null | undefined;
207
207
  } & {
208
- readonly endDate?: string | undefined;
208
+ readonly projectId?: string | undefined;
209
209
  } & {
210
210
  readonly projectName?: string | null | undefined;
211
211
  } & {
212
- readonly taskName?: string | null | undefined;
212
+ readonly projectOwnerName?: string | null | undefined;
213
213
  } & {
214
- readonly clientName?: string | null | undefined;
214
+ readonly projectStartDate?: string | null | undefined;
215
215
  } & {
216
- readonly folderName?: string | null | undefined;
216
+ readonly projectState?: string | null | undefined;
217
217
  } & {
218
- readonly entityName?: string | null | undefined;
218
+ readonly rate?: number | null | undefined;
219
219
  } & {
220
- readonly projectOwnerName?: string | null | undefined;
220
+ readonly readOnly?: boolean | null | undefined;
221
221
  } & {
222
- readonly projectState?: string | null | undefined;
222
+ readonly taskEndDate?: string | null | undefined;
223
223
  } & {
224
- readonly taskState?: string | null | undefined;
224
+ readonly taskId?: string | null | undefined;
225
225
  } & {
226
- readonly timesheetState?: string | null | undefined;
226
+ readonly taskName?: string | null | undefined;
227
227
  } & {
228
- readonly billingMode?: string | null | undefined;
228
+ readonly taskStartDate?: string | null | undefined;
229
229
  } & {
230
- readonly nonBillable?: number | null | undefined;
230
+ readonly taskState?: string | null | undefined;
231
231
  } & {
232
- readonly rate?: number | null | undefined;
232
+ readonly taskWorkload?: number | null | undefined;
233
233
  } & {
234
- readonly value?: number | null | undefined;
234
+ readonly ticketId?: string | null | undefined;
235
235
  } & {
236
- readonly projectStartDate?: string | null | undefined;
236
+ readonly timesheetState?: string | null | undefined;
237
237
  } & {
238
- readonly projectEndDate?: string | null | undefined;
238
+ readonly todoId?: string | null | undefined;
239
239
  } & {
240
- readonly taskStartDate?: string | null | undefined;
240
+ readonly userId?: string | undefined;
241
241
  } & {
242
- readonly taskEndDate?: string | null | undefined;
242
+ readonly value?: number | null | undefined;
243
243
  } & {
244
- readonly readOnly?: boolean | null | undefined;
244
+ readonly description: string | null;
245
245
  } & {
246
- readonly taskWorkload?: number | null | undefined;
246
+ readonly durationMinutes: number;
247
247
  } & {
248
- readonly projectColor?: string | undefined;
248
+ readonly id: number;
249
249
  } & {
250
- readonly clientColor?: string | undefined;
250
+ readonly startDate: string;
251
251
  }, {}, {}>;
252
252
  declare class Activity extends Activity_base {}
253
253
  declare function activityFromRaw(raw: ActivityRaw): typeof Activity.Type;
@@ -390,39 +390,39 @@ declare const Project_base: Schema.Class<Project, {
390
390
  calcDone: Schema.optional<typeof Schema.Number>;
391
391
  calcPlanned: Schema.optional<typeof Schema.Number>;
392
392
  }>, never, {
393
- readonly id: number;
393
+ readonly billingBudget?: number | undefined;
394
394
  } & {
395
- readonly startDate?: string | undefined;
395
+ readonly billingMode?: string | undefined;
396
396
  } & {
397
- readonly folderId?: number | undefined;
397
+ readonly billingRemaining?: number | undefined;
398
398
  } & {
399
- readonly endDate?: string | undefined;
399
+ readonly calcDone?: number | undefined;
400
400
  } & {
401
- readonly clientName?: string | undefined;
401
+ readonly calcPlanned?: number | undefined;
402
402
  } & {
403
- readonly folderName?: string | undefined;
403
+ readonly calcTotal?: number | undefined;
404
404
  } & {
405
- readonly billingMode?: string | undefined;
405
+ readonly clientId?: number | undefined;
406
406
  } & {
407
- readonly name: string;
407
+ readonly clientName?: string | undefined;
408
408
  } & {
409
- readonly state?: string | undefined;
409
+ readonly endDate?: string | undefined;
410
410
  } & {
411
- readonly ownerName?: string | undefined;
411
+ readonly extId?: string | undefined;
412
412
  } & {
413
- readonly billingBudget?: number | undefined;
413
+ readonly folderId?: number | undefined;
414
414
  } & {
415
- readonly billingRemaining?: number | undefined;
415
+ readonly folderName?: string | undefined;
416
416
  } & {
417
- readonly clientId?: number | undefined;
417
+ readonly ownerName?: string | undefined;
418
418
  } & {
419
- readonly extId?: string | undefined;
419
+ readonly startDate?: string | undefined;
420
420
  } & {
421
- readonly calcTotal?: number | undefined;
421
+ readonly state?: string | undefined;
422
422
  } & {
423
- readonly calcDone?: number | undefined;
423
+ readonly id: number;
424
424
  } & {
425
- readonly calcPlanned?: number | undefined;
425
+ readonly name: string;
426
426
  }, {}, {}>;
427
427
  declare class Project extends Project_base {}
428
428
  declare function projectFromRaw(raw: ProjectRaw): Project;
@@ -477,35 +477,35 @@ declare const Message_base: Schema.Class<Message, {
477
477
  outQueueId: Schema.optional<typeof Schema.String>;
478
478
  internal: Schema.optional<typeof Schema.Boolean>;
479
479
  }>, never, {
480
- readonly id: number;
481
- } & {
482
- readonly ownerName?: string | undefined;
483
- } & {
484
- readonly ownerId?: number | undefined;
485
- } & {
486
480
  readonly avatar?: string | undefined;
481
+ } & {
482
+ readonly content?: string | undefined;
487
483
  } & {
488
484
  readonly createdAt?: string | undefined;
489
485
  } & {
490
- readonly content?: string | undefined;
486
+ readonly internal?: boolean | undefined;
491
487
  } & {
492
- readonly subcontent?: string | undefined;
488
+ readonly likeCount?: number | undefined;
493
489
  } & {
494
- readonly objectType?: string | undefined;
490
+ readonly messageType?: string | undefined;
495
491
  } & {
496
492
  readonly objectId?: number | undefined;
497
493
  } & {
498
494
  readonly objectName?: string | undefined;
499
495
  } & {
500
- readonly messageType?: string | undefined;
496
+ readonly objectType?: string | undefined;
501
497
  } & {
502
- readonly likeCount?: number | undefined;
498
+ readonly outQueueId?: string | undefined;
499
+ } & {
500
+ readonly ownerId?: number | undefined;
501
+ } & {
502
+ readonly ownerName?: string | undefined;
503
503
  } & {
504
504
  readonly replyCount?: number | undefined;
505
505
  } & {
506
- readonly outQueueId?: string | undefined;
506
+ readonly subcontent?: string | undefined;
507
507
  } & {
508
- readonly internal?: boolean | undefined;
508
+ readonly id: number;
509
509
  }, {}, {}>;
510
510
  declare class Message extends Message_base {}
511
511
  declare function messageFromRaw(raw: MessageRaw): typeof Message.Type;
@@ -540,21 +540,21 @@ declare const Task_base: Schema.Class<Task, {
540
540
  endDate: Schema.optional<typeof Schema.String>;
541
541
  budget: Schema.optional<typeof Schema.Number>;
542
542
  }>, never, {
543
- readonly id: number;
544
- } & {
545
- readonly startDate?: string | undefined;
546
- } & {
547
- readonly projectId?: number | undefined;
543
+ readonly budget?: number | undefined;
548
544
  } & {
549
545
  readonly endDate?: string | undefined;
550
546
  } & {
551
547
  readonly name?: string | undefined;
552
- } & {
553
- readonly state?: string | undefined;
554
548
  } & {
555
549
  readonly ownerName?: string | undefined;
556
550
  } & {
557
- readonly budget?: number | undefined;
551
+ readonly projectId?: number | undefined;
552
+ } & {
553
+ readonly startDate?: string | undefined;
554
+ } & {
555
+ readonly state?: string | undefined;
556
+ } & {
557
+ readonly id: number;
558
558
  }, {}, {}>;
559
559
  declare class Task extends Task_base {}
560
560
  interface SetTaskStateParams {
@@ -616,29 +616,29 @@ declare const TaskForUser_base: Schema.Class<TaskForUser, {
616
616
  endDate: Schema.optional<typeof Schema.String>;
617
617
  state: Schema.optional<typeof Schema.String>;
618
618
  }>, never, {
619
- readonly id: number;
620
- } & {
621
- readonly startDate?: string | undefined;
619
+ readonly avail?: number | undefined;
622
620
  } & {
623
- readonly projectId?: number | undefined;
621
+ readonly clientId?: number | undefined;
624
622
  } & {
625
623
  readonly endDate?: string | undefined;
626
- } & {
627
- readonly projectStartDate?: string | undefined;
628
624
  } & {
629
625
  readonly projectEndDate?: string | undefined;
630
626
  } & {
631
- readonly state?: string | undefined;
627
+ readonly projectId?: number | undefined;
632
628
  } & {
633
- readonly clientId?: number | undefined;
629
+ readonly projectStartDate?: string | undefined;
634
630
  } & {
635
- readonly workload?: number | undefined;
631
+ readonly remaining?: number | undefined;
632
+ } & {
633
+ readonly startDate?: string | undefined;
634
+ } & {
635
+ readonly state?: string | undefined;
636
636
  } & {
637
637
  readonly total?: number | undefined;
638
638
  } & {
639
- readonly remaining?: number | undefined;
639
+ readonly workload?: number | undefined;
640
640
  } & {
641
- readonly avail?: number | undefined;
641
+ readonly id: number;
642
642
  }, {}, {}>;
643
643
  declare class TaskForUser extends TaskForUser_base {}
644
644
  declare const TodoDetail: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
@@ -676,23 +676,23 @@ declare const TodoSummary_base: Schema.Class<TodoSummary, {
676
676
  dueDate: Schema.optional<Schema.NullOr<typeof Schema.String>>;
677
677
  description: Schema.optional<Schema.NullOr<typeof Schema.String>>;
678
678
  }>, never, {
679
- readonly description?: string | null | undefined;
679
+ readonly boardId?: number | undefined;
680
680
  } & {
681
- readonly id: number;
681
+ readonly boardListId?: number | undefined;
682
682
  } & {
683
- readonly name?: string | undefined;
683
+ readonly description?: string | null | undefined;
684
684
  } & {
685
- readonly state?: string | null | undefined;
685
+ readonly dueDate?: string | null | undefined;
686
686
  } & {
687
687
  readonly extId?: string | undefined;
688
688
  } & {
689
- readonly ownerId?: number | undefined;
689
+ readonly name?: string | undefined;
690
690
  } & {
691
- readonly boardListId?: number | undefined;
691
+ readonly ownerId?: number | undefined;
692
692
  } & {
693
- readonly boardId?: number | undefined;
693
+ readonly state?: string | null | undefined;
694
694
  } & {
695
- readonly dueDate?: string | null | undefined;
695
+ readonly id: number;
696
696
  }, {}, {}>;
697
697
  declare class TodoSummary extends TodoSummary_base {}
698
698
  declare function todoSummaryFromRaw(raw: TodoSummaryRaw): typeof TodoSummary.Type;
@@ -757,9 +757,9 @@ declare const TloConfigFromEnv: Effect.Effect<{
757
757
  declare const TloConfigLive: Layer.Layer<TloConfig, effect_ConfigError0.ConfigError, never>;
758
758
  //#endregion
759
759
  //#region src/layers/TloLive.d.ts
760
- declare const TloServicesLive: Layer.Layer<TimeService | BoardService, never, TeamLeaderClient>;
760
+ declare const TloServicesLive: Layer.Layer<BoardService | TimeService, never, TeamLeaderClient>;
761
761
  declare const TloClientLive: Layer.Layer<TeamLeaderClient, never, TloConfig>;
762
- declare const TloLive: Layer.Layer<TimeService | BoardService, never, TloConfig>;
762
+ declare const TloLive: Layer.Layer<BoardService | TimeService, never, TloConfig>;
763
763
  //#endregion
764
764
  //#region src/schemas/common.d.ts
765
765
  /**
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{C as e,D as t,E as n,O as r,S as i,_ as a,a as o,b as s,c,d as l,f as u,g as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,v as C,w,x as T,y as E}from"./TloLive-Cmf1D1FV.mjs";import*as D from"effect/Schema";import*as O from"effect/Brand";const k=D.String.pipe(D.pattern(/^\d{14}$/),D.brand(`TloDateString`));function A(e){let t=Number.parseInt(e.slice(0,4),10),n=Number.parseInt(e.slice(4,6),10)-1,r=Number.parseInt(e.slice(6,8),10),i=Number.parseInt(e.slice(8,10),10),a=Number.parseInt(e.slice(10,12),10),o=Number.parseInt(e.slice(12,14),10);return new Date(t,n,r,i,a,o)}function j(e){return`${e.getFullYear().toString().padStart(4,`0`)}${(e.getMonth()+1).toString().padStart(2,`0`)}${e.getDate().toString().padStart(2,`0`)}${e.getHours().toString().padStart(2,`0`)}${e.getMinutes().toString().padStart(2,`0`)}${e.getSeconds().toString().padStart(2,`0`)}`}const M=D.transform(k,D.DateFromSelf,{strict:!0,decode:A,encode:j}),N=O.nominal(),P=D.String.pipe(D.fromBrand(N));function F(e){return D.Struct({success:D.Boolean,ID:D.optional(D.Number),OBJ:e,err:D.optional(D.String)})}export{E as Activity,_ as BoardService,b as BoardServiceLive,c as Message,m as Project,S as Task,l as TaskForUser,T as TeamLeaderClient,i as TeamLeaderClientLive,a as TimeService,C as TimeServiceLive,e as TloApiError,w as TloAuthError,x as TloClientLive,r as TloConfig,p as TloConfigFromEnv,o as TloConfigLive,M as TloDate,k as TloDateString,N as TloId,P as TloIdSchema,g as TloLive,n as TloNetworkError,t as TloParseError,F as TloResponse,y as TloServicesLive,u as TodoDetail,v as TodoSummary,s as activityFromRaw,j as formatTloDate,h as messageFromRaw,f as projectFromRaw,d as todoSummaryFromRaw};
1
+ import{C as e,D as t,E as n,O as r,S as i,_ as a,a as o,b as s,c,d as l,f as u,g as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,v as C,w,x as T,y as E}from"./TloLive-zcgFUY9N.mjs";import*as D from"effect/Schema";import*as O from"effect/Brand";const k=D.String.pipe(D.pattern(/^\d{14}$/),D.brand(`TloDateString`));function A(e){let t=Number.parseInt(e.slice(0,4),10),n=Number.parseInt(e.slice(4,6),10)-1,r=Number.parseInt(e.slice(6,8),10),i=Number.parseInt(e.slice(8,10),10),a=Number.parseInt(e.slice(10,12),10),o=Number.parseInt(e.slice(12,14),10);return new Date(t,n,r,i,a,o)}function j(e){return`${e.getFullYear().toString().padStart(4,`0`)}${(e.getMonth()+1).toString().padStart(2,`0`)}${e.getDate().toString().padStart(2,`0`)}${e.getHours().toString().padStart(2,`0`)}${e.getMinutes().toString().padStart(2,`0`)}${e.getSeconds().toString().padStart(2,`0`)}`}const M=D.transform(k,D.DateFromSelf,{strict:!0,decode:A,encode:j}),N=O.nominal(),P=D.String.pipe(D.fromBrand(N));function F(e){return D.Struct({success:D.Boolean,ID:D.optional(D.Number),OBJ:e,err:D.optional(D.String)})}export{E as Activity,_ as BoardService,b as BoardServiceLive,c as Message,m as Project,S as Task,l as TaskForUser,T as TeamLeaderClient,i as TeamLeaderClientLive,a as TimeService,C as TimeServiceLive,e as TloApiError,w as TloAuthError,x as TloClientLive,r as TloConfig,p as TloConfigFromEnv,o as TloConfigLive,M as TloDate,k as TloDateString,N as TloId,P as TloIdSchema,g as TloLive,n as TloNetworkError,t as TloParseError,F as TloResponse,y as TloServicesLive,u as TodoDetail,v as TodoSummary,s as activityFromRaw,j as formatTloDate,h as messageFromRaw,f as projectFromRaw,d as todoSummaryFromRaw};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2digits/tlo-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "public": true,
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,21 +24,22 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@effect/ai": "0.33.2",
27
- "@effect/cli": "0.73.0",
27
+ "@effect/cli": "0.73.1",
28
28
  "@effect/experimental": "0.58.0",
29
- "@effect/platform": "0.94.1",
29
+ "@effect/platform": "0.94.2",
30
+ "@effect/platform-node": "0.104.1",
30
31
  "@effect/rpc": "0.73.0",
31
- "effect": "3.19.14"
32
+ "effect": "3.19.15"
32
33
  },
33
34
  "devDependencies": {
34
35
  "@arethetypeswrong/core": "0.18.2",
35
- "@effect/language-service": "0.71.1",
36
- "@effect/platform-node": "0.104.0",
36
+ "@effect/language-service": "0.72.0",
37
37
  "@effect/vitest": "0.27.0",
38
- "publint": "0.3.16",
39
- "tsdown": "0.19.0",
38
+ "@typescript/native-preview": "7.0.0-dev.20260124.1",
39
+ "publint": "0.3.17",
40
+ "tsdown": "0.20.1",
40
41
  "typescript": "5.9.3",
41
- "vitest": "4.0.17",
42
+ "vitest": "4.0.18",
42
43
  "@2digits/tsconfig": "0.8.6"
43
44
  },
44
45
  "scripts": {