MCPcopy Create free account
hub / github.com/ZenNotes/zennotes / toggleTask

Function toggleTask

apps/desktop/src/mcp/vault-ops.ts:1018–1086  ·  view source on GitHub ↗
(root: string, taskId: string)

Source from the content-addressed store, hash-verified

1016
1017/** Toggle a specific task identified by "<path>#<taskIndex>". */
1018export async function toggleTask(root: string, taskId: string): Promise<VaultTask | null> {
1019 const hashIdx = taskId.lastIndexOf('#')
1020 if (hashIdx < 0) throw new Error(`Malformed task id: ${taskId}`)
1021 const rel = taskId.slice(0, hashIdx)
1022 const indexStr = taskId.slice(hashIdx + 1)
1023 const targetIndex = Number.parseInt(indexStr, 10)
1024 if (!Number.isInteger(targetIndex) || targetIndex < 0) {
1025 throw new Error(`Malformed task index in id: ${taskId}`)
1026 }
1027 const abs = resolveSafe(root, rel)
1028 const body = await fs.readFile(abs, 'utf8')
1029 const normalized = body.replace(/\r\n/g, '\n')
1030 const lines = normalized.split('\n')
1031 let taskIndex = 0
1032 let inFence = false
1033 let fenceMarker: string | null = null
1034 let lineNumber = -1
1035 for (let i = 0; i < lines.length; i++) {
1036 const line = lines[i]
1037 const fenceMatch = line.match(FENCE_LINE_RE)
1038 if (fenceMatch) {
1039 const marker = fenceMatch[2]
1040 if (!inFence) {
1041 inFence = true
1042 fenceMarker = marker
1043 } else if (marker === fenceMarker) {
1044 inFence = false
1045 fenceMarker = null
1046 }
1047 continue
1048 }
1049 if (inFence) continue
1050 if (!TASK_LINE_RE.test(line)) continue
1051 if (taskIndex === targetIndex) {
1052 lineNumber = i
1053 break
1054 }
1055 taskIndex += 1
1056 }
1057 if (lineNumber < 0) return null
1058 const original = lines[lineNumber]
1059 const toggled = original.replace(
1060 TASK_LINE_RE,
1061 (_m, ch: string, tail: string) => {
1062 const fullMatch = original.match(TASK_LINE_RE)!
1063 const bracketIdx = original.indexOf('[' + ch + ']')
1064 const next = ch === ' ' ? 'x' : ' '
1065 // Preserve the full prefix (list marker, whitespace) by splicing only
1066 // the single character inside the brackets.
1067 if (bracketIdx >= 0) {
1068 return (
1069 original.slice(0, bracketIdx + 1) + next + original.slice(bracketIdx + 2)
1070 )
1071 }
1072 return fullMatch[0]
1073 }
1074 )
1075 lines[lineNumber] = toggled

Callers 2

cmdTaskToggleFunction · 0.85
server.tsFile · 0.85

Calls 4

resolveSafeFunction · 0.70
folderOfFunction · 0.70
parseTasksFromBodyFunction · 0.70
toPosixFunction · 0.70

Tested by

no test coverage detected