@agimon-ai/doompi-task 0.0.1-alpha.13 → 0.0.1-alpha.15
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/README.md +21 -12
- package/dist/commands/task/promptGuidelines.cjs +1 -1
- package/dist/commands/task/promptGuidelines.cjs.map +1 -1
- package/dist/commands/task/promptGuidelines.mjs +1 -1
- package/dist/commands/task/promptGuidelines.mjs.map +1 -1
- package/dist/commands/task/responseEnvelope.cjs +6 -5
- package/dist/commands/task/responseEnvelope.cjs.map +1 -1
- package/dist/commands/task/responseEnvelope.d.cts +14 -2
- package/dist/commands/task/responseEnvelope.d.cts.map +1 -1
- package/dist/commands/task/responseEnvelope.d.mts +14 -2
- package/dist/commands/task/responseEnvelope.d.mts.map +1 -1
- package/dist/commands/task/responseEnvelope.mjs +6 -5
- package/dist/commands/task/responseEnvelope.mjs.map +1 -1
- package/dist/commands/task/taskTool.cjs +2 -2
- package/dist/commands/task/taskTool.cjs.map +1 -1
- package/dist/commands/task/taskTool.d.cts.map +1 -1
- package/dist/commands/task/taskTool.d.mts.map +1 -1
- package/dist/commands/task/taskTool.mjs +2 -2
- package/dist/commands/task/taskTool.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +1 -1
- package/dist/schemas/task.cjs +1 -1
- package/dist/schemas/task.cjs.map +1 -1
- package/dist/schemas/task.d.cts +28 -11
- package/dist/schemas/task.d.cts.map +1 -1
- package/dist/schemas/task.d.mts +28 -11
- package/dist/schemas/task.d.mts.map +1 -1
- package/dist/schemas/task.mjs +1 -1
- package/dist/schemas/task.mjs.map +1 -1
- package/dist/services/store/types.cjs.map +1 -1
- package/dist/services/store/types.d.cts +22 -10
- package/dist/services/store/types.d.cts.map +1 -1
- package/dist/services/store/types.d.mts +22 -10
- package/dist/services/store/types.d.mts.map +1 -1
- package/dist/services/store/types.mjs.map +1 -1
- package/dist/store/types.d.cts +2 -2
- package/dist/store/types.d.mts +2 -2
- package/dist/tool/responseEnvelope.cjs +1 -1
- package/dist/tool/responseEnvelope.d.cts +2 -2
- package/dist/tool/responseEnvelope.d.mts +2 -2
- package/dist/tool/responseEnvelope.mjs +1 -1
- package/dist/tool/schema.cjs +1 -1
- package/dist/tool/schema.d.cts +2 -2
- package/dist/tool/schema.d.mts +2 -2
- package/dist/tool/schema.mjs +1 -1
- package/dist/tui/format.cjs +3 -3
- package/dist/tui/format.cjs.map +1 -1
- package/dist/tui/format.d.cts.map +1 -1
- package/dist/tui/format.d.mts.map +1 -1
- package/dist/tui/format.mjs +3 -3
- package/dist/tui/format.mjs.map +1 -1
- package/dist/tui/selectors.cjs +1 -1
- package/dist/tui/selectors.cjs.map +1 -1
- package/dist/tui/selectors.d.cts +7 -0
- package/dist/tui/selectors.d.cts.map +1 -1
- package/dist/tui/selectors.d.mts +7 -0
- package/dist/tui/selectors.d.mts.map +1 -1
- package/dist/tui/selectors.mjs +1 -1
- package/dist/tui/selectors.mjs.map +1 -1
- package/package.json +5 -5
package/dist/tui/selectors.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return e.filter(e=>e.status!==`deleted`)}function t(e){let t=new Map;for(let n of e)t.has(n.id)||t.set(n.id,n.status);return t}function n(e,t){return e.blockedBy?.some(e=>{let n=t.get(e);return n!==void 0&&n!==`completed`&&n!==`deleted`})??!1}function r(e){let r=t(e),i=[],a={total:0,completed:0,inProgress:0,pending:0,failed:0,blocked:0},o={inProgress:[],blocked:[],pending:[],completed:[],failed:[]},s=!1;for(let t of e)if(t.status!==`deleted`)switch(i.push(t),a.total+=1,s||=!!t.blockedBy?.length,t.status){case`in_progress`:a.inProgress+=1,o.inProgress.push(t);break;case`pending`:a.pending+=1,n(t,r)?(a.blocked+=1,o.blocked.push(t)):o.pending.push(t);break;case`failed`:a.failed+=1,o.failed.push(t);break;case`completed`:a.completed+=1,o.completed.push(t)}return{visible:i,counts:a,groups:o,showIds:s,hasActiveWork:a.inProgress>0}}function i(e){return r(e).counts}function a(e){return r(e).groups}function o(e){return e.some(e=>e.status!==`deleted`&&!!e.blockedBy?.length)}function s(e){return e.some(e=>e.status===`in_progress`)}function c(e,t){let
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return e.filter(e=>e.status!==`deleted`)}function t(e){let t=new Map;for(let n of e)t.has(n.id)||t.set(n.id,n.status);return t}function n(e,t){return e.blockedBy?.some(e=>{let n=t.get(e);return n!==void 0&&n!==`completed`&&n!==`deleted`})??!1}function r(e){let r=t(e),i=[],a={total:0,completed:0,inProgress:0,pending:0,failed:0,blocked:0},o={inProgress:[],blocked:[],pending:[],completed:[],failed:[]},s=!1;for(let t of e)if(t.status!==`deleted`)switch(i.push(t),a.total+=1,s||=!!t.blockedBy?.length,t.status){case`in_progress`:a.inProgress+=1,o.inProgress.push(t);break;case`pending`:a.pending+=1,n(t,r)?(a.blocked+=1,o.blocked.push(t)):o.pending.push(t);break;case`failed`:a.failed+=1,o.failed.push(t);break;case`completed`:a.completed+=1,o.completed.push(t)}return{visible:i,counts:a,groups:o,showIds:s,hasActiveWork:a.inProgress>0}}function i(e){return r(e).counts}function a(e){return r(e).groups}function o(e){return e.some(e=>e.status!==`deleted`&&!!e.blockedBy?.length)}function s(e){return e.some(e=>e.status===`in_progress`)}function c(e,t){let{groups:n,visible:r}=e,i=[...n.inProgress,...n.failed,...n.blocked,...n.pending];if(t<=0)return{visible:[],hiddenCompleted:n.completed.length,truncatedTail:i.length};if(r.length<=t)return{visible:r,hiddenCompleted:0,truncatedTail:0};if(i.length<=t){let e=t-i.length,a=n.completed.slice(0,e),o=new Set([...i,...a]);return{visible:r.filter(e=>o.has(e)),hiddenCompleted:n.completed.length-a.length,truncatedTail:0}}let a=new Set(i.slice(0,t));return{visible:r.filter(e=>a.has(e)),hiddenCompleted:n.completed.length,truncatedTail:i.length-t}}function l(e,t){return c(r(e),t)}exports.countTasks=i,exports.deriveTaskProjection=r,exports.groupTasks=a,exports.hasActiveWork=s,exports.selectOverlayLayout=l,exports.selectOverlayLayoutFromProjection=c,exports.shouldShowIds=o,exports.visibleTasks=e;
|
|
2
2
|
//# sourceMappingURL=selectors.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.cjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../services/store/types.ts';\n\nexport interface TaskCounts {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n failed: number;\n blocked: number;\n}\n\nexport interface TaskGroups {\n inProgress: Task[];\n blocked: Task[];\n pending: Task[];\n completed: Task[];\n failed: Task[];\n}\n\nexport interface TaskProjection {\n visible: Task[];\n counts: TaskCounts;\n groups: TaskGroups;\n showIds: boolean;\n hasActiveWork: boolean;\n}\n\nexport function visibleTasks(tasks: readonly Task[]): Task[] {\n return tasks.filter((task) => task.status !== 'deleted');\n}\n\nfunction indexStatuses(tasks: readonly Task[]): Map<number, Task['status']> {\n const statuses = new Map<number, Task['status']>();\n for (const task of tasks) {\n // Valid stores have unique ids. Keeping the first entry also preserves the\n // former `Array.find` behavior if a corrupt document contains duplicates.\n if (!statuses.has(task.id)) statuses.set(task.id, task.status);\n }\n return statuses;\n}\n\nfunction hasUnresolvedBlocker(task: Task, statuses: ReadonlyMap<number, Task['status']>): boolean {\n return (\n task.blockedBy?.some((id) => {\n const status = statuses.get(id);\n return status !== undefined && status !== 'completed' && status !== 'deleted';\n }) ?? false\n );\n}\n\n/**\n * Derive all overlay-facing state in O(tasks + dependency edges).\n *\n * The id index replaces one full task-list scan per dependency, while the\n * ordered pass keeps group ordering identical to the source document.\n */\nexport function deriveTaskProjection(tasks: readonly Task[]): TaskProjection {\n const statuses = indexStatuses(tasks);\n const visible: Task[] = [];\n const counts: TaskCounts = { total: 0, completed: 0, inProgress: 0, pending: 0, failed: 0, blocked: 0 };\n const groups: TaskGroups = { inProgress: [], blocked: [], pending: [], completed: [], failed: [] };\n let showIds = false;\n\n for (const task of tasks) {\n if (task.status === 'deleted') continue;\n\n visible.push(task);\n counts.total += 1;\n showIds ||= Boolean(task.blockedBy?.length);\n\n switch (task.status) {\n case 'in_progress':\n counts.inProgress += 1;\n groups.inProgress.push(task);\n break;\n case 'pending': {\n counts.pending += 1;\n if (hasUnresolvedBlocker(task, statuses)) {\n counts.blocked += 1;\n groups.blocked.push(task);\n } else {\n groups.pending.push(task);\n }\n break;\n }\n case 'failed':\n counts.failed += 1;\n groups.failed.push(task);\n break;\n case 'completed':\n counts.completed += 1;\n groups.completed.push(task);\n break;\n }\n }\n\n return { visible, counts, groups, showIds, hasActiveWork: counts.inProgress > 0 };\n}\n\nexport function countTasks(tasks: readonly Task[]): TaskCounts {\n return deriveTaskProjection(tasks).counts;\n}\n\n/**\n * Group tasks for display.\n *\n * Blocked tasks split out of `pending` because a reader scanning the overlay\n * needs to know at a glance what is actually actionable right now.\n */\nexport function groupTasks(tasks: readonly Task[]): TaskGroups {\n return deriveTaskProjection(tasks).groups;\n}\n\n/** Ids are only worth the visual noise once dependencies are in play. */\nexport function shouldShowIds(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status !== 'deleted' && Boolean(task.blockedBy?.length));\n}\n\nexport function hasActiveWork(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status === 'in_progress');\n}\n\nexport interface OverlayLayout {\n visible: Task[];\n hiddenCompleted: number;\n truncatedTail: number;\n}\n\n/**\n * Choose which rows fit the overlay budget.\n *\n * Active work wins
|
|
1
|
+
{"version":3,"file":"selectors.cjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../services/store/types.ts';\n\nexport interface TaskCounts {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n failed: number;\n blocked: number;\n}\n\nexport interface TaskGroups {\n inProgress: Task[];\n blocked: Task[];\n pending: Task[];\n completed: Task[];\n failed: Task[];\n}\n\nexport interface TaskProjection {\n visible: Task[];\n counts: TaskCounts;\n groups: TaskGroups;\n showIds: boolean;\n hasActiveWork: boolean;\n}\n\nexport function visibleTasks(tasks: readonly Task[]): Task[] {\n return tasks.filter((task) => task.status !== 'deleted');\n}\n\nfunction indexStatuses(tasks: readonly Task[]): Map<number, Task['status']> {\n const statuses = new Map<number, Task['status']>();\n for (const task of tasks) {\n // Valid stores have unique ids. Keeping the first entry also preserves the\n // former `Array.find` behavior if a corrupt document contains duplicates.\n if (!statuses.has(task.id)) statuses.set(task.id, task.status);\n }\n return statuses;\n}\n\nfunction hasUnresolvedBlocker(task: Task, statuses: ReadonlyMap<number, Task['status']>): boolean {\n return (\n task.blockedBy?.some((id) => {\n const status = statuses.get(id);\n return status !== undefined && status !== 'completed' && status !== 'deleted';\n }) ?? false\n );\n}\n\n/**\n * Derive all overlay-facing state in O(tasks + dependency edges).\n *\n * The id index replaces one full task-list scan per dependency, while the\n * ordered pass keeps group ordering identical to the source document.\n */\nexport function deriveTaskProjection(tasks: readonly Task[]): TaskProjection {\n const statuses = indexStatuses(tasks);\n const visible: Task[] = [];\n const counts: TaskCounts = { total: 0, completed: 0, inProgress: 0, pending: 0, failed: 0, blocked: 0 };\n const groups: TaskGroups = { inProgress: [], blocked: [], pending: [], completed: [], failed: [] };\n let showIds = false;\n\n for (const task of tasks) {\n if (task.status === 'deleted') continue;\n\n visible.push(task);\n counts.total += 1;\n showIds ||= Boolean(task.blockedBy?.length);\n\n switch (task.status) {\n case 'in_progress':\n counts.inProgress += 1;\n groups.inProgress.push(task);\n break;\n case 'pending': {\n counts.pending += 1;\n if (hasUnresolvedBlocker(task, statuses)) {\n counts.blocked += 1;\n groups.blocked.push(task);\n } else {\n groups.pending.push(task);\n }\n break;\n }\n case 'failed':\n counts.failed += 1;\n groups.failed.push(task);\n break;\n case 'completed':\n counts.completed += 1;\n groups.completed.push(task);\n break;\n }\n }\n\n return { visible, counts, groups, showIds, hasActiveWork: counts.inProgress > 0 };\n}\n\nexport function countTasks(tasks: readonly Task[]): TaskCounts {\n return deriveTaskProjection(tasks).counts;\n}\n\n/**\n * Group tasks for display.\n *\n * Blocked tasks split out of `pending` because a reader scanning the overlay\n * needs to know at a glance what is actually actionable right now.\n */\nexport function groupTasks(tasks: readonly Task[]): TaskGroups {\n return deriveTaskProjection(tasks).groups;\n}\n\n/** Ids are only worth the visual noise once dependencies are in play. */\nexport function shouldShowIds(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status !== 'deleted' && Boolean(task.blockedBy?.length));\n}\n\nexport function hasActiveWork(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status === 'in_progress');\n}\n\nexport interface OverlayLayout {\n visible: Task[];\n hiddenCompleted: number;\n truncatedTail: number;\n}\n\n/**\n * Choose which rows fit the overlay budget.\n *\n * Active work wins limited space: in-progress first, then failed, blocked, and\n * pending. Selected rows are always returned in source order, however, so a\n * status update does not reshuffle an otherwise unchanged overlay.\n */\nexport function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout {\n const { groups, visible: sourceOrder } = projection;\n const active = [...groups.inProgress, ...groups.failed, ...groups.blocked, ...groups.pending];\n if (budget <= 0) {\n return {\n visible: [],\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length,\n };\n }\n if (sourceOrder.length <= budget) {\n return { visible: sourceOrder, hiddenCompleted: 0, truncatedTail: 0 };\n }\n\n if (active.length <= budget) {\n const remaining = budget - active.length;\n const shownCompleted = groups.completed.slice(0, remaining);\n const selected = new Set([...active, ...shownCompleted]);\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length - shownCompleted.length,\n truncatedTail: 0,\n };\n }\n\n const selected = new Set(active.slice(0, budget));\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length - budget,\n };\n}\n\nexport function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout {\n return selectOverlayLayoutFromProjection(deriveTaskProjection(tasks), budget);\n}\n"],"mappings":"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"}
|
package/dist/tui/selectors.d.cts
CHANGED
|
@@ -46,6 +46,13 @@ interface OverlayLayout {
|
|
|
46
46
|
hiddenCompleted: number;
|
|
47
47
|
truncatedTail: number;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Choose which rows fit the overlay budget.
|
|
51
|
+
*
|
|
52
|
+
* Active work wins limited space: in-progress first, then failed, blocked, and
|
|
53
|
+
* pending. Selected rows are always returned in source order, however, so a
|
|
54
|
+
* status update does not reshuffle an otherwise unchanged overlay.
|
|
55
|
+
*/
|
|
49
56
|
declare function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout;
|
|
50
57
|
declare function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout;
|
|
51
58
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.cts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;UAEiB;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf,YAAY;EACZ,SAAS;EACT,SAAS;EACT,WAAW;EACX,QAAQ;;UAGO;EACf,SAAS;EACT,QAAQ;EACR,QAAQ;EACR;EACA;;iBAGc,aAAa,gBAAgB,SAAS;;;;;;;iBA6BtC,qBAAqB,gBAAgB,SAAS;iBA2C9C,WAAW,gBAAgB,SAAS;;;;;;;iBAUpC,WAAW,gBAAgB,SAAS;;iBAKpC,cAAc,gBAAgB;iBAI9B,cAAc,gBAAgB;UAI7B;EACf,SAAS;EACT;EACA
|
|
1
|
+
{"version":3,"file":"selectors.d.cts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;UAEiB;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf,YAAY;EACZ,SAAS;EACT,SAAS;EACT,WAAW;EACX,QAAQ;;UAGO;EACf,SAAS;EACT,QAAQ;EACR,QAAQ;EACR;EACA;;iBAGc,aAAa,gBAAgB,SAAS;;;;;;;iBA6BtC,qBAAqB,gBAAgB,SAAS;iBA2C9C,WAAW,gBAAgB,SAAS;;;;;;;iBAUpC,WAAW,gBAAgB,SAAS;;iBAKpC,cAAc,gBAAgB;iBAI9B,cAAc,gBAAgB;UAI7B;EACf,SAAS;EACT;EACA;;;;;;;;;iBAUc,kCAAkC,YAAY,gBAAgB,iBAAiB;iBAiC/E,oBAAoB,gBAAgB,QAAQ,iBAAiB"}
|
package/dist/tui/selectors.d.mts
CHANGED
|
@@ -46,6 +46,13 @@ interface OverlayLayout {
|
|
|
46
46
|
hiddenCompleted: number;
|
|
47
47
|
truncatedTail: number;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Choose which rows fit the overlay budget.
|
|
51
|
+
*
|
|
52
|
+
* Active work wins limited space: in-progress first, then failed, blocked, and
|
|
53
|
+
* pending. Selected rows are always returned in source order, however, so a
|
|
54
|
+
* status update does not reshuffle an otherwise unchanged overlay.
|
|
55
|
+
*/
|
|
49
56
|
declare function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout;
|
|
50
57
|
declare function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout;
|
|
51
58
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.mts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;UAEiB;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf,YAAY;EACZ,SAAS;EACT,SAAS;EACT,WAAW;EACX,QAAQ;;UAGO;EACf,SAAS;EACT,QAAQ;EACR,QAAQ;EACR;EACA;;iBAGc,aAAa,gBAAgB,SAAS;;;;;;;iBA6BtC,qBAAqB,gBAAgB,SAAS;iBA2C9C,WAAW,gBAAgB,SAAS;;;;;;;iBAUpC,WAAW,gBAAgB,SAAS;;iBAKpC,cAAc,gBAAgB;iBAI9B,cAAc,gBAAgB;UAI7B;EACf,SAAS;EACT;EACA
|
|
1
|
+
{"version":3,"file":"selectors.d.mts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;UAEiB;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf,YAAY;EACZ,SAAS;EACT,SAAS;EACT,WAAW;EACX,QAAQ;;UAGO;EACf,SAAS;EACT,QAAQ;EACR,QAAQ;EACR;EACA;;iBAGc,aAAa,gBAAgB,SAAS;;;;;;;iBA6BtC,qBAAqB,gBAAgB,SAAS;iBA2C9C,WAAW,gBAAgB,SAAS;;;;;;;iBAUpC,WAAW,gBAAgB,SAAS;;iBAKpC,cAAc,gBAAgB;iBAI9B,cAAc,gBAAgB;UAI7B;EACf,SAAS;EACT;EACA;;;;;;;;;iBAUc,kCAAkC,YAAY,gBAAgB,iBAAiB;iBAiC/E,oBAAoB,gBAAgB,QAAQ,iBAAiB"}
|
package/dist/tui/selectors.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(e){return e.filter(e=>e.status!==`deleted`)}function t(e){let t=new Map;for(let n of e)t.has(n.id)||t.set(n.id,n.status);return t}function n(e,t){return e.blockedBy?.some(e=>{let n=t.get(e);return n!==void 0&&n!==`completed`&&n!==`deleted`})??!1}function r(e){let r=t(e),i=[],a={total:0,completed:0,inProgress:0,pending:0,failed:0,blocked:0},o={inProgress:[],blocked:[],pending:[],completed:[],failed:[]},s=!1;for(let t of e)if(t.status!==`deleted`)switch(i.push(t),a.total+=1,s||=!!t.blockedBy?.length,t.status){case`in_progress`:a.inProgress+=1,o.inProgress.push(t);break;case`pending`:a.pending+=1,n(t,r)?(a.blocked+=1,o.blocked.push(t)):o.pending.push(t);break;case`failed`:a.failed+=1,o.failed.push(t);break;case`completed`:a.completed+=1,o.completed.push(t)}return{visible:i,counts:a,groups:o,showIds:s,hasActiveWork:a.inProgress>0}}function i(e){return r(e).counts}function a(e){return r(e).groups}function o(e){return e.some(e=>e.status!==`deleted`&&!!e.blockedBy?.length)}function s(e){return e.some(e=>e.status===`in_progress`)}function c(e,t){let
|
|
1
|
+
function e(e){return e.filter(e=>e.status!==`deleted`)}function t(e){let t=new Map;for(let n of e)t.has(n.id)||t.set(n.id,n.status);return t}function n(e,t){return e.blockedBy?.some(e=>{let n=t.get(e);return n!==void 0&&n!==`completed`&&n!==`deleted`})??!1}function r(e){let r=t(e),i=[],a={total:0,completed:0,inProgress:0,pending:0,failed:0,blocked:0},o={inProgress:[],blocked:[],pending:[],completed:[],failed:[]},s=!1;for(let t of e)if(t.status!==`deleted`)switch(i.push(t),a.total+=1,s||=!!t.blockedBy?.length,t.status){case`in_progress`:a.inProgress+=1,o.inProgress.push(t);break;case`pending`:a.pending+=1,n(t,r)?(a.blocked+=1,o.blocked.push(t)):o.pending.push(t);break;case`failed`:a.failed+=1,o.failed.push(t);break;case`completed`:a.completed+=1,o.completed.push(t)}return{visible:i,counts:a,groups:o,showIds:s,hasActiveWork:a.inProgress>0}}function i(e){return r(e).counts}function a(e){return r(e).groups}function o(e){return e.some(e=>e.status!==`deleted`&&!!e.blockedBy?.length)}function s(e){return e.some(e=>e.status===`in_progress`)}function c(e,t){let{groups:n,visible:r}=e,i=[...n.inProgress,...n.failed,...n.blocked,...n.pending];if(t<=0)return{visible:[],hiddenCompleted:n.completed.length,truncatedTail:i.length};if(r.length<=t)return{visible:r,hiddenCompleted:0,truncatedTail:0};if(i.length<=t){let e=t-i.length,a=n.completed.slice(0,e),o=new Set([...i,...a]);return{visible:r.filter(e=>o.has(e)),hiddenCompleted:n.completed.length-a.length,truncatedTail:0}}let a=new Set(i.slice(0,t));return{visible:r.filter(e=>a.has(e)),hiddenCompleted:n.completed.length,truncatedTail:i.length-t}}function l(e,t){return c(r(e),t)}export{i as countTasks,r as deriveTaskProjection,a as groupTasks,s as hasActiveWork,l as selectOverlayLayout,c as selectOverlayLayoutFromProjection,o as shouldShowIds,e as visibleTasks};
|
|
2
2
|
//# sourceMappingURL=selectors.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.mjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../services/store/types.ts';\n\nexport interface TaskCounts {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n failed: number;\n blocked: number;\n}\n\nexport interface TaskGroups {\n inProgress: Task[];\n blocked: Task[];\n pending: Task[];\n completed: Task[];\n failed: Task[];\n}\n\nexport interface TaskProjection {\n visible: Task[];\n counts: TaskCounts;\n groups: TaskGroups;\n showIds: boolean;\n hasActiveWork: boolean;\n}\n\nexport function visibleTasks(tasks: readonly Task[]): Task[] {\n return tasks.filter((task) => task.status !== 'deleted');\n}\n\nfunction indexStatuses(tasks: readonly Task[]): Map<number, Task['status']> {\n const statuses = new Map<number, Task['status']>();\n for (const task of tasks) {\n // Valid stores have unique ids. Keeping the first entry also preserves the\n // former `Array.find` behavior if a corrupt document contains duplicates.\n if (!statuses.has(task.id)) statuses.set(task.id, task.status);\n }\n return statuses;\n}\n\nfunction hasUnresolvedBlocker(task: Task, statuses: ReadonlyMap<number, Task['status']>): boolean {\n return (\n task.blockedBy?.some((id) => {\n const status = statuses.get(id);\n return status !== undefined && status !== 'completed' && status !== 'deleted';\n }) ?? false\n );\n}\n\n/**\n * Derive all overlay-facing state in O(tasks + dependency edges).\n *\n * The id index replaces one full task-list scan per dependency, while the\n * ordered pass keeps group ordering identical to the source document.\n */\nexport function deriveTaskProjection(tasks: readonly Task[]): TaskProjection {\n const statuses = indexStatuses(tasks);\n const visible: Task[] = [];\n const counts: TaskCounts = { total: 0, completed: 0, inProgress: 0, pending: 0, failed: 0, blocked: 0 };\n const groups: TaskGroups = { inProgress: [], blocked: [], pending: [], completed: [], failed: [] };\n let showIds = false;\n\n for (const task of tasks) {\n if (task.status === 'deleted') continue;\n\n visible.push(task);\n counts.total += 1;\n showIds ||= Boolean(task.blockedBy?.length);\n\n switch (task.status) {\n case 'in_progress':\n counts.inProgress += 1;\n groups.inProgress.push(task);\n break;\n case 'pending': {\n counts.pending += 1;\n if (hasUnresolvedBlocker(task, statuses)) {\n counts.blocked += 1;\n groups.blocked.push(task);\n } else {\n groups.pending.push(task);\n }\n break;\n }\n case 'failed':\n counts.failed += 1;\n groups.failed.push(task);\n break;\n case 'completed':\n counts.completed += 1;\n groups.completed.push(task);\n break;\n }\n }\n\n return { visible, counts, groups, showIds, hasActiveWork: counts.inProgress > 0 };\n}\n\nexport function countTasks(tasks: readonly Task[]): TaskCounts {\n return deriveTaskProjection(tasks).counts;\n}\n\n/**\n * Group tasks for display.\n *\n * Blocked tasks split out of `pending` because a reader scanning the overlay\n * needs to know at a glance what is actually actionable right now.\n */\nexport function groupTasks(tasks: readonly Task[]): TaskGroups {\n return deriveTaskProjection(tasks).groups;\n}\n\n/** Ids are only worth the visual noise once dependencies are in play. */\nexport function shouldShowIds(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status !== 'deleted' && Boolean(task.blockedBy?.length));\n}\n\nexport function hasActiveWork(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status === 'in_progress');\n}\n\nexport interface OverlayLayout {\n visible: Task[];\n hiddenCompleted: number;\n truncatedTail: number;\n}\n\n/**\n * Choose which rows fit the overlay budget.\n *\n * Active work wins
|
|
1
|
+
{"version":3,"file":"selectors.mjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../services/store/types.ts';\n\nexport interface TaskCounts {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n failed: number;\n blocked: number;\n}\n\nexport interface TaskGroups {\n inProgress: Task[];\n blocked: Task[];\n pending: Task[];\n completed: Task[];\n failed: Task[];\n}\n\nexport interface TaskProjection {\n visible: Task[];\n counts: TaskCounts;\n groups: TaskGroups;\n showIds: boolean;\n hasActiveWork: boolean;\n}\n\nexport function visibleTasks(tasks: readonly Task[]): Task[] {\n return tasks.filter((task) => task.status !== 'deleted');\n}\n\nfunction indexStatuses(tasks: readonly Task[]): Map<number, Task['status']> {\n const statuses = new Map<number, Task['status']>();\n for (const task of tasks) {\n // Valid stores have unique ids. Keeping the first entry also preserves the\n // former `Array.find` behavior if a corrupt document contains duplicates.\n if (!statuses.has(task.id)) statuses.set(task.id, task.status);\n }\n return statuses;\n}\n\nfunction hasUnresolvedBlocker(task: Task, statuses: ReadonlyMap<number, Task['status']>): boolean {\n return (\n task.blockedBy?.some((id) => {\n const status = statuses.get(id);\n return status !== undefined && status !== 'completed' && status !== 'deleted';\n }) ?? false\n );\n}\n\n/**\n * Derive all overlay-facing state in O(tasks + dependency edges).\n *\n * The id index replaces one full task-list scan per dependency, while the\n * ordered pass keeps group ordering identical to the source document.\n */\nexport function deriveTaskProjection(tasks: readonly Task[]): TaskProjection {\n const statuses = indexStatuses(tasks);\n const visible: Task[] = [];\n const counts: TaskCounts = { total: 0, completed: 0, inProgress: 0, pending: 0, failed: 0, blocked: 0 };\n const groups: TaskGroups = { inProgress: [], blocked: [], pending: [], completed: [], failed: [] };\n let showIds = false;\n\n for (const task of tasks) {\n if (task.status === 'deleted') continue;\n\n visible.push(task);\n counts.total += 1;\n showIds ||= Boolean(task.blockedBy?.length);\n\n switch (task.status) {\n case 'in_progress':\n counts.inProgress += 1;\n groups.inProgress.push(task);\n break;\n case 'pending': {\n counts.pending += 1;\n if (hasUnresolvedBlocker(task, statuses)) {\n counts.blocked += 1;\n groups.blocked.push(task);\n } else {\n groups.pending.push(task);\n }\n break;\n }\n case 'failed':\n counts.failed += 1;\n groups.failed.push(task);\n break;\n case 'completed':\n counts.completed += 1;\n groups.completed.push(task);\n break;\n }\n }\n\n return { visible, counts, groups, showIds, hasActiveWork: counts.inProgress > 0 };\n}\n\nexport function countTasks(tasks: readonly Task[]): TaskCounts {\n return deriveTaskProjection(tasks).counts;\n}\n\n/**\n * Group tasks for display.\n *\n * Blocked tasks split out of `pending` because a reader scanning the overlay\n * needs to know at a glance what is actually actionable right now.\n */\nexport function groupTasks(tasks: readonly Task[]): TaskGroups {\n return deriveTaskProjection(tasks).groups;\n}\n\n/** Ids are only worth the visual noise once dependencies are in play. */\nexport function shouldShowIds(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status !== 'deleted' && Boolean(task.blockedBy?.length));\n}\n\nexport function hasActiveWork(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status === 'in_progress');\n}\n\nexport interface OverlayLayout {\n visible: Task[];\n hiddenCompleted: number;\n truncatedTail: number;\n}\n\n/**\n * Choose which rows fit the overlay budget.\n *\n * Active work wins limited space: in-progress first, then failed, blocked, and\n * pending. Selected rows are always returned in source order, however, so a\n * status update does not reshuffle an otherwise unchanged overlay.\n */\nexport function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout {\n const { groups, visible: sourceOrder } = projection;\n const active = [...groups.inProgress, ...groups.failed, ...groups.blocked, ...groups.pending];\n if (budget <= 0) {\n return {\n visible: [],\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length,\n };\n }\n if (sourceOrder.length <= budget) {\n return { visible: sourceOrder, hiddenCompleted: 0, truncatedTail: 0 };\n }\n\n if (active.length <= budget) {\n const remaining = budget - active.length;\n const shownCompleted = groups.completed.slice(0, remaining);\n const selected = new Set([...active, ...shownCompleted]);\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length - shownCompleted.length,\n truncatedTail: 0,\n };\n }\n\n const selected = new Set(active.slice(0, budget));\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length - budget,\n };\n}\n\nexport function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout {\n return selectOverlayLayoutFromProjection(deriveTaskProjection(tasks), budget);\n}\n"],"mappings":"AA2BA,SAAgB,EAAa,EAAgC,CAC3D,OAAO,EAAM,OAAQ,GAAS,EAAK,SAAW,SAAS,CACzD,CAEA,SAAS,EAAc,EAAqD,CAC1E,IAAM,EAAW,IAAI,IACrB,IAAK,IAAM,KAAQ,EAGZ,EAAS,IAAI,EAAK,EAAE,GAAG,EAAS,IAAI,EAAK,GAAI,EAAK,MAAM,EAE/D,OAAO,CACT,CAEA,SAAS,EAAqB,EAAY,EAAwD,CAChG,OACE,EAAK,WAAW,KAAM,GAAO,CAC3B,IAAM,EAAS,EAAS,IAAI,CAAE,EAC9B,OAAO,IAAW,IAAA,IAAa,IAAW,aAAe,IAAW,SACtE,CAAC,GAAK,EAEV,CAQA,SAAgB,EAAqB,EAAwC,CAC3E,IAAM,EAAW,EAAc,CAAK,EAC9B,EAAkB,CAAC,EACnB,EAAqB,CAAE,MAAO,EAAG,UAAW,EAAG,WAAY,EAAG,QAAS,EAAG,OAAQ,EAAG,QAAS,CAAE,EAChG,EAAqB,CAAE,WAAY,CAAC,EAAG,QAAS,CAAC,EAAG,QAAS,CAAC,EAAG,UAAW,CAAC,EAAG,OAAQ,CAAC,CAAE,EAC7F,EAAU,GAEd,IAAK,IAAM,KAAQ,EACb,KAAK,SAAW,UAMpB,OAJA,EAAQ,KAAK,CAAI,EACjB,EAAO,OAAS,EAChB,IAAY,EAAQ,EAAK,WAAW,OAE5B,EAAK,OAAb,CACE,IAAK,cACH,EAAO,YAAc,EACrB,EAAO,WAAW,KAAK,CAAI,EAC3B,MACF,IAAK,UACH,EAAO,SAAW,EACd,EAAqB,EAAM,CAAQ,GACrC,EAAO,SAAW,EAClB,EAAO,QAAQ,KAAK,CAAI,GAExB,EAAO,QAAQ,KAAK,CAAI,EAE1B,MAEF,IAAK,SACH,EAAO,QAAU,EACjB,EAAO,OAAO,KAAK,CAAI,EACvB,MACF,IAAK,YACH,EAAO,WAAa,EACpB,EAAO,UAAU,KAAK,CAAI,CAE9B,CAGF,MAAO,CAAE,UAAS,SAAQ,SAAQ,UAAS,cAAe,EAAO,WAAa,CAAE,CAClF,CAEA,SAAgB,EAAW,EAAoC,CAC7D,OAAO,EAAqB,CAAK,CAAC,CAAC,MACrC,CAQA,SAAgB,EAAW,EAAoC,CAC7D,OAAO,EAAqB,CAAK,CAAC,CAAC,MACrC,CAGA,SAAgB,EAAc,EAAiC,CAC7D,OAAO,EAAM,KAAM,GAAS,EAAK,SAAW,WAAa,EAAQ,EAAK,WAAW,MAAO,CAC1F,CAEA,SAAgB,EAAc,EAAiC,CAC7D,OAAO,EAAM,KAAM,GAAS,EAAK,SAAW,aAAa,CAC3D,CAeA,SAAgB,EAAkC,EAA4B,EAA+B,CAC3G,GAAM,CAAE,SAAQ,QAAS,GAAgB,EACnC,EAAS,CAAC,GAAG,EAAO,WAAY,GAAG,EAAO,OAAQ,GAAG,EAAO,QAAS,GAAG,EAAO,OAAO,EAC5F,GAAI,GAAU,EACZ,MAAO,CACL,QAAS,CAAC,EACV,gBAAiB,EAAO,UAAU,OAClC,cAAe,EAAO,MACxB,EAEF,GAAI,EAAY,QAAU,EACxB,MAAO,CAAE,QAAS,EAAa,gBAAiB,EAAG,cAAe,CAAE,EAGtE,GAAI,EAAO,QAAU,EAAQ,CAC3B,IAAM,EAAY,EAAS,EAAO,OAC5B,EAAiB,EAAO,UAAU,MAAM,EAAG,CAAS,EACpD,EAAW,IAAI,IAAI,CAAC,GAAG,EAAQ,GAAG,CAAc,CAAC,EACvD,MAAO,CACL,QAAS,EAAY,OAAQ,GAAS,EAAS,IAAI,CAAI,CAAC,EACxD,gBAAiB,EAAO,UAAU,OAAS,EAAe,OAC1D,cAAe,CACjB,CACF,CAEA,IAAM,EAAW,IAAI,IAAI,EAAO,MAAM,EAAG,CAAM,CAAC,EAChD,MAAO,CACL,QAAS,EAAY,OAAQ,GAAS,EAAS,IAAI,CAAI,CAAC,EACxD,gBAAiB,EAAO,UAAU,OAClC,cAAe,EAAO,OAAS,CACjC,CACF,CAEA,SAAgB,EAAoB,EAAwB,EAA+B,CACzF,OAAO,EAAkC,EAAqB,CAAK,EAAG,CAAM,CAC9E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-task",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.15",
|
|
4
4
|
"description": "Pi task tracking extension with file-backed tasks and subagent delegation",
|
|
5
5
|
"homepage": "https://agimon.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -142,9 +142,9 @@
|
|
|
142
142
|
},
|
|
143
143
|
"dependencies": {
|
|
144
144
|
"typebox": "1.1.38",
|
|
145
|
-
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.
|
|
146
|
-
"@agimon-ai/doompi-
|
|
147
|
-
"@agimon-ai/doompi-
|
|
145
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.15",
|
|
146
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.15",
|
|
147
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.15"
|
|
148
148
|
},
|
|
149
149
|
"devDependencies": {
|
|
150
150
|
"@earendil-works/pi-coding-agent": "0.84.1",
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
},
|
|
173
173
|
"pi": {
|
|
174
174
|
"extensions": [
|
|
175
|
-
"./dist/extensions/
|
|
175
|
+
"./dist/extensions/doom.mjs"
|
|
176
176
|
]
|
|
177
177
|
},
|
|
178
178
|
"scripts": {
|