@2digits/tlo-mcp 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{TloLive-BTpDuZnK.mjs → TloLive-NziwhmYD.mjs} +1 -1
- package/dist/bin.mjs +1 -1
- package/dist/index.d.mts +55 -43
- package/dist/index.mjs +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"effect/Context";import*as t from"effect/Effect";import*as n from"effect/Layer";import*as r from"effect/Match";import*as i from"effect/Option";import*as a from"effect/Record";import*as ee from"effect/Redacted";import*as o from"effect/Schema";import*as s from"effect/unstable/http/HttpBody";import*as te from"effect/unstable/http/UrlParams";import*as c from"effect/unstable/http/Cookies";import*as l from"effect/unstable/http/HttpClient";import*as u from"effect/unstable/http/HttpClientRequest";import*as d from"effect/Array";import*as f from"effect/String";import*as p from"effect/Config";import*as m from"effect/unstable/http/FetchHttpClient";var h=class extends e.Service()(`@2digits/tlo-mcp/services/TloConfig`){},g=class extends o.TaggedError()(`TloApiError`,{message:o.String,code:o.optional(o.String),endpoint:o.optional(o.String)}){},_=class extends o.TaggedError()(`TloAuthError`,{message:o.String}){},v=class extends o.TaggedError()(`TloNetworkError`,{message:o.String,cause:o.optional(o.Unknown),endpoint:o.optional(o.String)}){},y=class extends o.TaggedError()(`TloParseError`,{message:o.String,cause:o.optional(o.Unknown)}){};const ne=o.Union([g,_,v,y]);var b=class extends e.Service()(`@2digits/tlo-mcp/services/TloHttpClient`){};const x=n.effect(b,t.gen(function*(){let e=yield*h,t=yield*l.HttpClient,n=c.toCookieHeader(e.cookies),r=t.pipe(l.mapRequest(u.prependUrl(e.baseUrl)),l.mapRequest(u.setHeader(`Cookie`,n)),l.filterStatusOk);return b.of({client:r})}));var S=class extends e.Service()(`@2digits/tlo-mcp/services/TeamLeaderClient`){};const re=o.Struct({MSG:o.String,err:o.Finite}),ie=o.fromJsonString(o.Unknown),ae=/\{MSG:'([^']*)',\s*err:(\d+)\}/;function oe(e){let t=ae.exec(e);return r.value(t).pipe(r.when(r.defined,e=>i.some({MSG:e[1]??`Unknown error`,err:Number(e[2])})),r.orElse(()=>i.none()))}const C=n.effect(S,t.gen(function*(){let e=yield*h,{client:n}=yield*b;return S.of({post:t.fn(`TeamLeaderClient.post`)(function*(i,c,l){let u=a.set(c,`t`,ee.value(e.sessionToken)),d=te.fromInput(u),f=yield*(yield*n.post(i,{body:s.urlParams(d)})).text,p=oe(f);yield*r.value(p).pipe(r.tag(`Some`,({value:e})=>e.err===0?t.void:g.make({message:e.MSG,endpoint:i})),r.tag(`None`,()=>t.void),r.exhaustive);let m=yield*o.decodeEffect(ie)(f).pipe(t.mapError(e=>y.make({message:`Invalid JSON response`,cause:e})));return yield*r.value(m).pipe(r.when(o.is(re),e=>e.err===0?t.void:g.make({message:e.MSG,endpoint:i})),r.orElse(()=>t.void)),yield*o.decodeUnknownEffect(l)(m).pipe(t.mapError(e=>y.make({message:`Failed to parse response`,cause:e})))},t.scoped,(e,n)=>e.pipe(t.mapError(e=>r.value(e).pipe(r.when(o.is(g),e=>e),r.when(o.is(y),e=>e),r.orElse(e=>v.make({message:e.response===void 0?`Request failed: ${e.message}`:`HTTP ${e.response.status}`,cause:e,endpoint:n}))))))})})),w=o.Struct({ID:o.Finite,FOLDERID:o.optional(o.Union([o.String,o.Finite])),PROJECT_ID:o.optional(o.Union([o.String,o.Finite])),TASKID:o.Union([o.String,o.Finite]).pipe(o.NullOr,o.optional),TODOID:o.Union([o.String,o.Finite]).pipe(o.NullOr,o.optional),TICKETID:o.Union([o.String,o.Finite]).pipe(o.NullOr,o.optional),CONTACTID:o.optional(o.Union([o.String,o.Finite])),DESCRIPTION:o.NullOr(o.String),DT:o.String,START_DT:o.optional(o.String),END_DT:o.optional(o.String),DURATION:o.Finite,TYPE:o.optional(o.Finite),PROJECT_NAME:o.String.pipe(o.NullOr,o.optional),TASK_NAME:o.String.pipe(o.NullOr,o.optional),CLIENT_NAME:o.String.pipe(o.NullOr,o.optional),FOLDER_NAME:o.String.pipe(o.NullOr,o.optional),ENTITY_NAME:o.String.pipe(o.NullOr,o.optional),PROJECTOWNER_NAME:o.String.pipe(o.NullOr,o.optional),CLIENT_COLOR:o.String.pipe(o.NullOr,o.optional),PROJECT_COLOR:o.String.pipe(o.NullOr,o.optional),PROJECT_STATE:o.String.pipe(o.NullOr,o.optional),TASK_STATE:o.String.pipe(o.NullOr,o.optional),TIMESHEET_STATE:o.String.pipe(o.NullOr,o.optional),BILLING_MODE:o.String.pipe(o.NullOr,o.optional),NON_BILLABLE:o.Finite.pipe(o.NullOr,o.optional),RATE:o.Finite.pipe(o.NullOr,o.optional),VALUE:o.Finite.pipe(o.NullOr,o.optional),PROJECT_START_DT:o.String.pipe(o.NullOr,o.optional),PROJECT_END_DT:o.String.pipe(o.NullOr,o.optional),TASK_START_DT:o.String.pipe(o.NullOr,o.optional),TASK_END_DT:o.String.pipe(o.NullOr,o.optional),READONLY:o.Finite.pipe(o.NullOr,o.optional),TASK_WORKLOAD:o.Finite.pipe(o.NullOr,o.optional)});var T=class extends o.Class(`Activity`)({id:o.Finite,projectId:o.optional(o.String),folderId:o.optional(o.String),taskId:o.String.pipe(o.NullOr,o.optional),todoId:o.String.pipe(o.NullOr,o.optional),ticketId:o.String.pipe(o.NullOr,o.optional),userId:o.optional(o.String),description:o.NullOr(o.String),startDate:o.String,endDate:o.optional(o.String),durationMinutes:o.Finite,projectName:o.String.pipe(o.NullOr,o.optional),taskName:o.String.pipe(o.NullOr,o.optional),clientName:o.String.pipe(o.NullOr,o.optional),folderName:o.String.pipe(o.NullOr,o.optional),entityName:o.String.pipe(o.NullOr,o.optional),projectOwnerName:o.String.pipe(o.NullOr,o.optional),projectState:o.String.pipe(o.NullOr,o.optional),taskState:o.String.pipe(o.NullOr,o.optional),timesheetState:o.String.pipe(o.NullOr,o.optional),billingMode:o.String.pipe(o.NullOr,o.optional),nonBillable:o.Finite.pipe(o.NullOr,o.optional),rate:o.Finite.pipe(o.NullOr,o.optional),value:o.Finite.pipe(o.NullOr,o.optional),projectStartDate:o.String.pipe(o.NullOr,o.optional),projectEndDate:o.String.pipe(o.NullOr,o.optional),taskStartDate:o.String.pipe(o.NullOr,o.optional),taskEndDate:o.String.pipe(o.NullOr,o.optional),readOnly:o.Boolean.pipe(o.NullOr,o.optional),taskWorkload:o.Finite.pipe(o.NullOr,o.optional),projectColor:o.optional(o.String),clientColor:o.optional(o.String)}){};function E(e){return T.make({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 se=o.Struct({ACTIVITIES:o.Array(w)}),D=o.Struct({ID:o.Finite,DURATION:o.optional(o.Finite),DT:o.optional(o.String),TYPE:o.optional(o.Finite),DESCRIPTION:o.String.pipe(o.NullOr,o.optional),CLIENT_COLOR:o.optional(o.String),FOLDERID:o.optional(o.Union([o.String,o.Finite]))});function O(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 k=class extends e.Service()(`@2digits/tlo-mcp/services/TimeService`){};const A=n.effect(k,t.gen(function*(){let e=yield*S;return k.of({getWeek:t.fn(`TimeService.getWeek`)(function*(t,n,r=`Europe/Amsterdam`){let i=yield*e.post(`/ajax/pln/GetWeek`,{DT:O(t),CONTACTID:n,tmz:r},se);return d.map(E)(i.ACTIVITIES)}),createActivity:t.fn(`TimeService.createActivity`)(function*(t){return(yield*e.post(`/ajax/pln/SetActivity`,{ID:0,ACTION:`CREATE`,DT:O(t.startDate),DURATION:t.durationMinutes,FOLDERID:t.folderId,TASKID:t.taskId,TODOID:t.todoId,CONTACTID:t.contactId,CLIENT_COLOR:t.clientColor,DESCRIPTION:t.description},D)).ID}),updateActivity:t.fn(`TimeService.updateActivity`)(function*(t){yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`MOVE`,DT:t.startDate===void 0?void 0:O(t.startDate),DURATION:t.durationMinutes,DESCRIPTION:t.description},D)}),deleteActivity:t.fn(`TimeService.deleteActivity`)(function*(t){yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`DELETE`},D)})})})),j=o.Struct({ID:o.Finite,PROJECT_NAME:o.optional(o.String),NAME:o.optional(o.String),STATE:o.optional(o.String),OWNER_NAME:o.optional(o.String),START_DT:o.optional(o.String),END_DT:o.optional(o.String),BILLING_BUDGET:o.optional(o.Finite),BILLING_MODE:o.optional(o.String),BILLING_REMAINING:o.optional(o.Finite),CLIENT_NAME:o.optional(o.String),CLIENT_ID:o.optional(o.Finite),FOLDERID:o.optional(o.Finite),FOLDER_NAME:o.optional(o.String),EXTID:o.optional(o.String),CALC_TOTAL:o.optional(o.Finite),CALC_DONE:o.optional(o.Finite),CALC_PLANNED:o.optional(o.Finite)}),ce=o.Struct({Records:o.Array(j),RecordCount:o.optional(o.Finite)}),le=o.Union([j,o.Struct({Record:j})]);var M=class extends o.Class(`Project`)({id:o.Finite,name:o.String,state:o.optional(o.String),ownerName:o.optional(o.String),startDate:o.optional(o.String),endDate:o.optional(o.String),billingBudget:o.optional(o.Finite),billingMode:o.optional(o.String),billingRemaining:o.optional(o.Finite),clientName:o.optional(o.String),clientId:o.optional(o.Finite),folderId:o.optional(o.Finite),folderName:o.optional(o.String),extId:o.optional(o.String),calcTotal:o.optional(o.Finite),calcDone:o.optional(o.Finite),calcPlanned:o.optional(o.Finite)}){};function N(e){return M.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 P=o.Struct({ID:o.Finite,OWNERID:o.optional(o.Finite),OWNER_NAME:o.optional(o.String),AVATAR:o.optional(o.String),CREATED_DT:o.optional(o.String),CONTENT:o.optional(o.String),SUBCONTENT:o.optional(o.String),OBJECTTYPE:o.optional(o.String),OBJECTID:o.optional(o.Finite),OBJECTNAME:o.optional(o.String),MSGTYPE:o.optional(o.String),LIKECNT:o.optional(o.Finite),REPLYCNT:o.optional(o.Finite),OUTQUEUEID:o.optional(o.String),INTERNAL:o.optional(o.Finite)}),F=o.Array(P);var I=class extends o.Class(`Message`)({id:o.Finite,ownerId:o.optional(o.Finite),ownerName:o.optional(o.String),avatar:o.optional(o.String),createdAt:o.optional(o.String),content:o.optional(o.String),subcontent:o.optional(o.String),objectType:o.optional(o.String),objectId:o.optional(o.Finite),objectName:o.optional(o.String),messageType:o.optional(o.String),likeCount:o.optional(o.Finite),replyCount:o.optional(o.Finite),outQueueId:o.optional(o.String),internal:o.optional(o.Boolean)}){};function L(e){return I.make({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=o.Struct({ID:o.Finite,PROJECTID:o.optional(o.Finite),NAME:o.optional(o.String),STATE:o.optional(o.String),OWNER_NAME:o.optional(o.String),START_DT:o.optional(o.String),END_DT:o.optional(o.String),BUDGET:o.optional(o.Finite)}),z=o.Struct({Records:o.Array(R),RecordCount:o.optional(o.Finite)});var B=class extends o.Class(`Task`)({id:o.Finite,projectId:o.optional(o.Finite),name:o.optional(o.String),state:o.optional(o.String),ownerName:o.optional(o.String),startDate:o.optional(o.String),endDate:o.optional(o.String),budget:o.optional(o.Finite)}){};function V(e){return B.make({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=o.Struct({ID:o.Finite,WORKLOAD:o.optional(o.Finite),TOTAL:o.optional(o.Finite),REMAINING:o.optional(o.Finite),AVAIL:o.optional(o.Finite),CLIENTID:o.optional(o.Finite),PROJECTID:o.optional(o.Finite),PROJECT_START_DT:o.optional(o.String),PROJECT_END_DT:o.optional(o.String),START_DT:o.optional(o.String),END_DT:o.optional(o.String),STATE:o.optional(o.String)}),U=o.Struct({Records:o.Array(H)});var W=class extends o.Class(`TaskForUser`)({id:o.Finite,workload:o.optional(o.Finite),total:o.optional(o.Finite),remaining:o.optional(o.Finite),avail:o.optional(o.Finite),clientId:o.optional(o.Finite),projectId:o.optional(o.Finite),projectStartDate:o.optional(o.String),projectEndDate:o.optional(o.String),startDate:o.optional(o.String),endDate:o.optional(o.String),state:o.optional(o.String)}){};function ue(e){return W.make({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 G=o.Record(o.String,o.Unknown),de=o.Struct({ID:o.Finite,NAME:o.optional(o.String),BOARDLISTID:o.optional(o.Finite),BOARDID:o.optional(o.Finite),OWNERID:o.optional(o.Finite),EXTID:o.optional(o.String),STATE:o.String.pipe(o.NullOr,o.optional),DUE_DT:o.String.pipe(o.NullOr,o.optional),DESCRIPTION:o.String.pipe(o.NullOr,o.optional)}),K=o.Struct({Records:o.Array(de),RecordCount:o.optional(o.Finite)});var q=class extends o.Class(`TodoSummary`)({id:o.Finite,name:o.optional(o.String),boardListId:o.optional(o.Finite),boardId:o.optional(o.Finite),ownerId:o.optional(o.Finite),extId:o.optional(o.String),state:o.String.pipe(o.NullOr,o.optional),dueDate:o.String.pipe(o.NullOr,o.optional),description:o.String.pipe(o.NullOr,o.optional)}){};function J(e){return q.make({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.Service()(`@2digits/tlo-mcp/services/BoardService`){};function fe(e){return`${e.getFullYear()}-${(e.getMonth()+1).toString().padStart(2,`0`)}-${e.getDate().toString().padStart(2,`0`)}`}const X=n.effect(Y,t.gen(function*(){let e=yield*S;return Y.of({getProjects:t.fn(`BoardService.getProjects`)(function*(t={}){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`],r=yield*e.post(`/ajax/pln/GetProjects`,{STATE:d.join(n,`|`),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},ce);return d.map(N)(r.Records)}),getProjectDetails:t.fn(`BoardService.getProjectDetails`)(function*(t){let n=yield*e.post(`/ajax/pln/GetProjectDetails`,{ID:t.projectId},le);return N(r.value(n).pipe(r.when({Record:r.any},({Record:e})=>e),r.orElse(e=>e)))}),getMessages:t.fn(`BoardService.getMessages`)(function*(t){let n=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);return d.map(L)(n)}),getTasks:t.fn(`BoardService.getTasks`)(function*(t){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`],r=yield*e.post(`/ajax/pln/GetTasks`,{PROJECTID:t.projectId,STATE:d.join(n,`|`),COLUMNS:`ID|PROJECTID|NAME|STATE|OWNER_NAME|START_DT|END_DT|BUDGET`,limit:t.limit??100,page:t.page??1},z);return d.map(V)(r.Records)}),getTasksForUser:t.fn(`BoardService.getTasksForUser`)(function*(t){let n=yield*e.post(`/ajax/pln/GetTasksForUser`,{CONTACTID:t.contactId,START_DT:fe(t.startDate),PERIOD:t.period},U);return d.map(ue)(n.Records)}),getTodoDetail:t.fn(`BoardService.getTodoDetail`)(function*(t){return yield*e.post(`/ajax/board/GetTodoDetail`,{ID:t.id},G)}),getBoardTodos:t.fn(`BoardService.getBoardTodos`)(function*(t){let n=yield*e.post(`/ajax/board/GetTodos`,{BOARDID:t.boardId,BOARDLISTID:t.boardListId,limit:t.limit??100},K),i=d.map(J)(n.Records);return r.value(t.query).pipe(r.when(r.nonEmptyString,e=>{let t=f.toLowerCase(e);return d.filter(i,e=>e.name!==void 0&&f.includes(t)(f.toLowerCase(e.name)))}),r.orElse(()=>i))}),moveTodo:t.fn(`BoardService.moveTodo`)(function*(t){yield*e.post(`/ajax/board/MoveTodo`,{ID:t.id,BOARDID:t.boardId,BOARDLISTID:t.boardListId,SORTINDEX:t.sortIndex},o.Unknown)}),postMessage:t.fn(`BoardService.postMessage`)(function*(t){yield*e.post(`/ajax/board/ProcessMessage`,{ACTION:`ADD`,OBJECTTYPE:t.objectType,OBJECTID:t.objectId,CONTENT:t.content},o.Unknown)}),setTaskState:t.fn(`BoardService.setTaskState`)(function*(t){yield*e.post(`/ajax/pln/SetTaskState`,{PROJECTID:t.projectId,ID:t.taskId,STATE:t.state},o.Unknown)})})})),Z=t.gen(function*(){let e=yield*p.redacted(`TLO_SESSION_TOKEN`),n=yield*p.string(`TLO_BASE_URL`).pipe(p.withDefault(`https://socialbrothers.orbit.teamleader.eu`)),r=yield*p.string(`TLO_COOKIES`).pipe(p.withDefault(``));return{baseUrl:n,sessionToken:e,cookies:yield*t.fromResult(c.setAll(c.empty,a.toEntries(c.parseHeader(r))))}}),pe=n.effect(h,Z),Q=n.mergeAll(A,X),$=C.pipe(n.provide(x.pipe(n.provide(m.layer)))),me=Q.pipe(n.provide($));export{g as C,y as D,v as E,h as O,C as S,ne as T,k as _,pe as a,E as b,I as c,W as d,G as f,J as g,N as h,Z as i,M as l,L as m,me as n,Y as o,q as p,Q as r,X as s,$ as t,B as u,A as v,_ as w,S as x,T as y};
|
|
1
|
+
import*as e from"effect/Context";import*as t from"effect/Effect";import*as n from"effect/Layer";import*as r from"effect/Match";import*as i from"effect/Option";import*as a from"effect/Record";import*as ee from"effect/Redacted";import*as o from"effect/Schema";import*as s from"effect/unstable/http/HttpBody";import*as te from"effect/unstable/http/UrlParams";import*as c from"effect/unstable/http/Cookies";import*as l from"effect/unstable/http/HttpClient";import*as u from"effect/unstable/http/HttpClientRequest";import*as d from"effect/Array";import*as f from"effect/String";import*as p from"effect/Config";import*as m from"effect/unstable/http/FetchHttpClient";var h=class extends e.Service()(`@2digits/tlo-mcp/services/TloConfig`){},g=class extends o.TaggedError()(`TloApiError`,{message:o.String,code:o.optional(o.String),endpoint:o.optional(o.String)}){},_=class extends o.TaggedError()(`TloAuthError`,{message:o.String}){},v=class extends o.TaggedError()(`TloNetworkError`,{message:o.String,cause:o.optional(o.Unknown),endpoint:o.optional(o.String)}){},y=class extends o.TaggedError()(`TloParseError`,{message:o.String,cause:o.optional(o.Unknown)}){};const ne=o.Union([g,_,v,y]);var b=class extends e.Service()(`@2digits/tlo-mcp/services/TloHttpClient`){};const x=n.effect(b,t.gen(function*(){let e=yield*h,t=yield*l.HttpClient,n=c.toCookieHeader(e.cookies),r=t.pipe(l.mapRequest(u.prependUrl(e.baseUrl)),l.mapRequest(u.setHeader(`Cookie`,n)),l.filterStatusOk);return b.of({client:r})}));var S=class extends e.Service()(`@2digits/tlo-mcp/services/TeamLeaderClient`){};const re=o.Struct({MSG:o.String,err:o.Finite}),ie=o.fromJsonString(o.Unknown),ae=/\{MSG:'([^']*)',\s*err:(\d+)\}/;function oe(e){let t=ae.exec(e);return r.value(t).pipe(r.when(r.defined,e=>i.some({MSG:e[1]??`Unknown error`,err:Number(e[2])})),r.orElse(()=>i.none()))}const C=n.effect(S,t.gen(function*(){let e=yield*h,{client:n}=yield*b;return S.of({post:t.fn(`TeamLeaderClient.post`)(function*(i,c,l){let u=a.set(c,`t`,ee.value(e.sessionToken)),d=te.fromInput(u),f=yield*(yield*n.post(i,{body:s.urlParams(d)})).text,p=oe(f);yield*r.value(p).pipe(r.tag(`Some`,({value:e})=>e.err===0?t.void:g.make({message:e.MSG,endpoint:i})),r.tag(`None`,()=>t.void),r.exhaustive);let m=yield*o.decodeEffect(ie)(f).pipe(t.mapError(e=>y.make({message:`Invalid JSON response`,cause:e})));return yield*r.value(m).pipe(r.when(o.is(re),e=>e.err===0?t.void:g.make({message:e.MSG,endpoint:i})),r.orElse(()=>t.void)),yield*o.decodeUnknownEffect(l)(m).pipe(t.mapError(e=>y.make({message:`Failed to parse response`,cause:e})))},t.scoped,(e,n)=>e.pipe(t.mapError(e=>r.value(e).pipe(r.when(o.is(g),e=>e),r.when(o.is(y),e=>e),r.orElse(e=>v.make({message:e.response===void 0?`Request failed: ${e.message}`:`HTTP ${e.response.status}`,cause:e,endpoint:n}))))))})})),w=o.Struct({ID:o.Finite,FOLDERID:o.optional(o.Union([o.String,o.Finite])),PROJECT_ID:o.optional(o.Union([o.String,o.Finite])),TASKID:o.Union([o.String,o.Finite]).pipe(o.NullOr,o.optional),TODOID:o.Union([o.String,o.Finite]).pipe(o.NullOr,o.optional),TICKETID:o.Union([o.String,o.Finite]).pipe(o.NullOr,o.optional),CONTACTID:o.optional(o.Union([o.String,o.Finite])),DESCRIPTION:o.NullOr(o.String),DT:o.String,START_DT:o.optional(o.String),END_DT:o.optional(o.String),DURATION:o.Finite,TYPE:o.optional(o.Finite),PROJECT_NAME:o.String.pipe(o.NullOr,o.optional),TASK_NAME:o.String.pipe(o.NullOr,o.optional),CLIENT_NAME:o.String.pipe(o.NullOr,o.optional),FOLDER_NAME:o.String.pipe(o.NullOr,o.optional),ENTITY_NAME:o.String.pipe(o.NullOr,o.optional),PROJECTOWNER_NAME:o.String.pipe(o.NullOr,o.optional),CLIENT_COLOR:o.String.pipe(o.NullOr,o.optional),PROJECT_COLOR:o.String.pipe(o.NullOr,o.optional),PROJECT_STATE:o.String.pipe(o.NullOr,o.optional),TASK_STATE:o.String.pipe(o.NullOr,o.optional),TIMESHEET_STATE:o.String.pipe(o.NullOr,o.optional),BILLING_MODE:o.String.pipe(o.NullOr,o.optional),NON_BILLABLE:o.Finite.pipe(o.NullOr,o.optional),RATE:o.Finite.pipe(o.NullOr,o.optional),VALUE:o.Finite.pipe(o.NullOr,o.optional),PROJECT_START_DT:o.String.pipe(o.NullOr,o.optional),PROJECT_END_DT:o.String.pipe(o.NullOr,o.optional),TASK_START_DT:o.String.pipe(o.NullOr,o.optional),TASK_END_DT:o.String.pipe(o.NullOr,o.optional),READONLY:o.Finite.pipe(o.NullOr,o.optional),TASK_WORKLOAD:o.Finite.pipe(o.NullOr,o.optional)});var T=class extends o.Class(`Activity`)({id:o.Finite,projectId:o.optional(o.String),folderId:o.optional(o.String),taskId:o.String.pipe(o.NullOr,o.optional),todoId:o.String.pipe(o.NullOr,o.optional),ticketId:o.String.pipe(o.NullOr,o.optional),userId:o.optional(o.String),description:o.NullOr(o.String),startDate:o.String,endDate:o.optional(o.String),durationMinutes:o.Finite,projectName:o.String.pipe(o.NullOr,o.optional),taskName:o.String.pipe(o.NullOr,o.optional),clientName:o.String.pipe(o.NullOr,o.optional),folderName:o.String.pipe(o.NullOr,o.optional),entityName:o.String.pipe(o.NullOr,o.optional),projectOwnerName:o.String.pipe(o.NullOr,o.optional),projectState:o.String.pipe(o.NullOr,o.optional),taskState:o.String.pipe(o.NullOr,o.optional),timesheetState:o.String.pipe(o.NullOr,o.optional),billingMode:o.String.pipe(o.NullOr,o.optional),nonBillable:o.Finite.pipe(o.NullOr,o.optional),rate:o.Finite.pipe(o.NullOr,o.optional),value:o.Finite.pipe(o.NullOr,o.optional),projectStartDate:o.String.pipe(o.NullOr,o.optional),projectEndDate:o.String.pipe(o.NullOr,o.optional),taskStartDate:o.String.pipe(o.NullOr,o.optional),taskEndDate:o.String.pipe(o.NullOr,o.optional),readOnly:o.Boolean.pipe(o.NullOr,o.optional),taskWorkload:o.Finite.pipe(o.NullOr,o.optional),projectColor:o.optional(o.String),clientColor:o.optional(o.String)}){};function E(e){return T.make({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 se=o.Struct({ACTIVITIES:o.Array(w)}),D=o.Struct({ID:o.Finite,DURATION:o.optional(o.Finite),DT:o.optional(o.String),TYPE:o.optional(o.Finite),DESCRIPTION:o.String.pipe(o.NullOr,o.optional),CLIENT_COLOR:o.optional(o.String),FOLDERID:o.optional(o.Union([o.String,o.Finite]))});function O(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 k=class extends e.Service()(`@2digits/tlo-mcp/services/TimeService`){};const A=n.effect(k,t.gen(function*(){let e=yield*S;return k.of({getWeek:t.fn(`TimeService.getWeek`)(function*(t,n,r=`Europe/Amsterdam`){let i=yield*e.post(`/ajax/pln/GetWeek`,{DT:O(t),CONTACTID:n,tmz:r},se);return d.map(E)(i.ACTIVITIES)}),createActivity:t.fn(`TimeService.createActivity`)(function*(t){return(yield*e.post(`/ajax/pln/SetActivity`,{ID:0,ACTION:`CREATE`,DT:O(t.startDate),DURATION:t.durationMinutes,FOLDERID:t.folderId,TASKID:t.taskId,TODOID:t.todoId,CONTACTID:t.contactId,CLIENT_COLOR:t.clientColor,DESCRIPTION:t.description},D)).ID}),updateActivity:t.fn(`TimeService.updateActivity`)(function*(t){yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`MOVE`,DT:t.startDate===void 0?void 0:O(t.startDate),DURATION:t.durationMinutes,DESCRIPTION:t.description},D)}),deleteActivity:t.fn(`TimeService.deleteActivity`)(function*(t){yield*e.post(`/ajax/pln/SetActivity`,{ID:t.id,ACTION:`DELETE`},D)})})})),j=o.Struct({ID:o.Finite,PROJECT_NAME:o.optional(o.String),NAME:o.optional(o.String),STATE:o.optional(o.String),OWNER_NAME:o.optional(o.String),START_DT:o.optional(o.String),END_DT:o.optional(o.String),BILLING_BUDGET:o.optional(o.Finite),BILLING_MODE:o.optional(o.String),BILLING_REMAINING:o.optional(o.Finite),CLIENT_NAME:o.optional(o.String),CLIENT_ID:o.optional(o.Finite),FOLDERID:o.optional(o.Finite),FOLDER_NAME:o.optional(o.String),EXTID:o.optional(o.String),CALC_TOTAL:o.optional(o.Finite),CALC_DONE:o.optional(o.Finite),CALC_PLANNED:o.optional(o.Finite)}),ce=o.Struct({Records:o.Array(j),RecordCount:o.optional(o.Finite)}),le=o.Union([j,o.Struct({Record:j})]);var M=class extends o.Class(`Project`)({id:o.Finite,name:o.String,state:o.optional(o.String),ownerName:o.optional(o.String),startDate:o.optional(o.String),endDate:o.optional(o.String),billingBudget:o.optional(o.Finite),billingMode:o.optional(o.String),billingRemaining:o.optional(o.Finite),clientName:o.optional(o.String),clientId:o.optional(o.Finite),folderId:o.optional(o.Finite),folderName:o.optional(o.String),extId:o.optional(o.String),calcTotal:o.optional(o.Finite),calcDone:o.optional(o.Finite),calcPlanned:o.optional(o.Finite)}){};function N(e){return M.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 P=o.Struct({ID:o.Finite,OWNERID:o.optional(o.Finite),OWNER_NAME:o.optional(o.String),AVATAR:o.optional(o.String),CREATED_DT:o.optional(o.String),CONTENT:o.optional(o.String),SUBCONTENT:o.optional(o.String),OBJECTTYPE:o.optional(o.String),OBJECTID:o.optional(o.Finite),OBJECTNAME:o.optional(o.String),MSGTYPE:o.optional(o.String),LIKECNT:o.optional(o.Finite),REPLYCNT:o.optional(o.Finite),OUTQUEUEID:o.optional(o.String),INTERNAL:o.optional(o.Finite)}),F=o.Array(P);var I=class extends o.Class(`Message`)({id:o.Finite,ownerId:o.optional(o.Finite),ownerName:o.optional(o.String),avatar:o.optional(o.String),createdAt:o.optional(o.String),content:o.optional(o.String),subcontent:o.optional(o.String),objectType:o.optional(o.String),objectId:o.optional(o.Finite),objectName:o.optional(o.String),messageType:o.optional(o.String),likeCount:o.optional(o.Finite),replyCount:o.optional(o.Finite),outQueueId:o.optional(o.String),internal:o.optional(o.Boolean)}){};function L(e){return I.make({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=o.Struct({ID:o.Finite,PROJECTID:o.optional(o.Finite),NAME:o.optional(o.String),STATE:o.optional(o.String),OWNER_NAME:o.optional(o.String),START_DT:o.optional(o.String),END_DT:o.optional(o.String),BUDGET:o.optional(o.Finite)}),z=o.Struct({Records:o.Array(R),RecordCount:o.optional(o.Finite)});var B=class extends o.Class(`Task`)({id:o.Finite,projectId:o.optional(o.Finite),name:o.optional(o.String),state:o.optional(o.String),ownerName:o.optional(o.String),startDate:o.optional(o.String),endDate:o.optional(o.String),budget:o.optional(o.Finite)}){};function V(e){return B.make({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=o.Struct({ID:o.Finite,WORKLOAD:o.optional(o.Finite),TOTAL:o.optional(o.Finite),REMAINING:o.optional(o.Finite),AVAIL:o.optional(o.Finite),CLIENTID:o.optional(o.Finite),PROJECTID:o.optional(o.Finite),PROJECT_START_DT:o.optional(o.String),PROJECT_END_DT:o.optional(o.String),START_DT:o.optional(o.String),END_DT:o.optional(o.String),STATE:o.optional(o.String)}),U=o.Struct({Records:o.Array(H)});var W=class extends o.Class(`TaskForUser`)({id:o.Finite,workload:o.optional(o.Finite),total:o.optional(o.Finite),remaining:o.optional(o.Finite),avail:o.optional(o.Finite),clientId:o.optional(o.Finite),projectId:o.optional(o.Finite),projectStartDate:o.optional(o.String),projectEndDate:o.optional(o.String),startDate:o.optional(o.String),endDate:o.optional(o.String),state:o.optional(o.String)}){};function ue(e){return W.make({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 G=o.Record(o.String,o.Unknown),de=o.Struct({ID:o.Finite,NAME:o.optional(o.String),BOARDLISTID:o.optional(o.Finite),BOARDID:o.optional(o.Finite),OWNERID:o.optional(o.Finite),EXTID:o.optional(o.String),STATE:o.String.pipe(o.NullOr,o.optional),DUE_DT:o.String.pipe(o.NullOr,o.optional),DESCRIPTION:o.String.pipe(o.NullOr,o.optional)}),K=o.Struct({Records:o.Array(de),RecordCount:o.optional(o.Finite)});var q=class extends o.Class(`TodoSummary`)({id:o.Finite,name:o.optional(o.String),boardListId:o.optional(o.Finite),boardId:o.optional(o.Finite),ownerId:o.optional(o.Finite),extId:o.optional(o.String),state:o.String.pipe(o.NullOr,o.optional),dueDate:o.String.pipe(o.NullOr,o.optional),description:o.String.pipe(o.NullOr,o.optional)}){};function J(e){return q.make({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.Service()(`@2digits/tlo-mcp/services/BoardService`){};function fe(e){return`${e.getFullYear()}-${(e.getMonth()+1).toString().padStart(2,`0`)}-${e.getDate().toString().padStart(2,`0`)}`}const X=n.effect(Y,t.gen(function*(){let e=yield*S;return Y.of({getProjects:t.fn(`BoardService.getProjects`)(function*(t={}){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`],r=yield*e.post(`/ajax/pln/GetProjects`,{STATE:d.join(n,`|`),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},ce);return d.map(N)(r.Records)}),getProjectDetails:t.fn(`BoardService.getProjectDetails`)(function*(t){let n=yield*e.post(`/ajax/pln/GetProjectDetails`,{ID:t.projectId},le);return N(r.value(n).pipe(r.when({Record:r.any},({Record:e})=>e),r.orElse(e=>e)))}),getMessages:t.fn(`BoardService.getMessages`)(function*(t){let n=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);return d.map(L)(n)}),getTasks:t.fn(`BoardService.getTasks`)(function*(t){let n=t.states??[`DRAFT`,`OPEN`,`CLOSED`],r=yield*e.post(`/ajax/pln/GetTasks`,{PROJECTID:t.projectId,STATE:d.join(n,`|`),COLUMNS:`ID|PROJECTID|NAME|STATE|OWNER_NAME|START_DT|END_DT|BUDGET`,limit:t.limit??100,page:t.page??1},z);return d.map(V)(r.Records)}),getTasksForUser:t.fn(`BoardService.getTasksForUser`)(function*(t){let n=yield*e.post(`/ajax/pln/GetTasksForUser`,{CONTACTID:t.contactId,START_DT:fe(t.startDate),PERIOD:t.period},U);return d.map(ue)(n.Records)}),getTodoDetail:t.fn(`BoardService.getTodoDetail`)(function*(t){return yield*e.post(`/ajax/board/GetTodoDetail`,{ID:t.id},G)}),getBoardTodos:t.fn(`BoardService.getBoardTodos`)(function*(t){let n=yield*e.post(`/ajax/board/GetTodos`,{BOARDID:t.boardId,BOARDLISTID:t.boardListId,limit:t.limit??100},K),i=d.map(J)(n.Records);return r.value(t.query).pipe(r.when(r.nonEmptyString,e=>{let t=f.toLowerCase(e);return d.filter(i,e=>e.name!==void 0&&f.includes(t)(f.toLowerCase(e.name)))}),r.orElse(()=>i))}),moveTodo:t.fn(`BoardService.moveTodo`)(function*(t){yield*e.post(`/ajax/board/MoveTodo`,{ID:t.id,BOARDID:t.boardId,BOARDLISTID:t.boardListId,SORTINDEX:t.sortIndex},o.Unknown)}),postMessage:t.fn(`BoardService.postMessage`)(function*(t){yield*e.post(`/ajax/board/ProcessMessage`,{ACTION:`ADD`,OBJECTTYPE:t.objectType,OBJECTID:t.objectId,CONTENT:t.content},o.Unknown)}),setTaskState:t.fn(`BoardService.setTaskState`)(function*(t){yield*e.post(`/ajax/pln/SetTaskState`,{PROJECTID:t.projectId,ID:t.taskId,STATE:t.state},o.Unknown)})})})),Z=t.gen(function*(){let e=yield*p.Redacted(`TLO_SESSION_TOKEN`),n=yield*p.String(`TLO_BASE_URL`).pipe(p.withDefault(`https://socialbrothers.orbit.teamleader.eu`)),r=yield*p.String(`TLO_COOKIES`).pipe(p.withDefault(``));return{baseUrl:n,sessionToken:e,cookies:yield*t.fromResult(c.setAll(c.empty,a.toEntries(c.parseHeader(r))))}}),pe=n.effect(h,Z),Q=n.mergeAll(A,X),$=C.pipe(n.provide(x.pipe(n.provide(m.layer)))),me=Q.pipe(n.provide($));export{g as C,y as D,v as E,h as O,C as S,ne as T,k as _,pe as a,E as b,I as c,W as d,G as f,J as g,N as h,Z as i,M as l,L as m,me as n,Y as o,q as p,Q as r,X as s,$ as t,B as u,A as v,_ as w,S as x,T as y};
|
package/dist/bin.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{T as e,_ as t,a as n,c as r,d as i,f as a,l as o,n as s,o as c,p as l,u,y as d}from"./TloLive-BTpDuZnK.mjs";import*as f from"effect/Effect";import*as p from"effect/Layer";import*as m from"effect/Schema";import*as h from"@effect/platform-node/NodeRuntime";import*as g from"@effect/platform-node/NodeServices";import*as _ from"effect/unstable/cli/Command";import*as v from"effect/Logger";import*as y from"effect/unstable/ai/McpProtocol";import*as b from"effect/unstable/ai/McpServer";import*as x from"effect/unstable/ai/Toolkit";import*as S from"effect/unstable/ai/Tool";const C=m.Literals([`DRAFT`,`OPEN`,`COMPLETED`,`CLOSED`]),w=m.Literals([`TODO`,`BOARD`,`PROJECT`]),T=m.DateFromString.annotate({description:`ISO 8601 date string (e.g., 2025-01-20T10:00:00Z)`}),E=S.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:m.Struct({states:C.pipe(m.Array,m.optional).annotate({description:`Filter by project states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:m.optional(m.Finite).annotate({description:`Maximum number of projects to return. Defaults to 100`}),page:m.optional(m.Finite).annotate({description:`Page number for pagination. Defaults to 1`})}),success:m.Struct({projects:m.Array(o)}),failure:e,failureMode:`return`,dependencies:[c]}),D=S.make(`get_project_details`,{description:`Get single project with full details including billing rates and folder info. Requires projectId from get_projects.`,parameters:m.Struct({projectId:m.Finite.annotate({description:`Project ID from get_projects response`})}),success:m.Struct({project:o}),failure:e,failureMode:`return`,dependencies:[c]}),O=S.make(`get_messages`,{description:`Get comments/messages on a project, board, or todo. Use to read discussion history or context about work items.`,parameters:m.Struct({objectType:w.annotate({description:`Type of object: PROJECT (for project comments), BOARD (board-level), TODO (kanban card)`}),objectId:m.Finite.annotate({description:`ID of the project, board, or todo`}),onlyComments:m.optional(m.Boolean).annotate({description:`Only return user comments (exclude system messages). Defaults to true`}),hideInternal:m.optional(m.Boolean).annotate({description:`Hide internal/private messages. Defaults to true`}),limit:m.optional(m.Finite).annotate({description:`Maximum number of messages to return. Defaults to 100`})}),success:m.Struct({messages:m.Array(r)}),failure:e,failureMode:`return`,dependencies:[c]}),k=S.make(`set_task_state`,{description:`Change task state. Typical flow: DRAFT → OPEN → COMPLETED → CLOSED. Requires both projectId and taskId from get_tasks.`,parameters:m.Struct({projectId:m.Finite.annotate({description:`Project ID containing the task (from get_projects)`}),taskId:m.Finite.annotate({description:`Task ID to update (from get_tasks)`}),state:C.annotate({description:`New state: DRAFT, OPEN, COMPLETED, or CLOSED`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),A=S.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:m.Struct({projectId:m.Finite.annotate({description:`Project ID from get_projects`}),states:C.pipe(m.Array,m.optional).annotate({description:`Filter by task states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:m.optional(m.Finite).annotate({description:`Maximum number of tasks to return. Defaults to 100`}),page:m.optional(m.Finite).annotate({description:`Page number for pagination. Defaults to 1`})}),success:m.Struct({tasks:m.Array(u)}),failure:e,failureMode:`return`,dependencies:[c]}),j=S.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:m.Struct({contactId:m.String.annotate({description:`User/contact ID to get tasks for`}),startDate:T.annotate({description:`Start date for the query (e.g., 2025-01-20T00:00:00Z)`}),period:m.Finite.annotate({description:`Number of days to include in the query`})}),success:m.Struct({tasks:m.Array(i)}),failure:e,failureMode:`return`,dependencies:[c]}),M=S.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:m.Struct({id:m.Finite.annotate({description:`Todo/card ID to retrieve`})}),success:m.Struct({todo:a}),failure:e,failureMode:`return`,dependencies:[c]}),N=S.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:m.Struct({boardId:m.Finite.annotate({description:`Board ID (from get_todo_detail TODO.BOARDID field or URL)`}),query:m.optional(m.String).annotate({description:`Filter todos by name (case-insensitive partial match)`}),boardListId:m.optional(m.Finite).annotate({description:`Filter by column ID (from BOARDLISTS in get_todo_detail)`}),limit:m.optional(m.Finite).annotate({description:`Maximum results. Defaults to 100`})}),success:m.Struct({todos:m.Array(l)}),failure:e,failureMode:`return`,dependencies:[c]}),P=S.make(`move_todo`,{description:`Move kanban card between columns. Get boardId and boardListId from get_todo_detail response (BOARDLISTS array contains column IDs).`,parameters:m.Struct({id:m.Finite.annotate({description:`Todo/card ID to move`}),boardId:m.Finite.annotate({description:`Board ID (from get_todo_detail)`}),boardListId:m.Finite.annotate({description:`Target column ID (from BOARDLISTS in get_todo_detail)`}),sortIndex:m.Finite.annotate({description:`Position within column (0 = top)`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),F=S.make(`post_message`,{description:`Add a comment to a project, board, or todo. Use to leave notes or updates on work items.`,parameters:m.Struct({objectType:w.annotate({description:`Type of object: PROJECT, BOARD, or TODO`}),objectId:m.Finite.annotate({description:`ID of the project, board, or todo to comment on`}),content:m.String.annotate({description:`Comment text to post`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),I=S.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:m.Struct({date:T.annotate({description:`Any date within target week (e.g., 2025-01-20). Week is Mon-Sun.`}),contactId:m.String.annotate({description:`User/contact ID to get activities for`}),timezone:m.optional(m.String).annotate({description:`Timezone for week boundaries. Defaults to Europe/Amsterdam`})}),success:m.Struct({activities:m.Array(d)}),failure:e,failureMode:`return`,dependencies:[t]}),L=S.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:m.Struct({folderId:m.String.annotate({description:`Folder/project ID to log time against (from get_projects or get_week_activities)`}),startDate:T.annotate({description:`Date and time of the activity (e.g., 2025-01-20T09:00:00Z). Time is for display.`}),durationMinutes:m.Finite.annotate({description:`Duration in minutes. Examples: 30, 60 (1h), 90 (1.5h), 120 (2h)`}),contactId:m.String.annotate({description:`User/contact ID who performed the work`}),taskId:m.optional(m.String).annotate({description:`Task ID to attribute time to (from get_tasks). Links time to specific deliverable.`}),todoId:m.optional(m.String).annotate({description:`Todo/kanban card ID to link this time entry to`}),description:m.optional(m.String).annotate({description:`Description of work performed`}),clientColor:m.optional(m.String).annotate({description:`Hex color code for display (e.g., #eeeeee)`})}),success:m.Struct({id:m.Finite.annotate({description:`ID of the created activity`})}),failure:e,failureMode:`return`,dependencies:[t]}),R=S.make(`update_activity`,{description:`Modify an existing time entry. Get activity ID from get_week_activities. Only specify fields you want to change.`,parameters:m.Struct({id:m.Finite.annotate({description:`Activity ID to update (from get_week_activities)`}),startDate:m.optional(T).annotate({description:`New date/time for the activity`}),durationMinutes:m.optional(m.Finite).annotate({description:`New duration in minutes`}),description:m.optional(m.String).annotate({description:`New description`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[t]}),z=S.make(`delete_activity`,{description:`Remove a time entry. Get activity ID from get_week_activities. This action cannot be undone.`,parameters:m.Struct({id:m.Finite.annotate({description:`Activity ID to delete (from get_week_activities)`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[t]}),B=x.make(E,D,O,A,j,M,N,P,F,k,I,L,R,z),V=B.toLayer({get_projects:f.fn(`TloToolkitHandlers.get_projects`)(function*(e){return{projects:yield*(yield*c).getProjects(e)}}),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)}}),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)}}),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)}}),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){return{activities:yield*(yield*t).getWeek(e.date,e.contactId,e.timezone)}}),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 H(e){return b.toolkit(B).pipe(p.provide(V),p.provide(b.layerStdio({...e,protocols:[y.v2025_06_18]})),p.provide(v.layer([v.consolePretty({stderr:!0})])))}const U=`tlo-mcp`,W=`0.0.0`,G=_.make(U,{},f.fn(`TloMcp.serve`)(function*(){return yield*H({name:U,version:W}).pipe(p.provide(s),p.provide(n),p.launch)}));f.fn(`TloMcp.run`)(function*(e){return yield*_.run(G,{version:W})})(process.argv).pipe(f.provide(g.layer),h.runMain);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-NziwhmYD.mjs";import*as f from"effect/Effect";import*as p from"effect/Layer";import*as m from"effect/Schema";import*as h from"@effect/platform-node/NodeRuntime";import*as g from"@effect/platform-node/NodeServices";import*as _ from"effect/unstable/cli/Command";import*as v from"effect/Logger";import*as y from"effect/unstable/ai/McpProtocol";import*as b from"effect/unstable/ai/McpServer";import*as x from"effect/unstable/ai/Toolkit";import*as S from"effect/unstable/ai/Tool";const C=m.Literals([`DRAFT`,`OPEN`,`COMPLETED`,`CLOSED`]),w=m.Literals([`TODO`,`BOARD`,`PROJECT`]),T=m.DateFromString.annotate({description:`ISO 8601 date string (e.g., 2025-01-20T10:00:00Z)`}),E=S.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:m.Struct({states:C.pipe(m.Array,m.optional).annotate({description:`Filter by project states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:m.optional(m.Finite).annotate({description:`Maximum number of projects to return. Defaults to 100`}),page:m.optional(m.Finite).annotate({description:`Page number for pagination. Defaults to 1`})}),success:m.Struct({projects:m.Array(o)}),failure:e,failureMode:`return`,dependencies:[c]}),D=S.make(`get_project_details`,{description:`Get single project with full details including billing rates and folder info. Requires projectId from get_projects.`,parameters:m.Struct({projectId:m.Finite.annotate({description:`Project ID from get_projects response`})}),success:m.Struct({project:o}),failure:e,failureMode:`return`,dependencies:[c]}),O=S.make(`get_messages`,{description:`Get comments/messages on a project, board, or todo. Use to read discussion history or context about work items.`,parameters:m.Struct({objectType:w.annotate({description:`Type of object: PROJECT (for project comments), BOARD (board-level), TODO (kanban card)`}),objectId:m.Finite.annotate({description:`ID of the project, board, or todo`}),onlyComments:m.optional(m.Boolean).annotate({description:`Only return user comments (exclude system messages). Defaults to true`}),hideInternal:m.optional(m.Boolean).annotate({description:`Hide internal/private messages. Defaults to true`}),limit:m.optional(m.Finite).annotate({description:`Maximum number of messages to return. Defaults to 100`})}),success:m.Struct({messages:m.Array(r)}),failure:e,failureMode:`return`,dependencies:[c]}),k=S.make(`set_task_state`,{description:`Change task state. Typical flow: DRAFT → OPEN → COMPLETED → CLOSED. Requires both projectId and taskId from get_tasks.`,parameters:m.Struct({projectId:m.Finite.annotate({description:`Project ID containing the task (from get_projects)`}),taskId:m.Finite.annotate({description:`Task ID to update (from get_tasks)`}),state:C.annotate({description:`New state: DRAFT, OPEN, COMPLETED, or CLOSED`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),A=S.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:m.Struct({projectId:m.Finite.annotate({description:`Project ID from get_projects`}),states:C.pipe(m.Array,m.optional).annotate({description:`Filter by task states: DRAFT, OPEN, COMPLETED, CLOSED. Defaults to DRAFT, OPEN, CLOSED`}),limit:m.optional(m.Finite).annotate({description:`Maximum number of tasks to return. Defaults to 100`}),page:m.optional(m.Finite).annotate({description:`Page number for pagination. Defaults to 1`})}),success:m.Struct({tasks:m.Array(u)}),failure:e,failureMode:`return`,dependencies:[c]}),j=S.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:m.Struct({contactId:m.String.annotate({description:`User/contact ID to get tasks for`}),startDate:T.annotate({description:`Start date for the query (e.g., 2025-01-20T00:00:00Z)`}),period:m.Finite.annotate({description:`Number of days to include in the query`})}),success:m.Struct({tasks:m.Array(i)}),failure:e,failureMode:`return`,dependencies:[c]}),M=S.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:m.Struct({id:m.Finite.annotate({description:`Todo/card ID to retrieve`})}),success:m.Struct({todo:a}),failure:e,failureMode:`return`,dependencies:[c]}),N=S.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:m.Struct({boardId:m.Finite.annotate({description:`Board ID (from get_todo_detail TODO.BOARDID field or URL)`}),query:m.optional(m.String).annotate({description:`Filter todos by name (case-insensitive partial match)`}),boardListId:m.optional(m.Finite).annotate({description:`Filter by column ID (from BOARDLISTS in get_todo_detail)`}),limit:m.optional(m.Finite).annotate({description:`Maximum results. Defaults to 100`})}),success:m.Struct({todos:m.Array(l)}),failure:e,failureMode:`return`,dependencies:[c]}),P=S.make(`move_todo`,{description:`Move kanban card between columns. Get boardId and boardListId from get_todo_detail response (BOARDLISTS array contains column IDs).`,parameters:m.Struct({id:m.Finite.annotate({description:`Todo/card ID to move`}),boardId:m.Finite.annotate({description:`Board ID (from get_todo_detail)`}),boardListId:m.Finite.annotate({description:`Target column ID (from BOARDLISTS in get_todo_detail)`}),sortIndex:m.Finite.annotate({description:`Position within column (0 = top)`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),F=S.make(`post_message`,{description:`Add a comment to a project, board, or todo. Use to leave notes or updates on work items.`,parameters:m.Struct({objectType:w.annotate({description:`Type of object: PROJECT, BOARD, or TODO`}),objectId:m.Finite.annotate({description:`ID of the project, board, or todo to comment on`}),content:m.String.annotate({description:`Comment text to post`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[c]}),I=S.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:m.Struct({date:T.annotate({description:`Any date within target week (e.g., 2025-01-20). Week is Mon-Sun.`}),contactId:m.String.annotate({description:`User/contact ID to get activities for`}),timezone:m.optional(m.String).annotate({description:`Timezone for week boundaries. Defaults to Europe/Amsterdam`})}),success:m.Struct({activities:m.Array(d)}),failure:e,failureMode:`return`,dependencies:[t]}),L=S.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:m.Struct({folderId:m.String.annotate({description:`Folder/project ID to log time against (from get_projects or get_week_activities)`}),startDate:T.annotate({description:`Date and time of the activity (e.g., 2025-01-20T09:00:00Z). Time is for display.`}),durationMinutes:m.Finite.annotate({description:`Duration in minutes. Examples: 30, 60 (1h), 90 (1.5h), 120 (2h)`}),contactId:m.String.annotate({description:`User/contact ID who performed the work`}),taskId:m.optional(m.String).annotate({description:`Task ID to attribute time to (from get_tasks). Links time to specific deliverable.`}),todoId:m.optional(m.String).annotate({description:`Todo/kanban card ID to link this time entry to`}),description:m.optional(m.String).annotate({description:`Description of work performed`}),clientColor:m.optional(m.String).annotate({description:`Hex color code for display (e.g., #eeeeee)`})}),success:m.Struct({id:m.Finite.annotate({description:`ID of the created activity`})}),failure:e,failureMode:`return`,dependencies:[t]}),R=S.make(`update_activity`,{description:`Modify an existing time entry. Get activity ID from get_week_activities. Only specify fields you want to change.`,parameters:m.Struct({id:m.Finite.annotate({description:`Activity ID to update (from get_week_activities)`}),startDate:m.optional(T).annotate({description:`New date/time for the activity`}),durationMinutes:m.optional(m.Finite).annotate({description:`New duration in minutes`}),description:m.optional(m.String).annotate({description:`New description`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[t]}),z=S.make(`delete_activity`,{description:`Remove a time entry. Get activity ID from get_week_activities. This action cannot be undone.`,parameters:m.Struct({id:m.Finite.annotate({description:`Activity ID to delete (from get_week_activities)`})}),success:m.Void,failure:e,failureMode:`return`,dependencies:[t]}),B=x.make(E,D,O,A,j,M,N,P,F,k,I,L,R,z),V=B.toLayer({get_projects:f.fn(`TloToolkitHandlers.get_projects`)(function*(e){return{projects:yield*(yield*c).getProjects(e)}}),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)}}),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)}}),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)}}),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){return{activities:yield*(yield*t).getWeek(e.date,e.contactId,e.timezone)}}),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)})}),H=p.merge(v.layer([v.consolePretty()]),p.succeed(v.LogToStderr,!0));function U(e){return b.toolkit(B).pipe(p.provide(V),p.provide(b.layerStdio({...e,protocols:[y.v2025_06_18]})),p.provide(H))}const W=`tlo-mcp`,G=`0.0.0`,K=_.make(W,{},f.fn(`TloMcp.serve`)(function*(){return yield*U({name:W,version:G}).pipe(p.provide(s),p.provide(n),p.launch)}));f.fn(`TloMcp.run`)(function*(e){return yield*_.run(K,{version:G})})(process.argv).pipe(f.provide(g.layer),h.runMain);export{};
|
package/dist/index.d.mts
CHANGED
|
@@ -14,7 +14,7 @@ interface TloConfigShape {
|
|
|
14
14
|
readonly cookies: Cookies.Cookies;
|
|
15
15
|
}
|
|
16
16
|
declare const TloConfig_base: Context.ServiceClass<TloConfig, "@2digits/tlo-mcp/services/TloConfig", TloConfigShape>;
|
|
17
|
-
declare class TloConfig extends TloConfig_base {}
|
|
17
|
+
export declare class TloConfig extends TloConfig_base {}
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/schemas/errors.d.ts
|
|
20
20
|
declare const TloApiError_base: Schema.Class<TloApiError, Schema.TaggedStruct<"TloApiError", {
|
|
@@ -25,14 +25,14 @@ declare const TloApiError_base: Schema.Class<TloApiError, Schema.TaggedStruct<"T
|
|
|
25
25
|
/**
|
|
26
26
|
* Error returned when the TLO API indicates failure. This occurs when success: false in the response envelope.
|
|
27
27
|
*/
|
|
28
|
-
declare class TloApiError extends TloApiError_base {}
|
|
28
|
+
export declare class TloApiError extends TloApiError_base {}
|
|
29
29
|
declare const TloAuthError_base: Schema.Class<TloAuthError, Schema.TaggedStruct<"TloAuthError", {
|
|
30
30
|
readonly message: Schema.String;
|
|
31
31
|
}>, import("effect/Cause").YieldableError>;
|
|
32
32
|
/**
|
|
33
33
|
* Error for authentication failures. Session token expired or invalid credentials.
|
|
34
34
|
*/
|
|
35
|
-
declare class TloAuthError extends TloAuthError_base {}
|
|
35
|
+
export declare class TloAuthError extends TloAuthError_base {}
|
|
36
36
|
declare const TloNetworkError_base: Schema.Class<TloNetworkError, Schema.TaggedStruct<"TloNetworkError", {
|
|
37
37
|
readonly message: Schema.String;
|
|
38
38
|
readonly cause: Schema.optional<Schema.Unknown>;
|
|
@@ -41,7 +41,7 @@ declare const TloNetworkError_base: Schema.Class<TloNetworkError, Schema.TaggedS
|
|
|
41
41
|
/**
|
|
42
42
|
* Error for network/transport failures. Connection refused, timeout, etc.
|
|
43
43
|
*/
|
|
44
|
-
declare class TloNetworkError extends TloNetworkError_base {}
|
|
44
|
+
export declare class TloNetworkError extends TloNetworkError_base {}
|
|
45
45
|
declare const TloParseError_base: Schema.Class<TloParseError, Schema.TaggedStruct<"TloParseError", {
|
|
46
46
|
readonly message: Schema.String;
|
|
47
47
|
readonly cause: Schema.optional<Schema.Unknown>;
|
|
@@ -49,7 +49,7 @@ declare const TloParseError_base: Schema.Class<TloParseError, Schema.TaggedStruc
|
|
|
49
49
|
/**
|
|
50
50
|
* Error when response parsing fails. Unexpected response format from TLO.
|
|
51
51
|
*/
|
|
52
|
-
declare class TloParseError extends TloParseError_base {}
|
|
52
|
+
export declare class TloParseError extends TloParseError_base {}
|
|
53
53
|
type TloError = TloApiError | TloAuthError | TloNetworkError | TloParseError;
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/services/TloHttpClient.d.ts
|
|
@@ -64,8 +64,8 @@ interface TeamLeaderClientShape {
|
|
|
64
64
|
readonly post: <TSchema extends Schema.Constraint>(path: string, body: Record<string, string | number | boolean | undefined>, schema: TSchema) => Effect.Effect<TSchema['Type'], TloError, TSchema['DecodingServices']>;
|
|
65
65
|
}
|
|
66
66
|
declare const TeamLeaderClient_base: Context.ServiceClass<TeamLeaderClient, "@2digits/tlo-mcp/services/TeamLeaderClient", TeamLeaderClientShape>;
|
|
67
|
-
declare class TeamLeaderClient extends TeamLeaderClient_base {}
|
|
68
|
-
declare const TeamLeaderClientLive: Layer.Layer<TeamLeaderClient, never, TloConfig | TloHttpClient>;
|
|
67
|
+
export declare class TeamLeaderClient extends TeamLeaderClient_base {}
|
|
68
|
+
export declare const TeamLeaderClientLive: Layer.Layer<TeamLeaderClient, never, TloConfig | TloHttpClient>;
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region src/schemas/time.d.ts
|
|
71
71
|
/**
|
|
@@ -141,9 +141,11 @@ declare const Activity_base: Schema.Class<Activity, Schema.Struct<{
|
|
|
141
141
|
readonly taskWorkload: Schema.optional<Schema.NullOr<Schema.Finite>>;
|
|
142
142
|
readonly projectColor: Schema.optional<Schema.String>;
|
|
143
143
|
readonly clientColor: Schema.optional<Schema.String>;
|
|
144
|
-
}>, {
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
}>, {
|
|
145
|
+
readonly brand: unique symbol;
|
|
146
|
+
}>;
|
|
147
|
+
export declare class Activity extends Activity_base {}
|
|
148
|
+
export declare function activityFromRaw(raw: ActivityRaw): Activity;
|
|
147
149
|
declare const GetWeekResponse: Schema.Struct<{
|
|
148
150
|
readonly ACTIVITIES: Schema.$Array<Schema.Struct<{
|
|
149
151
|
readonly ID: Schema.Finite;
|
|
@@ -221,8 +223,8 @@ interface TimeServiceShape {
|
|
|
221
223
|
readonly deleteActivity: (params: DeleteActivityParams) => Effect.Effect<void, TloError>;
|
|
222
224
|
}
|
|
223
225
|
declare const TimeService_base: Context.ServiceClass<TimeService, "@2digits/tlo-mcp/services/TimeService", TimeServiceShape>;
|
|
224
|
-
declare class TimeService extends TimeService_base {}
|
|
225
|
-
declare const TimeServiceLive: Layer.Layer<TimeService, never, TeamLeaderClient>;
|
|
226
|
+
export declare class TimeService extends TimeService_base {}
|
|
227
|
+
export declare const TimeServiceLive: Layer.Layer<TimeService, never, TeamLeaderClient>;
|
|
226
228
|
//#endregion
|
|
227
229
|
//#region src/schemas/board.d.ts
|
|
228
230
|
type ProjectRaw = typeof ProjectRaw.Type;
|
|
@@ -264,9 +266,11 @@ declare const Project_base: Schema.Class<Project, Schema.Struct<{
|
|
|
264
266
|
readonly calcTotal: Schema.optional<Schema.Finite>;
|
|
265
267
|
readonly calcDone: Schema.optional<Schema.Finite>;
|
|
266
268
|
readonly calcPlanned: Schema.optional<Schema.Finite>;
|
|
267
|
-
}>, {
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
}>, {
|
|
270
|
+
readonly brand: unique symbol;
|
|
271
|
+
}>;
|
|
272
|
+
export declare class Project extends Project_base {}
|
|
273
|
+
export declare function projectFromRaw(raw: ProjectRaw): Project;
|
|
270
274
|
type MessageRaw = typeof MessageRaw.Type;
|
|
271
275
|
declare const MessageRaw: Schema.Struct<{
|
|
272
276
|
readonly ID: Schema.Finite;
|
|
@@ -301,9 +305,11 @@ declare const Message_base: Schema.Class<Message, Schema.Struct<{
|
|
|
301
305
|
readonly replyCount: Schema.optional<Schema.Finite>;
|
|
302
306
|
readonly outQueueId: Schema.optional<Schema.String>;
|
|
303
307
|
readonly internal: Schema.optional<Schema.Boolean>;
|
|
304
|
-
}>, {
|
|
305
|
-
|
|
306
|
-
|
|
308
|
+
}>, {
|
|
309
|
+
readonly brand: unique symbol;
|
|
310
|
+
}>;
|
|
311
|
+
export declare class Message extends Message_base {}
|
|
312
|
+
export declare function messageFromRaw(raw: MessageRaw): Message;
|
|
307
313
|
type TaskState = 'OPEN' | 'COMPLETED' | 'DRAFT' | 'CLOSED';
|
|
308
314
|
type TaskRaw = typeof TaskRaw.Type;
|
|
309
315
|
declare const TaskRaw: Schema.Struct<{
|
|
@@ -325,8 +331,10 @@ declare const Task_base: Schema.Class<Task, Schema.Struct<{
|
|
|
325
331
|
readonly startDate: Schema.optional<Schema.String>;
|
|
326
332
|
readonly endDate: Schema.optional<Schema.String>;
|
|
327
333
|
readonly budget: Schema.optional<Schema.Finite>;
|
|
328
|
-
}>, {
|
|
329
|
-
|
|
334
|
+
}>, {
|
|
335
|
+
readonly brand: unique symbol;
|
|
336
|
+
}>;
|
|
337
|
+
export declare class Task extends Task_base {}
|
|
330
338
|
interface SetTaskStateParams {
|
|
331
339
|
readonly projectId: number;
|
|
332
340
|
readonly taskId: number;
|
|
@@ -372,10 +380,12 @@ declare const TaskForUser_base: Schema.Class<TaskForUser, Schema.Struct<{
|
|
|
372
380
|
readonly startDate: Schema.optional<Schema.String>;
|
|
373
381
|
readonly endDate: Schema.optional<Schema.String>;
|
|
374
382
|
readonly state: Schema.optional<Schema.String>;
|
|
375
|
-
}>, {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
declare
|
|
383
|
+
}>, {
|
|
384
|
+
readonly brand: unique symbol;
|
|
385
|
+
}>;
|
|
386
|
+
export declare class TaskForUser extends TaskForUser_base {}
|
|
387
|
+
export type TodoDetail = typeof TodoDetail.Type;
|
|
388
|
+
export declare const TodoDetail: Schema.$Record<Schema.String, Schema.Unknown>;
|
|
379
389
|
type TodoSummaryRaw = typeof TodoSummaryRaw.Type;
|
|
380
390
|
declare const TodoSummaryRaw: Schema.Struct<{
|
|
381
391
|
readonly ID: Schema.Finite;
|
|
@@ -398,9 +408,11 @@ declare const TodoSummary_base: Schema.Class<TodoSummary, Schema.Struct<{
|
|
|
398
408
|
readonly state: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
399
409
|
readonly dueDate: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
400
410
|
readonly description: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
401
|
-
}>, {
|
|
402
|
-
|
|
403
|
-
|
|
411
|
+
}>, {
|
|
412
|
+
readonly brand: unique symbol;
|
|
413
|
+
}>;
|
|
414
|
+
export declare class TodoSummary extends TodoSummary_base {}
|
|
415
|
+
export declare function todoSummaryFromRaw(raw: TodoSummaryRaw): TodoSummary;
|
|
404
416
|
interface GetBoardTodosParams {
|
|
405
417
|
readonly boardId: number;
|
|
406
418
|
readonly boardListId?: number;
|
|
@@ -450,28 +462,28 @@ interface BoardServiceShape {
|
|
|
450
462
|
readonly setTaskState: (params: SetTaskStateParams) => Effect.Effect<void, TloError>;
|
|
451
463
|
}
|
|
452
464
|
declare const BoardService_base: Context.ServiceClass<BoardService, "@2digits/tlo-mcp/services/BoardService", BoardServiceShape>;
|
|
453
|
-
declare class BoardService extends BoardService_base {}
|
|
454
|
-
declare const BoardServiceLive: Layer.Layer<BoardService, never, TeamLeaderClient>;
|
|
465
|
+
export declare class BoardService extends BoardService_base {}
|
|
466
|
+
export declare const BoardServiceLive: Layer.Layer<BoardService, never, TeamLeaderClient>;
|
|
455
467
|
//#endregion
|
|
456
468
|
//#region src/layers/TloConfigLive.d.ts
|
|
457
|
-
declare const TloConfigFromEnv: Effect.Effect<{
|
|
469
|
+
export declare const TloConfigFromEnv: Effect.Effect<{
|
|
458
470
|
baseUrl: string;
|
|
459
471
|
sessionToken: import("effect/Redacted").Redacted<string>;
|
|
460
472
|
cookies: Cookies.Cookies;
|
|
461
473
|
}, Config.ConfigError | Cookies.CookiesError, never>;
|
|
462
|
-
declare const TloConfigLive: Layer.Layer<TloConfig, Config.ConfigError | Cookies.CookiesError, never>;
|
|
474
|
+
export declare const TloConfigLive: Layer.Layer<TloConfig, Config.ConfigError | Cookies.CookiesError, never>;
|
|
463
475
|
//#endregion
|
|
464
476
|
//#region src/layers/TloLive.d.ts
|
|
465
|
-
declare const TloServicesLive: Layer.Layer<BoardService | TimeService, never, TeamLeaderClient>;
|
|
466
|
-
declare const TloClientLive: Layer.Layer<TeamLeaderClient, never, TloConfig>;
|
|
467
|
-
declare const TloLive: Layer.Layer<BoardService | TimeService, never, TloConfig>;
|
|
477
|
+
export declare const TloServicesLive: Layer.Layer<BoardService | TimeService, never, TeamLeaderClient>;
|
|
478
|
+
export declare const TloClientLive: Layer.Layer<TeamLeaderClient, never, TloConfig>;
|
|
479
|
+
export declare const TloLive: Layer.Layer<BoardService | TimeService, never, TloConfig>;
|
|
468
480
|
//#endregion
|
|
469
481
|
//#region src/schemas/common.d.ts
|
|
470
482
|
/**
|
|
471
483
|
* TeamLeader Orbit uses YYYYMMDDHHMMSS format for dates. Example: "20251117143000" = Nov 17, 2025 14:30:00.
|
|
472
484
|
*/
|
|
473
|
-
declare const TloDateString: Schema.brand<Schema.String, "TloDateString">;
|
|
474
|
-
type TloDateString = typeof TloDateString.Type;
|
|
485
|
+
export declare const TloDateString: Schema.brand<Schema.String, "TloDateString">;
|
|
486
|
+
export type TloDateString = typeof TloDateString.Type;
|
|
475
487
|
/**
|
|
476
488
|
* Format Date to YYYYMMDDHHMMSS string.
|
|
477
489
|
*
|
|
@@ -481,25 +493,25 @@ declare function formatTloDate(date: Date): TloDateString;
|
|
|
481
493
|
/**
|
|
482
494
|
* Transform between TLO date strings and JavaScript Date objects.
|
|
483
495
|
*/
|
|
484
|
-
declare const TloDate: Schema.decodeTo<Schema.Date, Schema.brand<Schema.String, "TloDateString">, never, never>;
|
|
485
|
-
type TloDate = typeof TloDate.Type;
|
|
496
|
+
export declare const TloDate: Schema.decodeTo<Schema.Date, Schema.brand<Schema.String, "TloDateString">, never, never>;
|
|
497
|
+
export type TloDate = typeof TloDate.Type;
|
|
486
498
|
/**
|
|
487
499
|
* TLO entity IDs are numeric strings.
|
|
488
500
|
*/
|
|
489
|
-
type TloId = string & Brand.Brand<'TloId'>;
|
|
490
|
-
declare const TloId: Brand.Constructor<TloId>;
|
|
491
|
-
declare const TloIdSchema: Schema.brand<Schema.String, "TloId">;
|
|
501
|
+
export type TloId = string & Brand.Brand<'TloId'>;
|
|
502
|
+
export declare const TloId: Brand.Constructor<TloId>;
|
|
503
|
+
export declare const TloIdSchema: Schema.brand<Schema.String, "TloId">;
|
|
492
504
|
/**
|
|
493
505
|
* Standard TLO API response envelope schema. Note: Most endpoints return data directly without this wrapper. Kept for
|
|
494
506
|
* potential use with endpoints that do use the envelope pattern.
|
|
495
507
|
*
|
|
496
508
|
* @param dataSchema - Data schema to wrap.
|
|
497
509
|
*/
|
|
498
|
-
declare function TloResponse<T>(dataSchema: Schema.Schema<T>): Schema.Struct<{
|
|
510
|
+
export declare function TloResponse<T>(dataSchema: Schema.Schema<T>): Schema.Struct<{
|
|
499
511
|
readonly success: Schema.Boolean;
|
|
500
512
|
readonly ID: Schema.optional<Schema.Finite>;
|
|
501
513
|
readonly OBJ: Schema.Schema<T>;
|
|
502
514
|
readonly err: Schema.optional<Schema.String>;
|
|
503
515
|
}>;
|
|
504
516
|
//#endregion
|
|
505
|
-
export {
|
|
517
|
+
export { type ActivityRaw, type BoardServiceShape, type CreateActivityParams, type DeleteActivityParams, type GetBoardTodosParams, type GetMessagesParams, type GetProjectDetailsParams, type GetProjectsParams, type GetTasksForUserParams, type GetTodoDetailParams, type GetWeekResponse, type MessageRaw, type MoveTodoParams, type PostMessageParams, type ProjectRaw, type SetActivityResponse, type SetTaskStateParams, type TaskForUserRaw, type TaskRaw, type TaskState, type TeamLeaderClientShape, type TimeServiceShape, type TloConfigShape, type TloError, type UpdateActivityParams, formatTloDate };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,D as t,E as n,O as r,S as i,_ as a,a as o,b as s,c,d as l,f as u,g as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,v as C,w,x as T,y as E}from"./TloLive-
|
|
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-NziwhmYD.mjs";import*as D from"effect/Schema";import*as O from"effect/Brand";import*as k from"effect/DateTime";import*as A from"effect/SchemaTransformation";const j=D.String.pipe(D.check(D.isPattern(/^\d{14}$/)),D.brand(`TloDateString`));function M(e){let t=Number.parseInt(e.slice(0,4),10),n=Number.parseInt(e.slice(4,6),10),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 k.makeZonedUnsafe({year:t<=99?t+1900:t,month:n,day:r,hour:i,minute:a,second:o},{timeZone:k.zoneMakeLocal(),adjustForTimeZone:!0}).pipe(k.toDateUtc)}function N(e){let t=e.getFullYear().toString().padStart(4,`0`),n=(e.getMonth()+1).toString().padStart(2,`0`),r=e.getDate().toString().padStart(2,`0`),i=e.getHours().toString().padStart(2,`0`),a=e.getMinutes().toString().padStart(2,`0`),o=e.getSeconds().toString().padStart(2,`0`);return j.make(`${t}${n}${r}${i}${a}${o}`)}const P=j.pipe(D.decodeTo(D.Date,A.transform({decode:M,encode:N}))),F=O.nominal(),I=D.String.pipe(D.fromBrand(`TloId`,F));function L(e){return D.Struct({success:D.Boolean,ID:D.optional(D.Finite),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,P as TloDate,j as TloDateString,F as TloId,I as TloIdSchema,g as TloLive,n as TloNetworkError,t as TloParseError,L as TloResponse,y as TloServicesLive,u as TodoDetail,v as TodoSummary,s as activityFromRaw,N as formatTloDate,h as messageFromRaw,f as projectFromRaw,d as todoSummaryFromRaw};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2digits/tlo-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/2digits-agency/configs.git",
|
|
@@ -24,24 +24,24 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@effect/platform-node": "4.0.0-rc.
|
|
28
|
-
"effect": "4.0.0-rc.
|
|
27
|
+
"@effect/platform-node": "4.0.0-rc.115",
|
|
28
|
+
"effect": "4.0.0-rc.115"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@2digits/tsconfig": "0.8.
|
|
31
|
+
"@2digits/tsconfig": "0.8.8",
|
|
32
32
|
"@arethetypeswrong/core": "0.18.5",
|
|
33
|
-
"@effect/vitest": "4.0.0-rc.
|
|
34
|
-
"@typescript/native": "npm:typescript@7.0.2",
|
|
33
|
+
"@effect/vitest": "4.0.0-rc.115",
|
|
35
34
|
"publint": "0.3.24",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
35
|
+
"typescript": "7.0.2",
|
|
36
|
+
"vite-plus": "0.3.2",
|
|
37
|
+
"vitest": "5.0.0"
|
|
38
38
|
},
|
|
39
39
|
"public": true,
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "vp pack --minify --config-loader unconfig",
|
|
42
42
|
"dev": "vp pack --watch --config-loader unconfig",
|
|
43
|
-
"test": "
|
|
44
|
-
"test:watch": "
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"test:watch": "vitest",
|
|
45
45
|
"types": "tsc --noEmit"
|
|
46
46
|
}
|
|
47
47
|
}
|