"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("../../shared-types-B8BH5zz1.cjs"),S=require("../../file-lock-DtSfMcef.cjs");function I(i){const t=i.match(/^(\d+(?:\.\d+)*)\s/)||i.match(/^(\d+(?:\.\d+)*)\./);return t?t[1]:null}function d(i){return i.split(".").length}function f(i){const t=i.match(/^(\s*)([-*+])\s+\[([ xX\-~])\](\\?\*?)\s+(.+)$/);if(!t)return{isTask:!1,indent:0,status:c.TaskStatus.NotStarted,text:"",taskNumber:null,isOptional:!1};const s=t[3].toLowerCase(),e=t[4],o=e==="*"||e==="\\*";let a;s==="x"?a=c.TaskStatus.Completed:s==="-"?a=c.TaskStatus.InProgress:s==="~"?a=c.TaskStatus.Queued:a=c.TaskStatus.NotStarted;const n=t[5];return{isTask:!0,indent:t[1].length,status:a,text:n,taskNumber:I(n),isOptional:o}}function m(i,t,s){const e=f(i[t]);if(!e.isTask)throw new Error(`Invalid task format at line ${t}: ${i[t]}`);const o={id:e.taskNumber??e.text,text:e.text,startLine:t,endLine:t+1,markdownStatus:e.status,content:"",subTasks:[],level:s,isOptional:e.isOptional};let a=t+1;const n=[];let u=-1;for(;a<i.length;){const r=i[a],k=f(r),l=r.match(/^(\s*)/)?.[1].length||0;if(e.taskNumber){if(k.isTask)break}else{if(r.trim()!==""&&l<=e.indent)break;if(k.isTask){const{task:h,nextIndex:x}=m(i,a,s+1);o.subTasks.push(h),a=x;continue}}if(r.trim()!==""){const h=Math.min(l,e.indent+2);n.push(r.substring(h)),u=n.length-1}else u!==-1&&n.push("");a++}for(;n.length>0&&n[n.length-1]==="";)n.pop();return n.length>0&&(o.content=n.join(`
`)),o.endLine=a,{task:o,nextIndex:a}}function N(i){const t=[],s=new Map,e=new Set,o=i.filter(a=>a.taskInfo.taskNumber!==null);o.sort((a,n)=>{const u=d(a.taskInfo.taskNumber),r=d(n.taskInfo.taskNumber);return u!==r?u-r:a.taskInfo.taskNumber.localeCompare(n.taskInfo.taskNumber,void 0,{numeric:!0})});for(const{task:a,taskInfo:n}of o){const u=n.taskNumber,r=d(u);if(a.level=r,a.subTasks=[],s.set(u,a),r>1){const k=u.substring(0,u.lastIndexOf(".")),l=s.get(k);l?l.subTasks.push(a):e.add(u)}}for(const{task:a,taskInfo:n}of i)n.taskNumber!==null?(d(n.taskNumber)===1||e.has(n.taskNumber))&&t.push(a):t.push(a);return t}function b(i){const s=i.replace(/\r\n/g,`
`).replace(/\r/g,`
`).split(`
`);let e=0;const o=[];for(;e<s.length;){const n=f(s[e]);if(n.isTask){const{task:u,nextIndex:r}=m(s,e,1);u.id=n.taskNumber??n.text,o.push({task:u,lineIndex:e,taskInfo:n}),e=r}else e++}return o.some(n=>n.taskInfo.taskNumber!==null)?N(o):o.map(({task:n})=>n)}const P=/(?:_|\*\*)Property(?:\s+\d+)?(?::\s*.+)?(?:_|\*\*)/i;function T(){return{pbtResults:{},executionHistory:{}}}function p(i){return i.replace(/\.md$/,".meta.json")}function y(i){switch(i){case c.TaskStatus.Completed:return"x";case c.TaskStatus.InProgress:return"-";case c.TaskStatus.Queued:return"~";default:return" "}}function w(i,t){for(const s of i){if(s.id===t)return s;if(s.subTasks.length>0){const e=w(s.subTasks,t);if(e)return e}}}function g(i){const t=[];for(const s of i.subTasks)!s.isOptional&&s.markdownStatus!==c.TaskStatus.Completed&&t.push(s),t.push(...g(s));return t}class v{constructor(t){this.fs=t}async loadMetadata(t){const s=p(t);try{if(!await this.fs.exists(s))return T();const{content:o}=await this.fs.readTextFile({path:s});return JSON.parse(o)}catch{return T()}}async saveMetadata(t,s){const e=p(t);await this.fs.writeTextFile({path:e,content:JSON.stringify(s,null,2)})}async readAndParseTasks(t){const{content:s}=await this.fs.readTextFile({path:t});return{content:s,tasks:b(s)}}async resolveTask(t,s){const{tasks:e}=await this.readAndParseTasks(t),o=w(e,s);if(!o)throw new Error(`Task "${s}" not found in ${t}`);return{task:o,tasks:e}}async updateTaskStatus(t){const s=t.tasksPath.fsPath,e=t.status;await S.FileLock.getInstance().withLock(t.tasksPath,async()=>{const{task:n}=await this.resolveTask(s,t.taskId),{content:u}=await this.fs.readTextFile({path:s}),r=u.replace(/\r\n/g,`
`).split(`
`),k=r[n.startLine].replace(/\[([ xX\-~])\]/,`[${y(e)}]`);r[n.startLine]=k,await this.fs.writeTextFile({path:s,content:r.join(`
`)})});const o=await this.loadMetadata(s),a=o.executionHistory[t.taskId]??[];a.push({executionId:t.executionId,chatSessionId:t.chatSessionId,timestamp:Date.now()}),o.executionHistory[t.taskId]=a,await this.saveMetadata(s,o)}async validateTaskStatusChange(t){const s=t.newStatus;let e,o;try{const n=await this.resolveTask(t.tasksPath.fsPath,t.taskId);e=n.task,o=n.tasks}catch{return{valid:!1,reason:`Task "${t.taskId}" not found`}}if(s===c.TaskStatus.Completed){const n=g(e);if(n.length>0)return{valid:!1,reason:`Cannot complete task with incomplete non-optional subtasks: ${n.map(r=>`"${r.text}"`).join(", ")}`}}const a=[];return s===c.TaskStatus.InProgress&&a.push(...this.checkTaskOrder(o,e)),{valid:!0,warnings:a.length>0?a:void 0}}async getTaskMetadata(t){const{task:s}=await this.resolveTask(t.tasksPath.fsPath,t.taskId);return{isLeaf:s.subTasks.length===0}}async updatePBTStatus(t){const s=t.tasksPath.fsPath,{task:e}=await this.resolveTask(s,t.taskId);if(!P.test(e.content))throw new Error(`Task "${t.taskId}" is not a PBT task`);const o=await this.loadMetadata(s);o.pbtResults[t.taskId]={status:t.status,failingExample:t.failingExample,lastRunTimestamp:Date.now()},await this.saveMetadata(s,o)}async getTask(t){try{const{task:s}=await this.resolveTask(t.tasksPath.fsPath,t.taskId);return{text:s.text,startLine:s.startLine,endLine:s.endLine}}catch{return null}}checkTaskOrder(t,s){const e=[],o=this.findSiblings(t,s);for(const a of o){if(a.id===s.id)break;a.markdownStatus!==c.TaskStatus.Completed&&!a.isOptional&&e.push(`Task "${a.text}" has not been completed yet and appears before this task.`)}return e}findSiblings(t,s){for(const e of t){if(e.id===s.id)return t;if(e.subTasks.length>0){const o=this.findSiblings(e.subTasks,s);if(o.length>0)return o}}return[]}}exports.NodeTaskService=v;exports.parseMarkdownTasks=b;
//# sourceMappingURL=index.cjs.map
