@2digits/tlo-mcp 0.0.0 → 0.1.0

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.
@@ -0,0 +1 @@
1
+ import*as e from"effect/Context";import*as t from"@effect/platform/HttpBody";import*as n from"@effect/platform/UrlParams";import*as r from"effect/Effect";import*as i from"effect/Layer";import*as a from"effect/Option";import*as o from"effect/Redacted";import*as s from"effect/Schema";import*as c from"@effect/platform/HttpClient";import*as l from"@effect/platform/HttpClientRequest";import*as u from"effect/Config";import*as d from"@effect/platform/FetchHttpClient";var f=class extends e.Tag(`@2digits/tlo-mcp/services/TloConfig`)(){},p=class extends s.TaggedError()(`TloApiError`,{message:s.String,code:s.optional(s.String),endpoint:s.optional(s.String)}){},m=class extends s.TaggedError()(`TloAuthError`,{message:s.String}){},h=class extends s.TaggedError()(`TloNetworkError`,{message:s.String,cause:s.optional(s.Unknown),endpoint:s.optional(s.String)}){},g=class extends s.TaggedError()(`TloParseError`,{message:s.String,cause:s.optional(s.Unknown)}){};const ee=s.Union(p,m,h,g);var _=class extends e.Tag(`@2digits/tlo-mcp/services/TloHttpClient`)(){};function v(e){return[...e.entries()].map(([e,t])=>`${e}=${t}`).join(`; `)}const te=i.effect(_,r.gen(function*(){let e=yield*f,t=(yield*c.HttpClient).pipe(c.mapRequest(l.prependUrl(e.baseUrl)),c.mapRequest(t=>t.pipe(l.setHeader(`Cookie`,v(e.cookies)))),c.filterStatusOk);return _.of({client:t})}));var y=class extends e.Tag(`@2digits/tlo-mcp/services/TeamLeaderClient`)(){};function b(e){return t=>new h({message:t._tag===`ResponseError`?`HTTP ${t.response.status}`:`Request failed: ${t.reason}`,cause:t,endpoint:e})}function ne(e){return new g({message:`Failed to parse response`,cause:e})}function x(e){return typeof e==`object`&&!!e&&`err`in e&&typeof e.err==`number`&&e.err!==0}const re=/\{MSG:'([^']*)',\s*err:(\d+)\}/;function S(e){let t=re.exec(e);return t?a.some({MSG:t[1]??`Unknown error`,err:Number(t[2])}):a.none()}const C=i.effect(y,r.gen(function*(){let e=yield*f,{client:i}=yield*_;return y.of({post:r.fn(`TeamLeaderClient.post`)(function*(c,l,u){let d={...l,t:o.value(e.sessionToken)},f=n.fromInput(d);return yield*i.post(c,{body:t.urlParams(f)}).pipe(r.flatMap(e=>e.text),r.flatMap(e=>{let t=S(e);if(a.isSome(t)&&t.value.err!==0)return r.fail(new p({message:t.value.MSG,endpoint:c}));let n;try{n=JSON.parse(e)}catch{return r.fail(new g({message:`Invalid JSON response`,cause:e}))}return x(n)?r.fail(new p({message:n.MSG,endpoint:c})):s.decodeUnknown(u)(n).pipe(r.mapError(ne))}),r.scoped,r.mapError(e=>e instanceof p||e instanceof g?e:b(c)(e)))})})})),w=s.Struct({ID:s.Number,FOLDERID:s.optional(s.Union(s.String,s.Number)),PROJECT_ID:s.optional(s.Union(s.String,s.Number)),TASKID:s.optional(s.NullOr(s.Union(s.String,s.Number))),TODOID:s.optional(s.NullOr(s.Union(s.String,s.Number))),TICKETID:s.optional(s.NullOr(s.Union(s.String,s.Number))),CONTACTID:s.optional(s.Union(s.String,s.Number)),DESCRIPTION:s.NullOr(s.String),DT:s.String,START_DT:s.optional(s.String),END_DT:s.optional(s.String),DURATION:s.Number,TYPE:s.optional(s.Number),PROJECT_NAME:s.optional(s.NullOr(s.String)),TASK_NAME:s.optional(s.NullOr(s.String)),CLIENT_NAME:s.optional(s.NullOr(s.String)),FOLDER_NAME:s.optional(s.NullOr(s.String)),ENTITY_NAME:s.optional(s.NullOr(s.String)),PROJECTOWNER_NAME:s.optional(s.NullOr(s.String)),CLIENT_COLOR:s.optional(s.NullOr(s.String)),PROJECT_COLOR:s.optional(s.NullOr(s.String)),PROJECT_STATE:s.optional(s.NullOr(s.String)),TASK_STATE:s.optional(s.NullOr(s.String)),TIMESHEET_STATE:s.optional(s.NullOr(s.String)),BILLING_MODE:s.optional(s.NullOr(s.String)),NON_BILLABLE:s.optional(s.NullOr(s.Number)),RATE:s.optional(s.NullOr(s.Number)),VALUE:s.optional(s.NullOr(s.Number)),PROJECT_START_DT:s.optional(s.NullOr(s.String)),PROJECT_END_DT:s.optional(s.NullOr(s.String)),TASK_START_DT:s.optional(s.NullOr(s.String)),TASK_END_DT:s.optional(s.NullOr(s.String)),READONLY:s.optional(s.NullOr(s.Number)),TASK_WORKLOAD:s.optional(s.NullOr(s.Number))});var T=class extends s.Class(`Activity`)({id:s.Number,projectId:s.optional(s.String),folderId:s.optional(s.String),taskId:s.optional(s.NullOr(s.String)),todoId:s.optional(s.NullOr(s.String)),ticketId:s.optional(s.NullOr(s.String)),userId:s.optional(s.String),description:s.NullOr(s.String),startDate:s.String,endDate:s.optional(s.String),durationMinutes:s.Number,projectName:s.optional(s.NullOr(s.String)),taskName:s.optional(s.NullOr(s.String)),clientName:s.optional(s.NullOr(s.String)),folderName:s.optional(s.NullOr(s.String)),entityName:s.optional(s.NullOr(s.String)),projectOwnerName:s.optional(s.NullOr(s.String)),projectState:s.optional(s.NullOr(s.String)),taskState:s.optional(s.NullOr(s.String)),timesheetState:s.optional(s.NullOr(s.String)),billingMode:s.optional(s.NullOr(s.String)),nonBillable:s.optional(s.NullOr(s.Number)),rate:s.optional(s.NullOr(s.Number)),value:s.optional(s.NullOr(s.Number)),projectStartDate:s.optional(s.NullOr(s.String)),projectEndDate:s.optional(s.NullOr(s.String)),taskStartDate:s.optional(s.NullOr(s.String)),taskEndDate:s.optional(s.NullOr(s.String)),readOnly:s.optional(s.NullOr(s.Boolean)),taskWorkload:s.optional(s.NullOr(s.Number)),projectColor:s.optional(s.String),clientColor:s.optional(s.String)}){};function E(e){return new T({id:e.ID,projectId:e.PROJECT_ID===void 0?e.FOLDERID===void 0?void 0:String(e.FOLDERID):String(e.PROJECT_ID),folderId:e.FOLDERID===void 0?void 0:String(e.FOLDERID),taskId:e.TASKID!==void 0&&e.TASKID!==null?String(e.TASKID):null,todoId:e.TODOID!==void 0&&e.TODOID!==null?String(e.TODOID):null,ticketId:e.TICKETID!==void 0&&e.TICKETID!==null?String(e.TICKETID):null,userId:e.CONTACTID===void 0?void 0:String(e.CONTACTID),description:e.DESCRIPTION,startDate:e.DT,endDate:e.END_DT,durationMinutes:e.DURATION,projectName:e.PROJECT_NAME,taskName:e.TASK_NAME,clientName:e.CLIENT_NAME,folderName:e.FOLDER_NAME,entityName:e.ENTITY_NAME,projectOwnerName:e.PROJECTOWNER_NAME,projectState:e.PROJECT_STATE,taskState:e.TASK_STATE,timesheetState:e.TIMESHEET_STATE,billingMode:e.BILLING_MODE,nonBillable:e.NON_BILLABLE,rate:e.RATE,value:e.VALUE,projectStartDate:e.PROJECT_START_DT,projectEndDate:e.PROJECT_END_DT,taskStartDate:e.TASK_START_DT,taskEndDate:e.TASK_END_DT,readOnly:e.READONLY===void 0||e.READONLY===null?void 0:e.READONLY!==0,taskWorkload:e.TASK_WORKLOAD,projectColor:e.PROJECT_COLOR??void 0,clientColor:e.CLIENT_COLOR??void 0})}const D=s.Struct({ACTIVITIES:s.Array(w)}),O=s.Struct({ID:s.Number,DURATION:s.optional(s.Number),DT:s.optional(s.String),TYPE:s.optional(s.Number),DESCRIPTION:s.optional(s.NullOr(s.String)),CLIENT_COLOR:s.optional(s.String),FOLDERID:s.optional(s.Union(s.String,s.Number))});function k(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}T${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}`}var A=class extends e.Tag(`@2digits/tlo-mcp/services/TimeService`)(){};const j=i.effect(A,r.gen(function*(){let e=yield*y;return A.of({getWeek:r.fn(`TimeService.getWeek`)(function*(t,n,i=`Europe/Amsterdam`){return yield*e.post(`/ajax/pln/GetWeek`,{DT:k(t),CONTACTID:n,tmz:i},D).pipe(r.map(e=>e.ACTIVITIES.map(e=>E(e))))}),createActivity:r.fn(`TimeService.createActivity`)(function*(t){return yield*e.post(`/ajax/pln/SetActivity`,{ID:0,ACTION:`CREATE`,DT:k(t.startDate),DURATION:t.durationMinutes,FOLDERID:t.folderId,TASKID:t.taskId,TODOID:t.todoId,CONTACTID:t.contactId,CLIENT_COLOR:t.clientColor,DESCRIPTION:t.description},O).pipe(r.map(e=>e.ID))}),updateActivity:r.fn(`TimeService.updateActivity`)(function*(t){return yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`MOVE`,DT:t.startDate?k(t.startDate):void 0,DURATION:t.durationMinutes,DESCRIPTION:t.description},O).pipe(r.asVoid)}),deleteActivity:r.fn(`TimeService.deleteActivity`)(function*(t){return yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`DELETE`},O).pipe(r.asVoid)})})})),M=s.Struct({ID:s.Number,PROJECT_NAME:s.optional(s.String),NAME:s.optional(s.String),STATE:s.optional(s.String),OWNER_NAME:s.optional(s.String),START_DT:s.optional(s.String),END_DT:s.optional(s.String),BILLING_BUDGET:s.optional(s.Number),BILLING_MODE:s.optional(s.String),BILLING_REMAINING:s.optional(s.Number),CLIENT_NAME:s.optional(s.String),CLIENT_ID:s.optional(s.Number),FOLDERID:s.optional(s.Number),FOLDER_NAME:s.optional(s.String),EXTID:s.optional(s.String),CALC_TOTAL:s.optional(s.Number),CALC_DONE:s.optional(s.Number),CALC_PLANNED:s.optional(s.Number)}),ie=s.Struct({Records:s.Array(M),RecordCount:s.optional(s.Number)}),ae=s.Union(M,s.Struct({Record:M}));var N=class extends s.Class(`Project`)({id:s.Number,name:s.String,state:s.optional(s.String),ownerName:s.optional(s.String),startDate:s.optional(s.String),endDate:s.optional(s.String),billingBudget:s.optional(s.Number),billingMode:s.optional(s.String),billingRemaining:s.optional(s.Number),clientName:s.optional(s.String),clientId:s.optional(s.Number),folderId:s.optional(s.Number),folderName:s.optional(s.String),extId:s.optional(s.String),calcTotal:s.optional(s.Number),calcDone:s.optional(s.Number),calcPlanned:s.optional(s.Number)}){};function P(e){return N.make({id:e.ID,name:e.PROJECT_NAME??e.NAME??``,state:e.STATE,ownerName:e.OWNER_NAME,startDate:e.START_DT,endDate:e.END_DT,billingBudget:e.BILLING_BUDGET,billingMode:e.BILLING_MODE,billingRemaining:e.BILLING_REMAINING,clientName:e.CLIENT_NAME,clientId:e.CLIENT_ID,folderId:e.FOLDERID,folderName:e.FOLDER_NAME,extId:e.EXTID,calcTotal:e.CALC_TOTAL,calcDone:e.CALC_DONE,calcPlanned:e.CALC_PLANNED})}const oe=s.Struct({ID:s.Number,OWNERID:s.optional(s.Number),OWNER_NAME:s.optional(s.String),AVATAR:s.optional(s.String),CREATED_DT:s.optional(s.String),CONTENT:s.optional(s.String),SUBCONTENT:s.optional(s.String),OBJECTTYPE:s.optional(s.String),OBJECTID:s.optional(s.Number),OBJECTNAME:s.optional(s.String),MSGTYPE:s.optional(s.String),LIKECNT:s.optional(s.Number),REPLYCNT:s.optional(s.Number),OUTQUEUEID:s.optional(s.String),INTERNAL:s.optional(s.Number)}),F=s.Array(oe);var I=class extends s.Class(`Message`)({id:s.Number,ownerId:s.optional(s.Number),ownerName:s.optional(s.String),avatar:s.optional(s.String),createdAt:s.optional(s.String),content:s.optional(s.String),subcontent:s.optional(s.String),objectType:s.optional(s.String),objectId:s.optional(s.Number),objectName:s.optional(s.String),messageType:s.optional(s.String),likeCount:s.optional(s.Number),replyCount:s.optional(s.Number),outQueueId:s.optional(s.String),internal:s.optional(s.Boolean)}){};function L(e){return new I({id:e.ID,ownerId:e.OWNERID,ownerName:e.OWNER_NAME,avatar:e.AVATAR,createdAt:e.CREATED_DT,content:e.CONTENT,subcontent:e.SUBCONTENT,objectType:e.OBJECTTYPE,objectId:e.OBJECTID,objectName:e.OBJECTNAME,messageType:e.MSGTYPE,likeCount:e.LIKECNT,replyCount:e.REPLYCNT,outQueueId:e.OUTQUEUEID,internal:e.INTERNAL===void 0?void 0:e.INTERNAL!==0})}const R=s.Struct({ID:s.Number,PROJECTID:s.optional(s.Number),NAME:s.optional(s.String),STATE:s.optional(s.String),OWNER_NAME:s.optional(s.String),START_DT:s.optional(s.String),END_DT:s.optional(s.String),BUDGET:s.optional(s.Number)}),z=s.Struct({Records:s.Array(R),RecordCount:s.optional(s.Number)});var B=class extends s.Class(`Task`)({id:s.Number,projectId:s.optional(s.Number),name:s.optional(s.String),state:s.optional(s.String),ownerName:s.optional(s.String),startDate:s.optional(s.String),endDate:s.optional(s.String),budget:s.optional(s.Number)}){};function V(e){return new B({id:e.ID,projectId:e.PROJECTID,name:e.NAME,state:e.STATE,ownerName:e.OWNER_NAME,startDate:e.START_DT,endDate:e.END_DT,budget:e.BUDGET})}const H=s.Struct({ID:s.Number,WORKLOAD:s.optional(s.Number),TOTAL:s.optional(s.Number),REMAINING:s.optional(s.Number),AVAIL:s.optional(s.Number),CLIENTID:s.optional(s.Number),PROJECTID:s.optional(s.Number),PROJECT_START_DT:s.optional(s.String),PROJECT_END_DT:s.optional(s.String),START_DT:s.optional(s.String),END_DT:s.optional(s.String),STATE:s.optional(s.String)}),U=s.Struct({Records:s.Array(H)});var W=class extends s.Class(`TaskForUser`)({id:s.Number,workload:s.optional(s.Number),total:s.optional(s.Number),remaining:s.optional(s.Number),avail:s.optional(s.Number),clientId:s.optional(s.Number),projectId:s.optional(s.Number),projectStartDate:s.optional(s.String),projectEndDate:s.optional(s.String),startDate:s.optional(s.String),endDate:s.optional(s.String),state:s.optional(s.String)}){};function G(e){return new W({id:e.ID,workload:e.WORKLOAD,total:e.TOTAL,remaining:e.REMAINING,avail:e.AVAIL,clientId:e.CLIENTID,projectId:e.PROJECTID,projectStartDate:e.PROJECT_START_DT,projectEndDate:e.PROJECT_END_DT,startDate:e.START_DT,endDate:e.END_DT,state:e.STATE})}const K=s.Record({key:s.String,value:s.Unknown}),se=s.Struct({ID:s.Number,NAME:s.optional(s.String),BOARDLISTID:s.optional(s.Number),BOARDID:s.optional(s.Number),OWNERID:s.optional(s.Number),EXTID:s.optional(s.String),STATE:s.optional(s.NullOr(s.String)),DUE_DT:s.optional(s.NullOr(s.String)),DESCRIPTION:s.optional(s.NullOr(s.String))}),ce=s.Struct({Records:s.Array(se),RecordCount:s.optional(s.Number)});var q=class extends s.Class(`TodoSummary`)({id:s.Number,name:s.optional(s.String),boardListId:s.optional(s.Number),boardId:s.optional(s.Number),ownerId:s.optional(s.Number),extId:s.optional(s.String),state:s.optional(s.NullOr(s.String)),dueDate:s.optional(s.NullOr(s.String)),description:s.optional(s.NullOr(s.String))}){};function J(e){return new q({id:e.ID,name:e.NAME,boardListId:e.BOARDLISTID,boardId:e.BOARDID,ownerId:e.OWNERID,extId:e.EXTID,state:e.STATE,dueDate:e.DUE_DT,description:e.DESCRIPTION})}var Y=class extends e.Tag(`@2digits/tlo-mcp/services/BoardService`)(){};function le(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}function ue(e){return e.Records}const X=i.effect(Y,r.gen(function*(){let e=yield*y;return Y.of({getProjects:r.fn(`BoardService.getProjects`)(function*(t={}){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`];return yield*e.post(`/ajax/pln/GetProjects`,{STATE:n.join(`|`),COLUMNS:`ID|PROJECT_NAME|NAME|STATE|OWNER_NAME|START_DT|END_DT|BILLING_BUDGET|BILLING_MODE|BILLING_REMAINING|CLIENT_NAME|CLIENT_ID|FOLDERID|FOLDER_NAME|EXTID|CALC_TOTAL|CALC_DONE|CALC_PLANNED`,limit:t.limit??100,page:t.page??1},ie).pipe(r.map(e=>e.Records.map(e=>P(e))))}),getProjectDetails:r.fn(`BoardService.getProjectDetails`)(function*(t){return yield*e.post(`/ajax/pln/GetProjectDetails`,{ID:t.projectId},ae).pipe(r.map(e=>`Record`in e?e.Record:e),r.map(e=>P(e)))}),getMessages:r.fn(`BoardService.getMessages`)(function*(t){return yield*e.post(`/ajax/board/ProcessMessage`,{OBJECTTYPE:t.objectType,OBJECTID:t.objectId,ONLYCOMMENTS:t.onlyComments===!1?0:1,HIDEINTERNAL:t.hideInternal===!1?0:1,PAGETYPE:`SEQID`,MINID:0,limit:t.limit??100},F).pipe(r.map(e=>e.map(e=>L(e))))}),getTasks:r.fn(`BoardService.getTasks`)(function*(t){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`];return yield*e.post(`/ajax/pln/GetTasks`,{PROJECTID:t.projectId,STATE:n.join(`|`),COLUMNS:`ID|PROJECTID|NAME|STATE|OWNER_NAME|START_DT|END_DT|BUDGET`,limit:t.limit??100,page:t.page??1},z).pipe(r.map(e=>e.Records.map(e=>V(e))))}),getTasksForUser:r.fn(`BoardService.getTasksForUser`)(function*(t){return yield*e.post(`/ajax/pln/GetTasksForUser`,{CONTACTID:t.contactId,START_DT:le(t.startDate),PERIOD:t.period},U).pipe(r.map(e=>ue(e)),r.map(e=>e.map(e=>G(e))))}),getTodoDetail:r.fn(`BoardService.getTodoDetail`)(function*(t){return yield*e.post(`/ajax/board/GetTodoDetail`,{ID:t.id},K)}),getBoardTodos:r.fn(`BoardService.getBoardTodos`)(function*(t){return yield*e.post(`/ajax/board/GetTodos`,{BOARDID:t.boardId,BOARDLISTID:t.boardListId,limit:t.limit??100},ce).pipe(r.map(e=>e.Records.map(e=>J(e))),r.map(e=>{if(t.query){let n=t.query.toLowerCase();return e.filter(e=>e.name?.toLowerCase().includes(n))}return e}))}),moveTodo:r.fn(`BoardService.moveTodo`)(function*(t){return yield*e.post(`/ajax/board/MoveTodo`,{ID:t.id,BOARDID:t.boardId,BOARDLISTID:t.boardListId,SORTINDEX:t.sortIndex},s.Unknown).pipe(r.asVoid)}),postMessage:r.fn(`BoardService.postMessage`)(function*(t){return yield*e.post(`/ajax/board/ProcessMessage`,{ACTION:`ADD`,OBJECTTYPE:t.objectType,OBJECTID:t.objectId,CONTENT:t.content},s.Unknown).pipe(r.asVoid)}),setTaskState:r.fn(`BoardService.setTaskState`)(function*(t){return yield*e.post(`/ajax/pln/SetTaskState`,{PROJECTID:t.projectId,ID:t.taskId,STATE:t.state},s.Unknown).pipe(r.asVoid)})})}));function de(e){if(a.isNone(e))return new Map;let t=e.value.split(`;`).map(e=>e.trim().split(`=`)).filter(e=>e.length===2);return new Map(t)}const Z=r.gen(function*(){let e=yield*u.redacted(`TLO_SESSION_TOKEN`);return{baseUrl:yield*u.string(`TLO_BASE_URL`).pipe(u.withDefault(`https://socialbrothers.orbit.teamleader.eu`)),sessionToken:e,cookies:de(yield*u.option(u.string(`TLO_COOKIES`)))}}),fe=i.effect(f,Z),Q=i.mergeAll(j,X),$=C.pipe(i.provide(te.pipe(i.provide(d.layer)))),pe=Q.pipe(i.provide($));export{p as C,g as D,h as E,f as O,C as S,ee as T,A as _,fe as a,E as b,I as c,W as d,K as f,J as g,P as h,Z as i,N as l,L as m,pe as n,Y as o,q as p,Q as r,X as s,$ as t,B as u,j as v,m as w,y as x,T as y};
package/dist/bin.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{C as e,_ as t,a as n,c as r,d as i,f as a,h as o,l as s,n as c,o as l,u}from"./TloLive-19PJ2qwv.mjs";import*as d from"effect/Effect";import*as f from"effect/Layer";import*as p from"effect/Option";import*as m from"effect/Schema";import*as h from"@effect/platform/Command";import*as g from"@effect/platform/CommandExecutor";import*as _ from"@effect/platform/FileSystem";import*as v from"effect/Deferred";import{constUndefined as ee,constVoid as te,dual as ne,identity as re,pipe as y}from"effect/Function";import*as ie from"effect/Inspectable";import*as b from"effect/Sink";import*as x from"effect/Stream";import*as S from"node:child_process";import*as C from"@effect/platform/Error";import{BadArgument as ae,SystemError as oe}from"@effect/platform/Error";import*as w from"effect/Channel";import*as se from"effect/Cause";import*as ce from"effect/Chunk";import*as T from"effect/Exit";import*as le from"effect/Fiber";import*as ue from"effect/MutableRef";import*as de from"effect/Runtime";import{Readable as fe}from"node:stream";import{effectify as E}from"@effect/platform/Effectify";import*as pe from"node:crypto";import*as D from"node:fs";import*as me from"node:os";import*as O from"node:path";import{Path as k,TypeId as A}from"@effect/platform/Path";import*as j from"node:url";import*as M from"@effect/platform/Terminal";import*as he from"effect/Mailbox";import*as N from"effect/RcRef";import*as P from"node:readline";import*as F from"@effect/platform/Worker";import{WorkerError as I}from"@effect/platform/WorkerError";import*as ge from"effect/Scope";import{makeRunMain as _e}from"@effect/platform/Runtime";import*as L from"@effect/cli/Command";import*as R from"@effect/ai/McpServer";import*as z from"effect/Logger";import*as ve from"@effect/ai/Toolkit";import*as B from"@effect/ai/Tool";const V=(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 oe({reason:i,module:e,method:t,pathOrDescriptor:r,syscall:n.syscall,description:n.message,cause:n})},H=(e,t,n)=>x.fromChannel(ye(e,t,n)),ye=(e,t,n)=>w.suspend(()=>Se(e(),t,ue.make(void 0),n)),be=(e,t,{encoding:n,endOnDone:r=!0}={},i=d.void)=>{let a=xe(e,n),o=r?d.async(t=>{`closed`in e&&e.closed?t(d.void):(e.once(`finish`,()=>t(d.void)),e.end())}):d.void;return{awaitRead:()=>d.void,emit:a,error:e=>d.zipRight(o,t(e)),done:e=>d.zipRight(o,i)}},xe=(e,t)=>n=>n.length===0?d.void:d.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(d.void):s?o():e.once(`drain`,o)}o()}),Se=(e,t,n,r)=>{if(!e.readable)return w.void;let i=d.unsafeMakeLatch(!1);function a(){i.unsafeOpen()}function o(e){n.current=T.fail(t(e)),i.unsafeOpen()}function s(){n.current=T.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=w.suspend(function t(){let r=e.read(c);if(r===null)return n.current?w.fromEffect(n.current):(i.unsafeClose(),w.flatMap(i.await,t));let a=[r];for(;;){if(r=e.read(c),r===null)return w.flatMap(w.write(ce.unsafeFromArray(a)),t);a.push(r)}});return w.ensuring(l,d.sync(()=>{e.off(`readable`,a),e.off(`error`,o),e.off(`end`,s),r?.closeOnDone!==!1&&`closed`in e&&!e.closed&&e.destroy()}))},Ce=(e,t,n)=>b.fromChannel(we(e,t,n)),we=(e,t,n)=>w.flatMap(d.zip(d.sync(()=>e()),v.make()),([e,r])=>w.embedInput(Te(e,r,t),be(e,e=>v.failCause(r,e),n,v.complete(r,d.void)))),Te=(e,t,n)=>d.suspend(()=>{function r(e){v.unsafeDone(t,d.fail(n(e)))}return e.on(`error`,r),d.ensuring(v.await(t),d.sync(()=>{e.removeListener(`error`,r)}))}),Ee=e=>typeof e==`string`?e:`pipe`,De=e=>typeof e==`string`?e:`pipe`,U=e=>e instanceof globalThis.Error?e:new globalThis.Error(String(e)),W=(e,t,n)=>{let r=h.flatten(n).reduce((e,t)=>{let n=`${t.command} ${t.args.join(` `)}`;return e.length===0?n:`${e} | ${n}`},``);return V(`Command`,e)(t,[r])},Oe={[g.ProcessTypeId]:g.ProcessTypeId,...ie.BaseProto,toJSON(){return{_id:`@effect/platform/CommandExecutor/Process`,pid:this.pid}}},G=e=>t=>{switch(t._tag){case`StandardCommand`:{let n=d.flatMap(v.make(),e=>d.async(n=>{let r=S.spawn(t.command,t.args,{stdio:[Ee(t.stdin),De(t.stdout),De(t.stderr)],cwd:p.getOrElse(t.cwd,ee),shell:t.shell,env:{...process.env,...Object.fromEntries(t.env)},detached:process.platform!==`win32`});return r.on(`error`,e=>{n(d.fail(W(`spawn`,e,t)))}),r.on(`exit`,(...t)=>{v.unsafeDone(e,d.succeed(t))}),r.on(`spawn`,()=>{n(d.succeed([r,e]))}),d.sync(()=>{r.kill(`SIGTERM`)})})),r=process.platform===`win32`?(e,n)=>d.async(n=>{S.exec(`taskkill /pid ${e.pid} /T /F`,e=>{n(e?d.fail(W(`kill`,U(e),t)):d.void)})}):(e,n)=>d.try({try:()=>process.kill(-e.pid,n),catch:e=>W(`kill`,U(e),t)}),i=(e,n)=>d.suspend(()=>e.kill(n)?d.void:d.fail(W(`kill`,new globalThis.Error(`Failed to kill process`),t)));return y(p.match(t.cwd,{onNone:()=>d.void,onSome:t=>e.access(t)}),d.zipRight(d.acquireRelease(n,([e,t])=>d.flatMap(v.isDone(t),n=>n?d.flatMap(v.await(t),([t])=>t!==0&&t!==null?r(e,`SIGTERM`).pipe(d.ignore):d.void):r(e,`SIGTERM`).pipe(d.orElse(()=>i(e,`SIGTERM`)),d.zipRight(v.await(t)),d.ignore)))),d.map(([e,n])=>{let a=b.drain;e.stdin!==null&&(a=Ce(()=>e.stdin,e=>W(`toWritable`,U(e),t)));let o=d.flatMap(v.await(n),([e,n])=>e===null?d.fail(W(`exitCode`,new globalThis.Error(`Process interrupted due to receipt of signal: ${n}`),t)):d.succeed(g.ExitCode(e))),s=d.negate(v.isDone(n)),c=(t=`SIGTERM`)=>r(e,t).pipe(d.orElse(()=>i(e,t)),d.zipRight(d.asVoid(v.await(n)))),l=g.ProcessId(e.pid),u=H(()=>e.stderr,e=>W(`fromReadable(stderr)`,U(e),t)),f=H(()=>e.stdout,e=>W(`fromReadable(stdout)`,U(e),t));return typeof t.stdout!=`string`&&(f=x.transduce(f,t.stdout)),Object.assign(Object.create(Oe),{pid:l,exitCode:o,isRunning:s,kill:c,stdin:a,stderr:u,stdout:f})}),typeof t.stdin==`string`?re:d.tap(e=>d.forkDaemon(x.run(t.stdin,e.stdin))))}case`PipedCommand`:{let n=h.flatten(t);if(n.length===1)return y(n[0],G(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)=>y(h.stdin(n,t),G(e),d.map(e=>e.stdout),x.unwrapScoped),y(G(e)(r),d.map(e=>e.stdout),x.unwrapScoped));return y(h.stdin(o,s),G(e))}}},ke=f.effect(g.CommandExecutor,y(_.FileSystem,d.map(e=>g.makeExecutor(G(e))))),K=e=>t=>new C.BadArgument({module:`FileSystem`,method:e,cause:t}),Ae=(()=>{let e=E(D.access,V(`FileSystem`,`access`),K(`access`));return(t,n)=>{let r=D.constants.F_OK;return n?.readable&&(r|=D.constants.R_OK),n?.writable&&(r|=D.constants.W_OK),e(t,r)}})(),je=(()=>{let e=E(D.cp,V(`FileSystem`,`copy`),K(`copy`));return(t,n,r)=>e(t,n,{force:r?.overwrite??!1,preserveTimestamps:r?.preserveTimestamps??!1,recursive:!0})})(),Me=(()=>{let e=E(D.copyFile,V(`FileSystem`,`copyFile`),K(`copyFile`));return(t,n)=>e(t,n)})(),Ne=(()=>{let e=E(D.chmod,V(`FileSystem`,`chmod`),K(`chmod`));return(t,n)=>e(t,n)})(),Pe=(()=>{let e=E(D.chown,V(`FileSystem`,`chown`),K(`chown`));return(t,n,r)=>e(t,n,r)})(),Fe=(()=>{let e=E(D.link,V(`FileSystem`,`link`),K(`link`));return(t,n)=>e(t,n)})(),Ie=(()=>{let e=E(D.mkdir,V(`FileSystem`,`makeDirectory`),K(`makeDirectory`));return(t,n)=>e(t,{recursive:n?.recursive??!1,mode:n?.mode})})(),q=e=>{let t=E(D.mkdtemp,V(`FileSystem`,e),K(e));return e=>d.suspend(()=>{let n=e?.prefix??``,r=typeof e?.directory==`string`?O.join(e.directory,`.`):me.tmpdir();return t(n?O.join(r,n):r+`/`)})},Le=q(`makeTempDirectory`),J=e=>{let t=E(D.rm,V(`FileSystem`,e),K(e));return(e,n)=>t(e,{recursive:n?.recursive??!1,force:n?.force??!1})},Re=J(`remove`),ze=(()=>{let e=q(`makeTempDirectoryScoped`),t=J(`makeTempDirectoryScoped`);return n=>d.acquireRelease(e(n),e=>d.orDie(t(e,{recursive:!0})))})(),Be=e=>{let t=E(D.open,V(`FileSystem`,e),K(e)),n=E(D.close,V(`FileSystem`,e),K(e));return(e,r)=>y(d.acquireRelease(t(e,r?.flag??`r`,r?.mode),e=>d.orDie(n(e))),d.map(e=>He(_.FileDescriptor(e),r?.flag?.startsWith(`a`)??!1)))},Ve=Be(`open`),He=(()=>{let e=e=>E(D.read,V(`FileSystem`,e),K(e)),t=e(`read`),n=e(`readAlloc`),r=E(D.fstat,V(`FileSystem`,`stat`),K(`stat`)),i=E(D.ftruncate,V(`FileSystem`,`truncate`),K(`truncate`)),a=E(D.fsync,V(`FileSystem`,`sync`),K(`sync`)),o=e=>E(D.write,V(`FileSystem`,e),K(e)),s=o(`write`),c=o(`writeAll`);class l{fd;append;[_.FileTypeId];semaphore=d.unsafeMakeSemaphore(1);position=0n;constructor(e,t){this.fd=e,this.append=t,this[_.FileTypeId]=_.FileTypeId}get stat(){return d.map(r(this.fd),Ze)}get sync(){return a(this.fd)}seek(e,t){let n=_.Size(e);return this.semaphore.withPermits(1)(d.sync(()=>(t===`start`?this.position=n:t===`current`&&(this.position+=n),this.position)))}read(e){return this.semaphore.withPermits(1)(d.map(d.suspend(()=>t(this.fd,{buffer:e,position:this.position})),e=>{let t=_.Size(e);return this.position+=t,t}))}readAlloc(e){let t=Number(e);return this.semaphore.withPermits(1)(d.flatMap(d.sync(()=>Buffer.allocUnsafeSlow(t)),e=>d.map(n(this.fd,{buffer:e,position:this.position}),n=>{if(n===0)return p.none();if(this.position+=BigInt(n),n===t)return p.some(e);let r=Buffer.allocUnsafeSlow(n);return e.copy(r,0,0,n),p.some(r)})))}truncate(e){return this.semaphore.withPermits(1)(d.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)(d.map(d.suspend(()=>s(this.fd,e,void 0,void 0,this.append?void 0:Number(this.position))),e=>{let t=_.Size(e);return this.append||(this.position+=t),t}))}writeAllChunk(e){return d.flatMap(d.suspend(()=>c(this.fd,e,void 0,void 0,this.append?void 0:Number(this.position))),t=>t===0?d.fail(new C.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)):d.void))}writeAll(e){return this.semaphore.withPermits(1)(this.writeAllChunk(e))}}return(e,t)=>new l(e,t)})(),Ue=e=>{let t=q(e),n=Be(e),r=e=>d.sync(()=>pe.randomBytes(e).toString(`hex`));return e=>y(d.zip(t(e),r(6)),d.map(([t,n])=>O.join(t,n+(e?.suffix??``))),d.tap(e=>d.scoped(n(e,{flag:`w+`}))))},We=Ue(`makeTempFile`),Ge=(()=>{let e=Ue(`makeTempFileScoped`),t=J(`makeTempFileScoped`);return n=>d.acquireRelease(e(n),e=>d.orDie(t(O.dirname(e),{recursive:!0})))})(),Ke=(e,t)=>d.tryPromise({try:()=>D.promises.readdir(e,t),catch:t=>V(`FileSystem`,`readDirectory`)(t,[e])}),qe=e=>d.async((t,n)=>{try{D.readFile(e,{signal:n},(n,r)=>{t(n?d.fail(V(`FileSystem`,`readFile`)(n,[e])):d.succeed(r))})}catch(e){t(d.fail(K(`readFile`)(e)))}}),Je=(()=>{let e=E(D.readlink,V(`FileSystem`,`readLink`),K(`readLink`));return t=>e(t)})(),Ye=(()=>{let e=E(D.realpath,V(`FileSystem`,`realPath`),K(`realPath`));return t=>e(t)})(),Xe=(()=>{let e=E(D.rename,V(`FileSystem`,`rename`),K(`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:p.fromNullable(e.mtime),atime:p.fromNullable(e.atime),birthtime:p.fromNullable(e.birthtime),dev:e.dev,rdev:p.fromNullable(e.rdev),ino:p.fromNullable(e.ino),mode:e.mode,nlink:p.fromNullable(e.nlink),uid:p.fromNullable(e.uid),gid:p.fromNullable(e.gid),size:_.Size(e.size),blksize:p.map(p.fromNullable(e.blksize),_.Size),blocks:p.fromNullable(e.blocks)}),Y=(()=>{let e=E(D.stat,V(`FileSystem`,`stat`),K(`stat`));return t=>d.map(e(t),Ze)})(),Qe=(()=>{let e=E(D.symlink,V(`FileSystem`,`symlink`),K(`symlink`));return(t,n)=>e(t,n)})(),$e=(()=>{let e=E(D.truncate,V(`FileSystem`,`truncate`),K(`truncate`));return(t,n)=>e(t,n===void 0?void 0:Number(n))})(),et=(()=>{let e=E(D.utimes,V(`FileSystem`,`utime`),K(`utime`));return(t,n,r)=>e(t,n,r)})(),tt=(e,t)=>x.asyncScoped(n=>d.acquireRelease(d.sync(()=>{let r=D.watch(e,{recursive:t?.recursive},(e,t)=>{if(t)switch(e){case`rename`:n.fromEffect(d.matchEffect(Y(t),{onSuccess:e=>d.succeed(_.WatchEventCreate({path:t})),onFailure:e=>e._tag===`SystemError`&&e.reason===`NotFound`?d.succeed(_.WatchEventRemove({path:t})):d.fail(e)}));return;case`change`:n.single(_.WatchEventUpdate({path:t}));return}});return r.on(`error`,t=>{n.fail(new C.SystemError({module:`FileSystem`,reason:`Unknown`,method:`watch`,pathOrDescriptor:e,cause:t}))}),r.on(`close`,()=>{n.end()}),r}),e=>d.sync(()=>e.close()))),nt=(e,t,n)=>Y(t).pipe(d.map(r=>e.pipe(p.flatMap(e=>e.register(t,r,n)),p.getOrElse(()=>tt(t,n)))),x.unwrap),rt=(e,t,n)=>d.async((r,i)=>{try{D.writeFile(e,t,{signal:i,flag:n?.flag,mode:n?.mode},t=>{r(t?d.fail(V(`FileSystem`,`writeFile`)(t,[e])):d.void)})}catch(e){r(d.fail(K(`writeFile`)(e)))}}),it=d.map(d.serviceOption(_.WatchBackend),e=>_.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:Y,symlink:Qe,truncate:$e,utimes:et,watch(t,n){return nt(e,t,n)},writeFile:rt})),at=f.effect(_.FileSystem,it),ot=e=>d.try({try:()=>j.fileURLToPath(e),catch:t=>new ae({module:`Path`,method:`fromFileUrl`,description:`Invalid file URL: ${e}`,cause:t})}),st=e=>d.try({try:()=>j.pathToFileURL(e),catch:t=>new ae({module:`Path`,method:`toFileUrl`,description:`Invalid path: ${e}`,cause:t})});({...O.posix}),{...O.win32};const ct=f.succeed(k,k.of({[A]:A,...O,fromFileUrl:ot,toFileUrl:st})),lt=e=>e.key.ctrl&&(e.key.name===`c`||e.key.name===`d`),ut=d.fnUntraced(function*(e=lt){let t=process.stdin,n=process.stdout,r=yield*N.make({acquire:d.acquireRelease(d.sync(()=>{let e=P.createInterface({input:t,escapeCodeTimeout:50});return P.emitKeypressEvents(t,e),t.isTTY&&t.setRawMode(!0),e}),e=>d.sync(()=>{t.isTTY&&t.setRawMode(!1),e.close()}))}),i=d.sync(()=>n.columns??0),a=d.gen(function*(){yield*N.get(r);let n=yield*he.make(),i=(t,r)=>{let i={input:p.fromNullable(t),key:{name:r.name??``,ctrl:!!r.ctrl,meta:!!r.meta,shift:!!r.shift}};n.unsafeOffer(i),e(i)&&n.unsafeDone(T.void)};return yield*d.addFinalizer(()=>d.sync(()=>t.off(`keypress`,i))),t.on(`keypress`,i),n}),o=N.get(r).pipe(d.flatMap(e=>d.async(t=>{let n=e=>t(d.succeed(e));return e.once(`line`,n),d.sync(()=>e.off(`line`,n))})),d.scoped);return M.Terminal.of({columns:i,readInput:a,readLine:o,display:e=>d.uninterruptible(d.async(t=>{n.write(e,e=>t(e?d.fail(new C.BadArgument({module:`Terminal`,method:`display`,description:`Failed to write prompt to stdout`,cause:e})):d.void))}))})}),dt=f.scoped(M.Terminal,ut(lt)),ft=F.makePlatform()({setup({scope:e,worker:t}){return d.flatMap(v.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`,()=>{v.unsafeDone(n,T.void)}),d.as(ge.addFinalizer(e,d.suspend(()=>(r.postMessage([1]),v.await(n))).pipe(d.interruptible,d.timeout(5e3),d.catchAllCause(()=>d.sync(()=>r.kill())))),r)})},listen({deferred:e,emit:t,port:n}){return n.worker.on(`message`,e=>{t(e)}),n.worker.on(`messageerror`,t=>{v.unsafeDone(e,new I({reason:`decode`,cause:t}))}),n.worker.on(`error`,t=>{v.unsafeDone(e,new I({reason:`unknown`,cause:t}))}),n.worker.on(`exit`,t=>{v.unsafeDone(e,new I({reason:`unknown`,cause:Error(`exited with code ${t}`)}))}),d.void}}),pt=f.succeed(F.PlatformWorker,ft),mt=f.provide(F.layerManager,pt),ht=y(f.mergeAll(ct,ke,dt,mt),f.provideMerge(at)),gt=_e(({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=Ce(()=>process.stdout,e=>new oe({module:`Stream`,method:`stdout`,reason:`Unknown`,cause:e})),vt=H(()=>process.stdin,e=>e,{closeOnDone:!1}).pipe(x.orDie);x.orDie,x.orDie;const X=m.Literal(`DRAFT`,`OPEN`,`COMPLETED`,`CLOSED`),yt=m.Literal(`TODO`,`BOARD`,`PROJECT`),Z=m.String.annotations({description:`ISO 8601 date string (e.g., 2025-01-20T10:00:00Z)`}),bt=B.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(X)).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(s)}),failure:e,failureMode:`return`,dependencies:[l]}),xt=B.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:s}),failure:e,failureMode:`return`,dependencies:[l]}),St=B.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: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:[l]}),Ct=B.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:X.annotations({description:`New state: DRAFT, OPEN, COMPLETED, or CLOSED`})},success:m.Void,failure:e,failureMode:`return`,dependencies:[l]}),wt=B.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(X)).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:[l]}),Tt=B.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:Z.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:[l]}),Et=B.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:[l]}),Dt=B.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:[l]}),Ot=B.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: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:[l]}),kt=B.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:Z.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(t)}),failure:e,failureMode:`return`,dependencies:[o]}),At=B.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:Z.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:[o]}),jt=B.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(Z).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:[o]}),Mt=B.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:[o]}),Nt=ve.make(bt,xt,St,wt,Tt,Et,Dt,Ot,Ct,kt,At,jt,Mt),Pt=[`DRAFT`,`OPEN`,`CLOSED`],Ft=Nt.toLayer({get_projects:d.fn(`TloToolkitHandlers.get_projects`)(function*(e){return{projects:yield*(yield*l).getProjects({...e,states:e.states??[...Pt],limit:e.limit??100,page:e.page??1})}}),get_project_details:d.fn(`TloToolkitHandlers.get_project_details`)(function*(e){return{project:yield*(yield*l).getProjectDetails(e)}}),get_messages:d.fn(`TloToolkitHandlers.get_messages`)(function*(e){return{messages:yield*(yield*l).getMessages({...e,onlyComments:e.onlyComments??!0,hideInternal:e.hideInternal??!0,limit:e.limit??100})}}),set_task_state:d.fn(`TloToolkitHandlers.set_task_state`)(function*(e){yield*(yield*l).setTaskState(e)}),get_tasks:d.fn(`TloToolkitHandlers.get_tasks`)(function*(e){return{tasks:yield*(yield*l).getTasks({...e,states:e.states??[...Pt],limit:e.limit??100,page:e.page??1})}}),get_tasks_for_user:d.fn(`TloToolkitHandlers.get_tasks_for_user`)(function*({startDate:e,...t}){return{tasks:yield*(yield*l).getTasksForUser({...t,startDate:new Date(e)})}}),get_todo_detail:d.fn(`TloToolkitHandlers.get_todo_detail`)(function*(e){return{todo:yield*(yield*l).getTodoDetail(e)}}),move_todo:d.fn(`TloToolkitHandlers.move_todo`)(function*(e){yield*(yield*l).moveTodo(e)}),post_message:d.fn(`TloToolkitHandlers.post_message`)(function*(e){yield*(yield*l).postMessage(e)}),get_week_activities:d.fn(`TloToolkitHandlers.get_week_activities`)(function*(e){let t=yield*o,n=new Date(e.date),r=e.timezone??`Europe/Amsterdam`;return{activities:yield*t.getWeek(n,e.contactId,r)}}),create_activity:d.fn(`TloToolkitHandlers.create_activity`)(function*({startDate:e,...t}){return{id:yield*(yield*o).createActivity({...t,startDate:new Date(e)})}}),update_activity:d.fn(`TloToolkitHandlers.update_activity`)(function*({startDate:e,...t}){yield*(yield*o).updateActivity({...t,startDate:e?new Date(e):void 0})}),delete_activity:d.fn(`TloToolkitHandlers.delete_activity`)(function*(e){yield*(yield*o).deleteActivity(e)})});function It(e){return R.toolkit(Nt).pipe(f.provide(Ft),f.provide(R.layerStdio({...e,stdin:vt,stdout:_t})),f.provide(z.add(z.prettyLogger({stderr:!0}))))}const Q=`tlo-mcp`,$=`0.0.0`,Lt=L.make(Q,{},d.fn(function*(){return yield*It({name:Q,version:$}).pipe(f.provide(c),f.provide(n),f.launch)}));L.run(Lt,{name:Q,version:$})(process.argv).pipe(d.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-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{};
package/dist/index.d.mts CHANGED
@@ -643,6 +643,65 @@ declare const TaskForUser_base: Schema.Class<TaskForUser, {
643
643
  declare class TaskForUser extends TaskForUser_base {}
644
644
  declare const TodoDetail: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
645
645
  type TodoDetail = typeof TodoDetail.Type;
646
+ declare const TodoSummaryRaw: Schema.Struct<{
647
+ ID: typeof Schema.Number;
648
+ NAME: Schema.optional<typeof Schema.String>;
649
+ BOARDLISTID: Schema.optional<typeof Schema.Number>;
650
+ BOARDID: Schema.optional<typeof Schema.Number>;
651
+ OWNERID: Schema.optional<typeof Schema.Number>;
652
+ EXTID: Schema.optional<typeof Schema.String>;
653
+ STATE: Schema.optional<Schema.NullOr<typeof Schema.String>>;
654
+ DUE_DT: Schema.optional<Schema.NullOr<typeof Schema.String>>;
655
+ DESCRIPTION: Schema.optional<Schema.NullOr<typeof Schema.String>>;
656
+ }>;
657
+ type TodoSummaryRaw = typeof TodoSummaryRaw.Type;
658
+ declare const TodoSummary_base: Schema.Class<TodoSummary, {
659
+ id: typeof Schema.Number;
660
+ name: Schema.optional<typeof Schema.String>;
661
+ boardListId: Schema.optional<typeof Schema.Number>;
662
+ boardId: Schema.optional<typeof Schema.Number>;
663
+ ownerId: Schema.optional<typeof Schema.Number>;
664
+ extId: Schema.optional<typeof Schema.String>;
665
+ state: Schema.optional<Schema.NullOr<typeof Schema.String>>;
666
+ dueDate: Schema.optional<Schema.NullOr<typeof Schema.String>>;
667
+ description: Schema.optional<Schema.NullOr<typeof Schema.String>>;
668
+ }, Schema.Struct.Encoded<{
669
+ id: typeof Schema.Number;
670
+ name: Schema.optional<typeof Schema.String>;
671
+ boardListId: Schema.optional<typeof Schema.Number>;
672
+ boardId: Schema.optional<typeof Schema.Number>;
673
+ ownerId: Schema.optional<typeof Schema.Number>;
674
+ extId: Schema.optional<typeof Schema.String>;
675
+ state: Schema.optional<Schema.NullOr<typeof Schema.String>>;
676
+ dueDate: Schema.optional<Schema.NullOr<typeof Schema.String>>;
677
+ description: Schema.optional<Schema.NullOr<typeof Schema.String>>;
678
+ }>, never, {
679
+ readonly description?: string | null | undefined;
680
+ } & {
681
+ readonly id: number;
682
+ } & {
683
+ readonly name?: string | undefined;
684
+ } & {
685
+ readonly state?: string | null | undefined;
686
+ } & {
687
+ readonly extId?: string | undefined;
688
+ } & {
689
+ readonly ownerId?: number | undefined;
690
+ } & {
691
+ readonly boardListId?: number | undefined;
692
+ } & {
693
+ readonly boardId?: number | undefined;
694
+ } & {
695
+ readonly dueDate?: string | null | undefined;
696
+ }, {}, {}>;
697
+ declare class TodoSummary extends TodoSummary_base {}
698
+ declare function todoSummaryFromRaw(raw: TodoSummaryRaw): typeof TodoSummary.Type;
699
+ interface GetBoardTodosParams {
700
+ readonly boardId: number;
701
+ readonly boardListId?: number;
702
+ readonly query?: string;
703
+ readonly limit?: number;
704
+ }
646
705
  interface GetTasksParams {
647
706
  readonly projectId: number;
648
707
  readonly states?: ReadonlyArray<TaskState>;
@@ -680,6 +739,7 @@ interface BoardServiceShape {
680
739
  readonly getTasks: (params: GetTasksParams) => Effect.Effect<ReadonlyArray<typeof Task.Type>, TloError>;
681
740
  readonly getTasksForUser: (params: GetTasksForUserParams) => Effect.Effect<ReadonlyArray<typeof TaskForUser.Type>, TloError>;
682
741
  readonly getTodoDetail: (params: GetTodoDetailParams) => Effect.Effect<TodoDetail, TloError>;
742
+ readonly getBoardTodos: (params: GetBoardTodosParams) => Effect.Effect<ReadonlyArray<typeof TodoSummary.Type>, TloError>;
683
743
  readonly moveTodo: (params: MoveTodoParams) => Effect.Effect<void, TloError>;
684
744
  readonly postMessage: (params: PostMessageParams) => Effect.Effect<void, TloError>;
685
745
  readonly setTaskState: (params: SetTaskStateParams) => Effect.Effect<void, TloError>;
@@ -735,4 +795,4 @@ declare function TloResponse<$A, $I, $R>(dataSchema: Schema.Schema<$A, $I, $R>):
735
795
  err: Schema.optional<typeof Schema.String>;
736
796
  }>;
737
797
  //#endregion
738
- export { Activity, type ActivityRaw, BoardService, BoardServiceLive, type BoardServiceShape, type CreateActivityParams, type DeleteActivityParams, type GetMessagesParams, type GetProjectDetailsParams, type GetProjectsParams, type GetTasksForUserParams, type GetTodoDetailParams, type GetWeekResponse, Message, type MessageRaw, type MoveTodoParams, type PostMessageParams, Project, type ProjectRaw, type SetActivityResponse, type SetTaskStateParams, Task, TaskForUser, type TaskForUserRaw, type TaskRaw, type TaskState, TeamLeaderClient, TeamLeaderClientLive, type TeamLeaderClientShape, TimeService, TimeServiceLive, type TimeServiceShape, TloApiError, TloAuthError, TloClientLive, TloConfig, TloConfigFromEnv, TloConfigLive, type TloConfigShape, TloDate, TloDateString, type TloError, TloId, TloIdSchema, TloLive, TloNetworkError, TloParseError, TloResponse, TloServicesLive, TodoDetail, type UpdateActivityParams, activityFromRaw, formatTloDate, messageFromRaw, projectFromRaw };
798
+ export { Activity, type ActivityRaw, BoardService, BoardServiceLive, type BoardServiceShape, type CreateActivityParams, type DeleteActivityParams, type GetBoardTodosParams, type GetMessagesParams, type GetProjectDetailsParams, type GetProjectsParams, type GetTasksForUserParams, type GetTodoDetailParams, type GetWeekResponse, Message, type MessageRaw, type MoveTodoParams, type PostMessageParams, Project, type ProjectRaw, type SetActivityResponse, type SetTaskStateParams, Task, TaskForUser, type TaskForUserRaw, type TaskRaw, type TaskState, TeamLeaderClient, TeamLeaderClientLive, type TeamLeaderClientShape, TimeService, TimeServiceLive, type TimeServiceShape, TloApiError, TloAuthError, TloClientLive, TloConfig, TloConfigFromEnv, TloConfigLive, type TloConfigShape, TloDate, TloDateString, type TloError, TloId, TloIdSchema, TloLive, TloNetworkError, TloParseError, TloResponse, TloServicesLive, TodoDetail, TodoSummary, type UpdateActivityParams, activityFromRaw, formatTloDate, messageFromRaw, projectFromRaw, todoSummaryFromRaw };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{E as e,S as t,T as n,_ as r,a as i,b as a,c as o,d as s,f as c,g as l,h as u,i as d,l as f,m as p,n as m,o as h,p as g,r as _,s as v,t as y,u as b,v as x,w as S,x as C,y as w}from"./TloLive-19PJ2qwv.mjs";import*as T from"effect/Schema";import*as E from"effect/Brand";const D=T.String.pipe(T.pattern(/^\d{14}$/),T.brand(`TloDateString`));function O(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 k(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 A=T.transform(D,T.DateFromSelf,{strict:!0,decode:O,encode:k}),j=E.nominal(),M=T.String.pipe(T.fromBrand(j));function N(e){return T.Struct({success:T.Boolean,ID:T.optional(T.Number),OBJ:e,err:T.optional(T.String)})}export{r as Activity,h as BoardService,v as BoardServiceLive,o as Message,f as Project,b as Task,s as TaskForUser,w as TeamLeaderClient,a as TeamLeaderClientLive,u as TimeService,l as TimeServiceLive,C as TloApiError,t as TloAuthError,y as TloClientLive,e as TloConfig,d as TloConfigFromEnv,i as TloConfigLive,A as TloDate,D as TloDateString,j as TloId,M as TloIdSchema,m as TloLive,S as TloNetworkError,n as TloParseError,N as TloResponse,_ as TloServicesLive,c as TodoDetail,x as activityFromRaw,k as formatTloDate,g as messageFromRaw,p as projectFromRaw};
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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2digits/tlo-mcp",
3
- "version": "0.0.0",
3
+ "version": "0.1.0",
4
4
  "public": true,
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,32 +21,31 @@
21
21
  "./package.json": "./package.json"
22
22
  },
23
23
  "sideEffects": false,
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "@effect/ai": "0.33.2",
27
+ "@effect/cli": "0.73.0",
28
+ "@effect/experimental": "0.58.0",
29
+ "@effect/platform": "0.94.1",
30
+ "@effect/rpc": "0.73.0",
31
+ "effect": "3.19.14"
32
+ },
33
+ "devDependencies": {
34
+ "@arethetypeswrong/core": "0.18.2",
35
+ "@effect/language-service": "0.71.1",
36
+ "@effect/platform-node": "0.104.0",
37
+ "@effect/vitest": "0.27.0",
38
+ "publint": "0.3.16",
39
+ "tsdown": "0.19.0",
40
+ "typescript": "5.9.3",
41
+ "vitest": "4.0.17",
42
+ "@2digits/tsconfig": "0.8.6"
43
+ },
24
44
  "scripts": {
25
- "prepare": "effect-language-service patch",
26
45
  "build": "tsdown --minify --config-loader unconfig",
27
46
  "dev": "tsdown --watch --config-loader unconfig",
28
47
  "test": "vitest run",
29
48
  "test:watch": "vitest",
30
49
  "types": "tsc --noEmit"
31
- },
32
- "license": "MIT",
33
- "dependencies": {
34
- "@effect/ai": "catalog:",
35
- "@effect/cli": "catalog:",
36
- "@effect/experimental": "catalog:",
37
- "@effect/platform": "catalog:",
38
- "@effect/rpc": "catalog:",
39
- "effect": "catalog:"
40
- },
41
- "devDependencies": {
42
- "@2digits/tsconfig": "workspace:*",
43
- "@arethetypeswrong/core": "catalog:",
44
- "@effect/language-service": "catalog:",
45
- "@effect/platform-node": "catalog:",
46
- "@effect/vitest": "catalog:",
47
- "publint": "catalog:",
48
- "tsdown": "catalog:",
49
- "typescript": "catalog:",
50
- "vitest": "catalog:"
51
50
  }
52
- }
51
+ }
@@ -1 +0,0 @@
1
- import*as e from"effect/Context";import*as t from"@effect/platform/HttpBody";import*as n from"@effect/platform/UrlParams";import*as r from"effect/Effect";import*as i from"effect/Layer";import*as a from"effect/Option";import*as o from"effect/Redacted";import*as s from"effect/Schema";import*as c from"@effect/platform/HttpClient";import*as l from"@effect/platform/HttpClientRequest";import*as u from"effect/Config";import*as d from"@effect/platform/FetchHttpClient";var f=class extends e.Tag(`@2digits/tlo-mcp/services/TloConfig`)(){},p=class extends s.TaggedError()(`TloApiError`,{message:s.String,code:s.optional(s.String),endpoint:s.optional(s.String)}){},m=class extends s.TaggedError()(`TloAuthError`,{message:s.String}){},h=class extends s.TaggedError()(`TloNetworkError`,{message:s.String,cause:s.optional(s.Unknown),endpoint:s.optional(s.String)}){},g=class extends s.TaggedError()(`TloParseError`,{message:s.String,cause:s.optional(s.Unknown)}){};const _=s.Union(p,m,h,g);var v=class extends e.Tag(`@2digits/tlo-mcp/services/TloHttpClient`)(){};function y(e){return[...e.entries()].map(([e,t])=>`${e}=${t}`).join(`; `)}const b=i.effect(v,r.gen(function*(){let e=yield*f,t=(yield*c.HttpClient).pipe(c.mapRequest(l.prependUrl(e.baseUrl)),c.mapRequest(t=>t.pipe(l.setHeader(`Cookie`,y(e.cookies)))),c.filterStatusOk);return v.of({client:t})}));var x=class extends e.Tag(`@2digits/tlo-mcp/services/TeamLeaderClient`)(){};function ee(e){return t=>new h({message:t._tag===`ResponseError`?`HTTP ${t.response.status}`:`Request failed: ${t.reason}`,cause:t,endpoint:e})}function te(e){return new g({message:`Failed to parse response`,cause:e})}function ne(e){return typeof e==`object`&&!!e&&`err`in e&&typeof e.err==`number`&&e.err!==0}const re=/\{MSG:'([^']*)',\s*err:(\d+)\}/;function S(e){let t=re.exec(e);return t?a.some({MSG:t[1]??`Unknown error`,err:Number(t[2])}):a.none()}const C=i.effect(x,r.gen(function*(){let e=yield*f,{client:i}=yield*v;return x.of({post:r.fn(`TeamLeaderClient.post`)(function*(c,l,u){let d={...l,t:o.value(e.sessionToken)},f=n.fromInput(d);return yield*i.post(c,{body:t.urlParams(f)}).pipe(r.flatMap(e=>e.text),r.flatMap(e=>{let t=S(e);if(a.isSome(t)&&t.value.err!==0)return r.fail(new p({message:t.value.MSG,endpoint:c}));let n;try{n=JSON.parse(e)}catch{return r.fail(new g({message:`Invalid JSON response`,cause:e}))}return ne(n)?r.fail(new p({message:n.MSG,endpoint:c})):s.decodeUnknown(u)(n).pipe(r.mapError(te))}),r.scoped,r.mapError(e=>e instanceof p||e instanceof g?e:ee(c)(e)))})})})),w=s.Struct({ID:s.Number,FOLDERID:s.optional(s.Union(s.String,s.Number)),PROJECT_ID:s.optional(s.Union(s.String,s.Number)),TASKID:s.optional(s.NullOr(s.Union(s.String,s.Number))),TODOID:s.optional(s.NullOr(s.Union(s.String,s.Number))),TICKETID:s.optional(s.NullOr(s.Union(s.String,s.Number))),CONTACTID:s.optional(s.Union(s.String,s.Number)),DESCRIPTION:s.NullOr(s.String),DT:s.String,START_DT:s.optional(s.String),END_DT:s.optional(s.String),DURATION:s.Number,TYPE:s.optional(s.Number),PROJECT_NAME:s.optional(s.NullOr(s.String)),TASK_NAME:s.optional(s.NullOr(s.String)),CLIENT_NAME:s.optional(s.NullOr(s.String)),FOLDER_NAME:s.optional(s.NullOr(s.String)),ENTITY_NAME:s.optional(s.NullOr(s.String)),PROJECTOWNER_NAME:s.optional(s.NullOr(s.String)),CLIENT_COLOR:s.optional(s.NullOr(s.String)),PROJECT_COLOR:s.optional(s.NullOr(s.String)),PROJECT_STATE:s.optional(s.NullOr(s.String)),TASK_STATE:s.optional(s.NullOr(s.String)),TIMESHEET_STATE:s.optional(s.NullOr(s.String)),BILLING_MODE:s.optional(s.NullOr(s.String)),NON_BILLABLE:s.optional(s.NullOr(s.Number)),RATE:s.optional(s.NullOr(s.Number)),VALUE:s.optional(s.NullOr(s.Number)),PROJECT_START_DT:s.optional(s.NullOr(s.String)),PROJECT_END_DT:s.optional(s.NullOr(s.String)),TASK_START_DT:s.optional(s.NullOr(s.String)),TASK_END_DT:s.optional(s.NullOr(s.String)),READONLY:s.optional(s.NullOr(s.Number)),TASK_WORKLOAD:s.optional(s.NullOr(s.Number))});var T=class extends s.Class(`Activity`)({id:s.Number,projectId:s.optional(s.String),folderId:s.optional(s.String),taskId:s.optional(s.NullOr(s.String)),todoId:s.optional(s.NullOr(s.String)),ticketId:s.optional(s.NullOr(s.String)),userId:s.optional(s.String),description:s.NullOr(s.String),startDate:s.String,endDate:s.optional(s.String),durationMinutes:s.Number,projectName:s.optional(s.NullOr(s.String)),taskName:s.optional(s.NullOr(s.String)),clientName:s.optional(s.NullOr(s.String)),folderName:s.optional(s.NullOr(s.String)),entityName:s.optional(s.NullOr(s.String)),projectOwnerName:s.optional(s.NullOr(s.String)),projectState:s.optional(s.NullOr(s.String)),taskState:s.optional(s.NullOr(s.String)),timesheetState:s.optional(s.NullOr(s.String)),billingMode:s.optional(s.NullOr(s.String)),nonBillable:s.optional(s.NullOr(s.Number)),rate:s.optional(s.NullOr(s.Number)),value:s.optional(s.NullOr(s.Number)),projectStartDate:s.optional(s.NullOr(s.String)),projectEndDate:s.optional(s.NullOr(s.String)),taskStartDate:s.optional(s.NullOr(s.String)),taskEndDate:s.optional(s.NullOr(s.String)),readOnly:s.optional(s.NullOr(s.Boolean)),taskWorkload:s.optional(s.NullOr(s.Number)),projectColor:s.optional(s.String),clientColor:s.optional(s.String)}){};function E(e){return new T({id:e.ID,projectId:e.PROJECT_ID===void 0?e.FOLDERID===void 0?void 0:String(e.FOLDERID):String(e.PROJECT_ID),folderId:e.FOLDERID===void 0?void 0:String(e.FOLDERID),taskId:e.TASKID!==void 0&&e.TASKID!==null?String(e.TASKID):null,todoId:e.TODOID!==void 0&&e.TODOID!==null?String(e.TODOID):null,ticketId:e.TICKETID!==void 0&&e.TICKETID!==null?String(e.TICKETID):null,userId:e.CONTACTID===void 0?void 0:String(e.CONTACTID),description:e.DESCRIPTION,startDate:e.DT,endDate:e.END_DT,durationMinutes:e.DURATION,projectName:e.PROJECT_NAME,taskName:e.TASK_NAME,clientName:e.CLIENT_NAME,folderName:e.FOLDER_NAME,entityName:e.ENTITY_NAME,projectOwnerName:e.PROJECTOWNER_NAME,projectState:e.PROJECT_STATE,taskState:e.TASK_STATE,timesheetState:e.TIMESHEET_STATE,billingMode:e.BILLING_MODE,nonBillable:e.NON_BILLABLE,rate:e.RATE,value:e.VALUE,projectStartDate:e.PROJECT_START_DT,projectEndDate:e.PROJECT_END_DT,taskStartDate:e.TASK_START_DT,taskEndDate:e.TASK_END_DT,readOnly:e.READONLY===void 0||e.READONLY===null?void 0:e.READONLY!==0,taskWorkload:e.TASK_WORKLOAD,projectColor:e.PROJECT_COLOR??void 0,clientColor:e.CLIENT_COLOR??void 0})}const D=s.Struct({ACTIVITIES:s.Array(w)}),O=s.Struct({ID:s.Number,DURATION:s.optional(s.Number),DT:s.optional(s.String),TYPE:s.optional(s.Number),DESCRIPTION:s.optional(s.NullOr(s.String)),CLIENT_COLOR:s.optional(s.String),FOLDERID:s.optional(s.Union(s.String,s.Number))});function k(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}T${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}`}var A=class extends e.Tag(`@2digits/tlo-mcp/services/TimeService`)(){};const j=i.effect(A,r.gen(function*(){let e=yield*x;return A.of({getWeek:r.fn(`TimeService.getWeek`)(function*(t,n,i=`Europe/Amsterdam`){return yield*e.post(`/ajax/pln/GetWeek`,{DT:k(t),CONTACTID:n,tmz:i},D).pipe(r.map(e=>e.ACTIVITIES.map(e=>E(e))))}),createActivity:r.fn(`TimeService.createActivity`)(function*(t){return yield*e.post(`/ajax/pln/SetActivity`,{ID:0,ACTION:`CREATE`,DT:k(t.startDate),DURATION:t.durationMinutes,FOLDERID:t.folderId,TASKID:t.taskId,TODOID:t.todoId,CONTACTID:t.contactId,CLIENT_COLOR:t.clientColor,DESCRIPTION:t.description},O).pipe(r.map(e=>e.ID))}),updateActivity:r.fn(`TimeService.updateActivity`)(function*(t){return yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`MOVE`,DT:t.startDate?k(t.startDate):void 0,DURATION:t.durationMinutes,DESCRIPTION:t.description},O).pipe(r.asVoid)}),deleteActivity:r.fn(`TimeService.deleteActivity`)(function*(t){return yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`DELETE`},O).pipe(r.asVoid)})})})),M=s.Struct({ID:s.Number,PROJECT_NAME:s.optional(s.String),NAME:s.optional(s.String),STATE:s.optional(s.String),OWNER_NAME:s.optional(s.String),START_DT:s.optional(s.String),END_DT:s.optional(s.String),BILLING_BUDGET:s.optional(s.Number),BILLING_MODE:s.optional(s.String),BILLING_REMAINING:s.optional(s.Number),CLIENT_NAME:s.optional(s.String),CLIENT_ID:s.optional(s.Number),FOLDERID:s.optional(s.Number),FOLDER_NAME:s.optional(s.String),EXTID:s.optional(s.String),CALC_TOTAL:s.optional(s.Number),CALC_DONE:s.optional(s.Number),CALC_PLANNED:s.optional(s.Number)}),ie=s.Struct({Records:s.Array(M),RecordCount:s.optional(s.Number)}),ae=s.Union(M,s.Struct({Record:M}));var N=class extends s.Class(`Project`)({id:s.Number,name:s.String,state:s.optional(s.String),ownerName:s.optional(s.String),startDate:s.optional(s.String),endDate:s.optional(s.String),billingBudget:s.optional(s.Number),billingMode:s.optional(s.String),billingRemaining:s.optional(s.Number),clientName:s.optional(s.String),clientId:s.optional(s.Number),folderId:s.optional(s.Number),folderName:s.optional(s.String),extId:s.optional(s.String),calcTotal:s.optional(s.Number),calcDone:s.optional(s.Number),calcPlanned:s.optional(s.Number)}){};function P(e){return N.make({id:e.ID,name:e.PROJECT_NAME??e.NAME??``,state:e.STATE,ownerName:e.OWNER_NAME,startDate:e.START_DT,endDate:e.END_DT,billingBudget:e.BILLING_BUDGET,billingMode:e.BILLING_MODE,billingRemaining:e.BILLING_REMAINING,clientName:e.CLIENT_NAME,clientId:e.CLIENT_ID,folderId:e.FOLDERID,folderName:e.FOLDER_NAME,extId:e.EXTID,calcTotal:e.CALC_TOTAL,calcDone:e.CALC_DONE,calcPlanned:e.CALC_PLANNED})}const F=s.Struct({ID:s.Number,OWNERID:s.optional(s.Number),OWNER_NAME:s.optional(s.String),AVATAR:s.optional(s.String),CREATED_DT:s.optional(s.String),CONTENT:s.optional(s.String),SUBCONTENT:s.optional(s.String),OBJECTTYPE:s.optional(s.String),OBJECTID:s.optional(s.Number),OBJECTNAME:s.optional(s.String),MSGTYPE:s.optional(s.String),LIKECNT:s.optional(s.Number),REPLYCNT:s.optional(s.Number),OUTQUEUEID:s.optional(s.String),INTERNAL:s.optional(s.Number)}),I=s.Array(F);var L=class extends s.Class(`Message`)({id:s.Number,ownerId:s.optional(s.Number),ownerName:s.optional(s.String),avatar:s.optional(s.String),createdAt:s.optional(s.String),content:s.optional(s.String),subcontent:s.optional(s.String),objectType:s.optional(s.String),objectId:s.optional(s.Number),objectName:s.optional(s.String),messageType:s.optional(s.String),likeCount:s.optional(s.Number),replyCount:s.optional(s.Number),outQueueId:s.optional(s.String),internal:s.optional(s.Boolean)}){};function R(e){return new L({id:e.ID,ownerId:e.OWNERID,ownerName:e.OWNER_NAME,avatar:e.AVATAR,createdAt:e.CREATED_DT,content:e.CONTENT,subcontent:e.SUBCONTENT,objectType:e.OBJECTTYPE,objectId:e.OBJECTID,objectName:e.OBJECTNAME,messageType:e.MSGTYPE,likeCount:e.LIKECNT,replyCount:e.REPLYCNT,outQueueId:e.OUTQUEUEID,internal:e.INTERNAL===void 0?void 0:e.INTERNAL!==0})}const z=s.Struct({ID:s.Number,PROJECTID:s.optional(s.Number),NAME:s.optional(s.String),STATE:s.optional(s.String),OWNER_NAME:s.optional(s.String),START_DT:s.optional(s.String),END_DT:s.optional(s.String),BUDGET:s.optional(s.Number)}),B=s.Struct({Records:s.Array(z),RecordCount:s.optional(s.Number)});var V=class extends s.Class(`Task`)({id:s.Number,projectId:s.optional(s.Number),name:s.optional(s.String),state:s.optional(s.String),ownerName:s.optional(s.String),startDate:s.optional(s.String),endDate:s.optional(s.String),budget:s.optional(s.Number)}){};function H(e){return new V({id:e.ID,projectId:e.PROJECTID,name:e.NAME,state:e.STATE,ownerName:e.OWNER_NAME,startDate:e.START_DT,endDate:e.END_DT,budget:e.BUDGET})}const U=s.Struct({ID:s.Number,WORKLOAD:s.optional(s.Number),TOTAL:s.optional(s.Number),REMAINING:s.optional(s.Number),AVAIL:s.optional(s.Number),CLIENTID:s.optional(s.Number),PROJECTID:s.optional(s.Number),PROJECT_START_DT:s.optional(s.String),PROJECT_END_DT:s.optional(s.String),START_DT:s.optional(s.String),END_DT:s.optional(s.String),STATE:s.optional(s.String)}),W=s.Struct({Records:s.Array(U)});var G=class extends s.Class(`TaskForUser`)({id:s.Number,workload:s.optional(s.Number),total:s.optional(s.Number),remaining:s.optional(s.Number),avail:s.optional(s.Number),clientId:s.optional(s.Number),projectId:s.optional(s.Number),projectStartDate:s.optional(s.String),projectEndDate:s.optional(s.String),startDate:s.optional(s.String),endDate:s.optional(s.String),state:s.optional(s.String)}){};function K(e){return new G({id:e.ID,workload:e.WORKLOAD,total:e.TOTAL,remaining:e.REMAINING,avail:e.AVAIL,clientId:e.CLIENTID,projectId:e.PROJECTID,projectStartDate:e.PROJECT_START_DT,projectEndDate:e.PROJECT_END_DT,startDate:e.START_DT,endDate:e.END_DT,state:e.STATE})}const q=s.Record({key:s.String,value:s.Unknown});var J=class extends e.Tag(`@2digits/tlo-mcp/services/BoardService`)(){};function oe(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}function Y(e){return e.Records}const X=i.effect(J,r.gen(function*(){let e=yield*x;return J.of({getProjects:r.fn(`BoardService.getProjects`)(function*(t={}){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`];return yield*e.post(`/ajax/pln/GetProjects`,{STATE:n.join(`|`),COLUMNS:`ID|PROJECT_NAME|NAME|STATE|OWNER_NAME|START_DT|END_DT|BILLING_BUDGET|BILLING_MODE|BILLING_REMAINING|CLIENT_NAME|CLIENT_ID|FOLDERID|FOLDER_NAME|EXTID|CALC_TOTAL|CALC_DONE|CALC_PLANNED`,limit:t.limit??100,page:t.page??1},ie).pipe(r.map(e=>e.Records.map(e=>P(e))))}),getProjectDetails:r.fn(`BoardService.getProjectDetails`)(function*(t){return yield*e.post(`/ajax/pln/GetProjectDetails`,{ID:t.projectId},ae).pipe(r.map(e=>`Record`in e?e.Record:e),r.map(e=>P(e)))}),getMessages:r.fn(`BoardService.getMessages`)(function*(t){return yield*e.post(`/ajax/board/ProcessMessage`,{OBJECTTYPE:t.objectType,OBJECTID:t.objectId,ONLYCOMMENTS:t.onlyComments===!1?0:1,HIDEINTERNAL:t.hideInternal===!1?0:1,PAGETYPE:`SEQID`,MINID:0,limit:t.limit??100},I).pipe(r.map(e=>e.map(e=>R(e))))}),getTasks:r.fn(`BoardService.getTasks`)(function*(t){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`];return yield*e.post(`/ajax/pln/GetTasks`,{PROJECTID:t.projectId,STATE:n.join(`|`),COLUMNS:`ID|PROJECTID|NAME|STATE|OWNER_NAME|START_DT|END_DT|BUDGET`,limit:t.limit??100,page:t.page??1},B).pipe(r.map(e=>e.Records.map(e=>H(e))))}),getTasksForUser:r.fn(`BoardService.getTasksForUser`)(function*(t){return yield*e.post(`/ajax/pln/GetTasksForUser`,{CONTACTID:t.contactId,START_DT:oe(t.startDate),PERIOD:t.period},W).pipe(r.map(e=>Y(e)),r.map(e=>e.map(e=>K(e))))}),getTodoDetail:r.fn(`BoardService.getTodoDetail`)(function*(t){return yield*e.post(`/ajax/board/GetTodoDetail`,{ID:t.id},q)}),moveTodo:r.fn(`BoardService.moveTodo`)(function*(t){return yield*e.post(`/ajax/board/MoveTodo`,{ID:t.id,BOARDID:t.boardId,BOARDLISTID:t.boardListId,SORTINDEX:t.sortIndex},s.Unknown).pipe(r.asVoid)}),postMessage:r.fn(`BoardService.postMessage`)(function*(t){return yield*e.post(`/ajax/board/ProcessMessage`,{ACTION:`ADD`,OBJECTTYPE:t.objectType,OBJECTID:t.objectId,CONTENT:t.content},s.Unknown).pipe(r.asVoid)}),setTaskState:r.fn(`BoardService.setTaskState`)(function*(t){return yield*e.post(`/ajax/pln/SetTaskState`,{PROJECTID:t.projectId,ID:t.taskId,STATE:t.state},s.Unknown).pipe(r.asVoid)})})}));function se(e){if(a.isNone(e))return new Map;let t=e.value.split(`;`).map(e=>e.trim().split(`=`)).filter(e=>e.length===2);return new Map(t)}const Z=r.gen(function*(){let e=yield*u.redacted(`TLO_SESSION_TOKEN`);return{baseUrl:yield*u.string(`TLO_BASE_URL`).pipe(u.withDefault(`https://socialbrothers.orbit.teamleader.eu`)),sessionToken:e,cookies:se(yield*u.option(u.string(`TLO_COOKIES`)))}}),ce=i.effect(f,Z),Q=i.mergeAll(j,X),$=C.pipe(i.provide(b.pipe(i.provide(d.layer)))),le=Q.pipe(i.provide($));export{_ as C,f as E,m as S,g as T,T as _,ce as a,C as b,L as c,G as d,q as f,j as g,A as h,Z as i,N as l,P as m,le as n,J as o,R as p,Q as r,X as s,$ as t,V as u,E as v,h as w,p as x,x as y};