@opentask/taskin-task-manager 3.0.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +119 -0
- package/dist/completion-blockers.test.d.ts +1 -0
- package/dist/completion-blockers.test.js +57 -0
- package/dist/completion-blockers.test.js.map +1 -0
- package/dist/filter-tasks/filter-criteria.d.ts +181 -0
- package/dist/filter-tasks/filter-criteria.js +115 -0
- package/dist/filter-tasks/filter-criteria.js.map +1 -0
- package/dist/filter-tasks/filter-criteria.test.d.ts +1 -0
- package/dist/filter-tasks/filter-criteria.test.js +86 -0
- package/dist/filter-tasks/filter-criteria.test.js.map +1 -0
- package/dist/filter-tasks/filter-tasks.d.ts +26 -0
- package/dist/filter-tasks/filter-tasks.js +99 -0
- package/dist/filter-tasks/filter-tasks.js.map +1 -0
- package/dist/filter-tasks/filter-tasks.test.d.ts +1 -0
- package/dist/filter-tasks/filter-tasks.test.js +110 -0
- package/dist/filter-tasks/filter-tasks.test.js.map +1 -0
- package/dist/filter-tasks/filter-tasks.types.d.ts +27 -0
- package/dist/filter-tasks/filter-tasks.types.js +2 -0
- package/dist/filter-tasks/filter-tasks.types.js.map +1 -0
- package/dist/filter-tasks/index.d.ts +4 -0
- package/dist/filter-tasks/index.js +3 -0
- package/dist/filter-tasks/index.js.map +1 -0
- package/dist/group-registry.contract.d.ts +18 -0
- package/dist/group-registry.contract.js +73 -0
- package/dist/group-registry.contract.js.map +1 -0
- package/dist/group-registry.types.d.ts +44 -0
- package/dist/group-registry.types.js +2 -0
- package/dist/group-registry.types.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/numerar-prioridade/index.d.ts +1 -0
- package/dist/numerar-prioridade/index.js +2 -0
- package/dist/numerar-prioridade/index.js.map +1 -0
- package/dist/numerar-prioridade/numerar-prioridade.d.ts +36 -0
- package/dist/numerar-prioridade/numerar-prioridade.js +75 -0
- package/dist/numerar-prioridade/numerar-prioridade.js.map +1 -0
- package/dist/numerar-prioridade/numerar-prioridade.test.d.ts +1 -0
- package/dist/numerar-prioridade/numerar-prioridade.test.js +55 -0
- package/dist/numerar-prioridade/numerar-prioridade.test.js.map +1 -0
- package/dist/ordenar-tarefas/index.d.ts +1 -0
- package/dist/ordenar-tarefas/index.js +2 -0
- package/dist/ordenar-tarefas/index.js.map +1 -0
- package/dist/ordenar-tarefas/ordenar-tarefas.d.ts +70 -0
- package/dist/ordenar-tarefas/ordenar-tarefas.js +79 -0
- package/dist/ordenar-tarefas/ordenar-tarefas.js.map +1 -0
- package/dist/ordenar-tarefas/ordenar-tarefas.test.d.ts +1 -0
- package/dist/ordenar-tarefas/ordenar-tarefas.test.js +70 -0
- package/dist/ordenar-tarefas/ordenar-tarefas.test.js.map +1 -0
- package/dist/task-manager.d.ts +34 -1
- package/dist/task-manager.js +58 -0
- package/dist/task-manager.js.map +1 -1
- package/dist/task-manager.types.d.ts +93 -0
- package/dist/testing.d.ts +8 -0
- package/dist/testing.js +9 -0
- package/dist/testing.js.map +1 -0
- package/dist/user-registry.contract.js +6 -6
- package/dist/user-registry.contract.js.map +1 -1
- package/package.json +7 -6
- package/src/completion-blockers.test.ts +77 -0
- package/src/filter-tasks/filter-criteria.test.ts +113 -0
- package/src/filter-tasks/filter-criteria.ts +175 -0
- package/src/filter-tasks/filter-tasks.test.ts +129 -0
- package/src/filter-tasks/filter-tasks.ts +106 -0
- package/src/filter-tasks/filter-tasks.types.ts +26 -0
- package/src/filter-tasks/index.ts +16 -0
- package/src/group-registry.contract.ts +99 -0
- package/src/group-registry.types.ts +47 -0
- package/src/index.ts +4 -0
- package/src/numerar-prioridade/index.ts +1 -0
- package/src/numerar-prioridade/numerar-prioridade.test.ts +69 -0
- package/src/numerar-prioridade/numerar-prioridade.ts +80 -0
- package/src/ordenar-tarefas/index.ts +1 -0
- package/src/ordenar-tarefas/ordenar-tarefas.test.ts +92 -0
- package/src/ordenar-tarefas/ordenar-tarefas.ts +135 -0
- package/src/task-manager.ts +70 -0
- package/src/task-manager.types.ts +95 -0
- package/src/testing.ts +8 -0
- package/src/user-registry.contract.ts +6 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Task, TaskId, TaskType } from '@opentask/taskin-types';
|
|
2
|
+
import type { IGroupRegistry } from './group-registry.types.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Options for creating a new task
|
|
@@ -40,6 +41,14 @@ export type ValidationSeverity = 'error' | 'warning' | 'info';
|
|
|
40
41
|
* A validation error or warning found during linting
|
|
41
42
|
* @public
|
|
42
43
|
*/
|
|
44
|
+
/** Um criterio que ainda impede a conclusao. */
|
|
45
|
+
export interface CriterioEmAberto {
|
|
46
|
+
/** O texto do item, como escrito. */
|
|
47
|
+
readonly texto: string;
|
|
48
|
+
/** Onde ele esta, quando a fonte sabe dizer. */
|
|
49
|
+
readonly linha?: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
export interface ValidationIssue {
|
|
44
53
|
/** The file or task that has the issue */
|
|
45
54
|
file: string;
|
|
@@ -130,6 +139,20 @@ export interface ITaskProvider<TTask extends Task = Task> {
|
|
|
130
139
|
* @returns The lint result with any validation issues found
|
|
131
140
|
*/
|
|
132
141
|
lint: (fix?: boolean) => Promise<LintResult>;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Os criterios de conclusao que ainda bloqueiam esta tarefa, se a fonte tiver
|
|
145
|
+
* o conceito.
|
|
146
|
+
*
|
|
147
|
+
* **Opcional de proposito.** Checklist e uma forma do provider de arquivos: o
|
|
148
|
+
* Jira tem subtarefas, o GitHub tem itens de lista na descricao. Um provider
|
|
149
|
+
* sem nada equivalente simplesmente nao implementa, e o `finishTask` conclui
|
|
150
|
+
* sem portao — em vez de chamar algo que falha.
|
|
151
|
+
*
|
|
152
|
+
* O conceito e de dominio ("o que falta para isto estar pronto?"); a
|
|
153
|
+
* representacao e de provider.
|
|
154
|
+
*/
|
|
155
|
+
getCompletionBlockers?: (task: TTask) => Promise<CriterioEmAberto[]>;
|
|
133
156
|
}
|
|
134
157
|
|
|
135
158
|
/**
|
|
@@ -154,6 +177,64 @@ export interface ITaskManager<TTask extends Task = Task> {
|
|
|
154
177
|
*/
|
|
155
178
|
finishTask: (taskId: TaskId) => Promise<TTask>;
|
|
156
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Every task the configured provider knows about.
|
|
182
|
+
*
|
|
183
|
+
* Delegates to the provider, like {@link ITaskManager.lint} does. Listing is
|
|
184
|
+
* a domain question — "what work exists?" — and a consumer that only holds a
|
|
185
|
+
* manager should not need the provider to answer it. The MCP server did, and
|
|
186
|
+
* shipped a `taskin://tasks` resource that answered with a placeholder.
|
|
187
|
+
*
|
|
188
|
+
* @returns The tasks, in whatever order the provider returns them
|
|
189
|
+
*/
|
|
190
|
+
getAllTasks: () => Promise<TTask[]>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Da a cada tarefa um numero de prioridade, de uma vez.
|
|
194
|
+
*
|
|
195
|
+
* E operacao de dominio, e nao um `updateTask` generico, por dois motivos.
|
|
196
|
+
*
|
|
197
|
+
* O primeiro e de desenho: a regra da numeracao — preservar a ordem, manter o
|
|
198
|
+
* numero de quem ja tem, abrir espaco quando faltar — passa a viver num lugar
|
|
199
|
+
* so, em vez de ser reescrita pela CLI e pelo servidor MCP.
|
|
200
|
+
*
|
|
201
|
+
* O segundo e de tipo: um metodo que **consome** `TTask` torna a interface
|
|
202
|
+
* contravariante nele, e um `ITaskManager<TarefaEspecifica>` deixa de poder
|
|
203
|
+
* ser usado onde se espera `ITaskManager<Task>`. Uma operacao que so devolve
|
|
204
|
+
* numeros nao tem esse problema.
|
|
205
|
+
*
|
|
206
|
+
* Existe porque um projeto **meio numerado** cobra caro: mover uma tarefa do
|
|
207
|
+
* meio da regiao sem numero reescreve todos os antecessores — 124 arquivos num
|
|
208
|
+
* projeto de 500, medido. Depois desta operacao, todo movimento custa um.
|
|
209
|
+
*
|
|
210
|
+
* @param options - `dryRun` apenas conta, sem gravar
|
|
211
|
+
* @returns Quantas existem, quantas estavam sem numero, e quantas mudaram
|
|
212
|
+
*/
|
|
213
|
+
/**
|
|
214
|
+
* Os grupos, quando a fonte tem o conceito — `undefined` quando nao tem.
|
|
215
|
+
*
|
|
216
|
+
* Opcional de proposito: o GitHub mapeia para milestone, o Redmine para
|
|
217
|
+
* categoria, e uma fonte sem nada equivalente simplesmente nao oferece. Quem
|
|
218
|
+
* consome descobre pela ausencia, em vez de chamar algo que falha.
|
|
219
|
+
*/
|
|
220
|
+
readonly groupRegistry?: IGroupRegistry;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Conclui a tarefa e relata os criterios que ficaram em aberto.
|
|
224
|
+
*
|
|
225
|
+
* Avisa, e nao recusa: fechar e um gesto unico, muitas vezes com pressa, e
|
|
226
|
+
* recusar ali torna o comando fragil. O portao duro vive no `lint`.
|
|
227
|
+
*
|
|
228
|
+
* O relato vem vazio quando o provider nao tem o conceito de checklist.
|
|
229
|
+
*/
|
|
230
|
+
finishTaskComRelato: (taskId: TaskId) => Promise<{ task: TTask; blockers: CriterioEmAberto[] }>;
|
|
231
|
+
|
|
232
|
+
prioritizeAll: (options?: { dryRun?: boolean }) => Promise<{
|
|
233
|
+
total: number;
|
|
234
|
+
withoutPriority: number;
|
|
235
|
+
changed: number;
|
|
236
|
+
}>;
|
|
237
|
+
|
|
157
238
|
/**
|
|
158
239
|
* Mark a task as ready for review.
|
|
159
240
|
* Transitions the task from 'in-progress' to 'in-review' status.
|
|
@@ -197,4 +278,18 @@ export interface ITaskManager<TTask extends Task = Task> {
|
|
|
197
278
|
* @returns The lint result with any validation issues found
|
|
198
279
|
*/
|
|
199
280
|
lint: (fix?: boolean) => Promise<LintResult>;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Os criterios de conclusao que ainda bloqueiam esta tarefa, se a fonte tiver
|
|
284
|
+
* o conceito.
|
|
285
|
+
*
|
|
286
|
+
* **Opcional de proposito.** Checklist e uma forma do provider de arquivos: o
|
|
287
|
+
* Jira tem subtarefas, o GitHub tem itens de lista na descricao. Um provider
|
|
288
|
+
* sem nada equivalente simplesmente nao implementa, e o `finishTask` conclui
|
|
289
|
+
* sem portao — em vez de chamar algo que falha.
|
|
290
|
+
*
|
|
291
|
+
* O conceito e de dominio ("o que falta para isto estar pronto?"); a
|
|
292
|
+
* representacao e de provider.
|
|
293
|
+
*/
|
|
294
|
+
getCompletionBlockers?: (task: TTask) => Promise<CriterioEmAberto[]>;
|
|
200
295
|
}
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contratos que as implementacoes provam contra si mesmas.
|
|
3
|
+
*
|
|
4
|
+
* Exportado por `@opentask/taskin-task-manager/testing` para o `vitest` nunca
|
|
5
|
+
* entrar no grafo de execucao do pacote.
|
|
6
|
+
*/
|
|
7
|
+
export * from './group-registry.contract.js';
|
|
8
|
+
export * from './user-registry.contract.js';
|
|
@@ -40,7 +40,7 @@ export function runUserRegistryContractTests(createSubject: () => Promise<IUserR
|
|
|
40
40
|
const user = registry.resolveUser('joao.silva');
|
|
41
41
|
expect(user).toBeDefined();
|
|
42
42
|
expect(user!.id).toBe('joao.silva');
|
|
43
|
-
expect(user!.
|
|
43
|
+
expect(user!.avatarHash).toMatch(/^[a-f0-9]{32}$/);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it('should return user by name (case-insensitive)', async () => {
|
|
@@ -54,7 +54,7 @@ export function runUserRegistryContractTests(createSubject: () => Promise<IUserR
|
|
|
54
54
|
const user = registry.resolveUser('Maria Souza');
|
|
55
55
|
expect(user).toBeDefined();
|
|
56
56
|
expect(user!.id).toBe('maria');
|
|
57
|
-
expect(user!.
|
|
57
|
+
expect(user!.avatarHash).toMatch(/^[a-f0-9]{32}$/);
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it('should return undefined for unknown user', async () => {
|
|
@@ -65,21 +65,21 @@ export function runUserRegistryContractTests(createSubject: () => Promise<IUserR
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
describe('createTemporaryUser', () => {
|
|
68
|
-
it('should create user with
|
|
68
|
+
it('should create user with an avatar identity hash', async () => {
|
|
69
69
|
const registry = await createSubject();
|
|
70
70
|
const user = registry.createTemporaryUser('Carlos');
|
|
71
71
|
|
|
72
72
|
expect(user.id).toBe('carlos');
|
|
73
73
|
expect(user.name).toBe('Carlos');
|
|
74
74
|
expect(user.email).toBe('carlos@example.com');
|
|
75
|
-
expect(user.
|
|
75
|
+
expect(user.avatarHash).toMatch(/^[a-f0-9]{32}$/);
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
it('should create different
|
|
78
|
+
it('should create different avatar hashes for different inputs', async () => {
|
|
79
79
|
const registry = await createSubject();
|
|
80
80
|
const user1 = registry.createTemporaryUser('Alice');
|
|
81
81
|
const user2 = registry.createTemporaryUser('Bob');
|
|
82
|
-
expect(user1.
|
|
82
|
+
expect(user1.avatarHash).not.toBe(user2.avatarHash);
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
|