@wrongstack/tools 0.308.6 → 0.308.7

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/builtin.js CHANGED
@@ -26246,6 +26246,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26246
26246
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26247
26247
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26248
26248
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26249
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26249
26250
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26250
26251
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26251
26252
  });
@@ -26265,6 +26266,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26265
26266
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26266
26267
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26267
26268
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26269
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26268
26270
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26269
26271
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26270
26272
  }
@@ -26427,6 +26429,7 @@ function taskInput(input) {
26427
26429
  status: input.metricStatus ?? "pending",
26428
26430
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26429
26431
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26432
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26430
26433
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26431
26434
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26432
26435
  }
@@ -27116,7 +27119,7 @@ function serializeKanbanOutput(output, input) {
27116
27119
 
27117
27120
  // src/kanban-tool-schema.ts
27118
27121
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
27119
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
27122
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
27120
27123
  var KANBAN_INPUT_SCHEMA = {
27121
27124
  type: "object",
27122
27125
  properties: {
@@ -27325,6 +27328,7 @@ var KANBAN_INPUT_SCHEMA = {
27325
27328
  metricName: { type: "string" },
27326
27329
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
27327
27330
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
27331
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
27328
27332
  metricUnit: { type: "string" },
27329
27333
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
27330
27334
  metricNotes: { type: "string" },
package/dist/index.js CHANGED
@@ -26849,6 +26849,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26849
26849
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26850
26850
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26851
26851
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26852
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26852
26853
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26853
26854
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26854
26855
  });
@@ -26868,6 +26869,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26868
26869
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26869
26870
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26870
26871
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26872
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26871
26873
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26872
26874
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26873
26875
  }
@@ -27030,6 +27032,7 @@ function taskInput(input) {
27030
27032
  status: input.metricStatus ?? "pending",
27031
27033
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
27032
27034
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
27035
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
27033
27036
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
27034
27037
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
27035
27038
  }
@@ -27719,7 +27722,7 @@ function serializeKanbanOutput(output, input) {
27719
27722
 
27720
27723
  // src/kanban-tool-schema.ts
27721
27724
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
27722
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
27725
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
27723
27726
  var KANBAN_INPUT_SCHEMA = {
27724
27727
  type: "object",
27725
27728
  properties: {
@@ -27928,6 +27931,7 @@ var KANBAN_INPUT_SCHEMA = {
27928
27931
  metricName: { type: "string" },
27929
27932
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
27930
27933
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
27934
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
27931
27935
  metricUnit: { type: "string" },
27932
27936
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
27933
27937
  metricNotes: { type: "string" },
@@ -33,6 +33,7 @@ export declare function taskInput(input: KanbanToolInput): {
33
33
  status: "met" | "missed" | "pending" | "waived";
34
34
  target?: string | number;
35
35
  current?: string | number;
36
+ direction?: "at_least" | "at_most";
36
37
  unit?: string;
37
38
  notes?: string;
38
39
  }[];
@@ -1,5 +1,5 @@
1
1
  import type { JSONSchema } from '@wrongstack/core/types';
2
2
  export declare const KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
3
- export declare const KANBAN_TOOL_USAGE_HINT = "Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus \"passed\" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType (\"command\", \"test\", \"file_exists\", \"file_matches\", \"git_diff\", \"metric\") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or \"manual\") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.";
3
+ export declare const KANBAN_TOOL_USAGE_HINT = "Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus \"passed\" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType (\"command\", \"test\", \"file_exists\", \"file_matches\", \"git_diff\", \"metric\") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or \"manual\") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection \"at_most\" with add_goal_metric / update_goal_metric so verification compares current <= target instead.";
4
4
  export declare const KANBAN_INPUT_SCHEMA: JSONSchema;
5
5
  //# sourceMappingURL=kanban-tool-schema.d.ts.map
@@ -41,6 +41,8 @@ export interface KanbanToolInput extends Omit<AssignKanbanTaskInput, 'status'> {
41
41
  metricName?: string | undefined;
42
42
  metricTarget?: string | number | undefined;
43
43
  metricCurrent?: string | number | undefined;
44
+ /** Comparison direction for the goal metric: `at_least` (default) or `at_most`. */
45
+ metricDirection?: 'at_least' | 'at_most' | undefined;
44
46
  metricUnit?: string | undefined;
45
47
  metricStatus?: 'pending' | 'met' | 'missed' | 'waived' | undefined;
46
48
  metricNotes?: string | undefined;
package/dist/kanban.js CHANGED
@@ -721,6 +721,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
721
721
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
722
722
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
723
723
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
724
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
724
725
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
725
726
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
726
727
  });
@@ -740,6 +741,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
740
741
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
741
742
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
742
743
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
744
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
743
745
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
744
746
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
745
747
  }
@@ -902,6 +904,7 @@ function taskInput(input) {
902
904
  status: input.metricStatus ?? "pending",
903
905
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
904
906
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
907
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
905
908
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
906
909
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
907
910
  }
@@ -1591,7 +1594,7 @@ function serializeKanbanOutput(output, input) {
1591
1594
 
1592
1595
  // src/kanban-tool-schema.ts
1593
1596
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
1594
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
1597
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
1595
1598
  var KANBAN_INPUT_SCHEMA = {
1596
1599
  type: "object",
1597
1600
  properties: {
@@ -1800,6 +1803,7 @@ var KANBAN_INPUT_SCHEMA = {
1800
1803
  metricName: { type: "string" },
1801
1804
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
1802
1805
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
1806
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
1803
1807
  metricUnit: { type: "string" },
1804
1808
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
1805
1809
  metricNotes: { type: "string" },
package/dist/pack.js CHANGED
@@ -26246,6 +26246,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26246
26246
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26247
26247
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26248
26248
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26249
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26249
26250
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26250
26251
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26251
26252
  });
@@ -26265,6 +26266,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26265
26266
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26266
26267
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26267
26268
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26269
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26268
26270
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26269
26271
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26270
26272
  }
@@ -26427,6 +26429,7 @@ function taskInput(input) {
26427
26429
  status: input.metricStatus ?? "pending",
26428
26430
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26429
26431
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26432
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26430
26433
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26431
26434
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26432
26435
  }
@@ -27116,7 +27119,7 @@ function serializeKanbanOutput(output, input) {
27116
27119
 
27117
27120
  // src/kanban-tool-schema.ts
27118
27121
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
27119
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
27122
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
27120
27123
  var KANBAN_INPUT_SCHEMA = {
27121
27124
  type: "object",
27122
27125
  properties: {
@@ -27325,6 +27328,7 @@ var KANBAN_INPUT_SCHEMA = {
27325
27328
  metricName: { type: "string" },
27326
27329
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
27327
27330
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
27331
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
27328
27332
  metricUnit: { type: "string" },
27329
27333
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
27330
27334
  metricNotes: { type: "string" },
package/dist/plan.js CHANGED
@@ -1193,6 +1193,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
1193
1193
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
1194
1194
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1195
1195
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1196
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1196
1197
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1197
1198
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1198
1199
  });
@@ -1212,6 +1213,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
1212
1213
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
1213
1214
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1214
1215
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1216
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1215
1217
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1216
1218
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1217
1219
  }
@@ -1374,6 +1376,7 @@ function taskInput(input) {
1374
1376
  status: input.metricStatus ?? "pending",
1375
1377
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1376
1378
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1379
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1377
1380
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1378
1381
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1379
1382
  }
@@ -2063,7 +2066,7 @@ function serializeKanbanOutput(output, input) {
2063
2066
 
2064
2067
  // src/kanban-tool-schema.ts
2065
2068
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
2066
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
2069
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
2067
2070
  var KANBAN_INPUT_SCHEMA = {
2068
2071
  type: "object",
2069
2072
  properties: {
@@ -2272,6 +2275,7 @@ var KANBAN_INPUT_SCHEMA = {
2272
2275
  metricName: { type: "string" },
2273
2276
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
2274
2277
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
2278
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
2275
2279
  metricUnit: { type: "string" },
2276
2280
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
2277
2281
  metricNotes: { type: "string" },
package/dist/task.js CHANGED
@@ -1153,6 +1153,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
1153
1153
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
1154
1154
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1155
1155
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1156
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1156
1157
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1157
1158
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1158
1159
  });
@@ -1172,6 +1173,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
1172
1173
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
1173
1174
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1174
1175
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1176
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1175
1177
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1176
1178
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1177
1179
  }
@@ -1334,6 +1336,7 @@ function taskInput(input) {
1334
1336
  status: input.metricStatus ?? "pending",
1335
1337
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1336
1338
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1339
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1337
1340
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1338
1341
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1339
1342
  }
@@ -2023,7 +2026,7 @@ function serializeKanbanOutput(output, input) {
2023
2026
 
2024
2027
  // src/kanban-tool-schema.ts
2025
2028
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
2026
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
2029
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
2027
2030
  var KANBAN_INPUT_SCHEMA = {
2028
2031
  type: "object",
2029
2032
  properties: {
@@ -2232,6 +2235,7 @@ var KANBAN_INPUT_SCHEMA = {
2232
2235
  metricName: { type: "string" },
2233
2236
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
2234
2237
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
2238
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
2235
2239
  metricUnit: { type: "string" },
2236
2240
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
2237
2241
  metricNotes: { type: "string" },
package/dist/todo.js CHANGED
@@ -1140,6 +1140,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
1140
1140
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
1141
1141
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1142
1142
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1143
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1143
1144
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1144
1145
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1145
1146
  });
@@ -1159,6 +1160,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
1159
1160
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
1160
1161
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1161
1162
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1163
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1162
1164
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1163
1165
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1164
1166
  }
@@ -1321,6 +1323,7 @@ function taskInput(input) {
1321
1323
  status: input.metricStatus ?? "pending",
1322
1324
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
1323
1325
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
1326
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
1324
1327
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
1325
1328
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
1326
1329
  }
@@ -2010,7 +2013,7 @@ function serializeKanbanOutput(output, input) {
2010
2013
 
2011
2014
  // src/kanban-tool-schema.ts
2012
2015
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
2013
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
2016
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
2014
2017
  var KANBAN_INPUT_SCHEMA = {
2015
2018
  type: "object",
2016
2019
  properties: {
@@ -2219,6 +2222,7 @@ var KANBAN_INPUT_SCHEMA = {
2219
2222
  metricName: { type: "string" },
2220
2223
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
2221
2224
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
2225
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
2222
2226
  metricUnit: { type: "string" },
2223
2227
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
2224
2228
  metricNotes: { type: "string" },
package/dist/tool-tier.js CHANGED
@@ -26246,6 +26246,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26246
26246
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26247
26247
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26248
26248
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26249
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26249
26250
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26250
26251
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26251
26252
  });
@@ -26265,6 +26266,7 @@ async function handleKanbanDetailAction(projectRoot, input) {
26265
26266
  ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
26266
26267
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26267
26268
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26269
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26268
26270
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26269
26271
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26270
26272
  }
@@ -26427,6 +26429,7 @@ function taskInput(input) {
26427
26429
  status: input.metricStatus ?? "pending",
26428
26430
  ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
26429
26431
  ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
26432
+ ...input.metricDirection !== void 0 ? { direction: input.metricDirection } : {},
26430
26433
  ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
26431
26434
  ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
26432
26435
  }
@@ -27116,7 +27119,7 @@ function serializeKanbanOutput(output, input) {
27116
27119
 
27117
27120
  // src/kanban-tool-schema.ts
27118
27121
  var KANBAN_TOOL_DESCRIPTION = "Durable project task boards: create and move cards, record checks, notes, links and assignments. The board is a record of the work, not a permit for it \u2014 nothing here gates other tools. Managed boards additionally enforce ordered Backlog \u2192 Todo \u2192 Running \u2192 Review \u2192 Done transitions; release_managed_lifecycle turns that off.";
27119
- var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything.';
27122
+ var KANBAN_TOOL_USAGE_HINT = 'Track substantial or multi-step work so it survives the session; a trivial edit or a question needs no card. Work stays on ONE board: call list_boards first and add_task to the board this project already uses. create_board is for a genuinely separate line of work, not for each new piece of it \u2014 a second board splits the same effort in two, and a board holding a single card is the usual sign. Common flow: list_boards or search_tasks to orient, add_task to record work, start_task when you begin, update_check with checkStatus "passed" to tick acceptance criteria (read their ids from get_task), then transition_task. On a managed board a refused transition names the field it wants \u2014 supply it and retry. When the acceptance criterion is something a machine can run, say so: set checkType ("command", "test", "file_exists", "file_matches", "git_diff", "metric") and put the command, pattern or path in checkNotes, then verify_completion executes it and the result is real evidence. Leave checkType off (or "manual") only for criteria that genuinely need a human eye \u2014 a manual check records your assertion, it does not test anything. Goal metrics pass when current >= target by default; when lower is better (error rate, cost ceiling, latency, open-bug count), pass metricDirection "at_most" with add_goal_metric / update_goal_metric so verification compares current <= target instead.';
27120
27123
  var KANBAN_INPUT_SCHEMA = {
27121
27124
  type: "object",
27122
27125
  properties: {
@@ -27325,6 +27328,7 @@ var KANBAN_INPUT_SCHEMA = {
27325
27328
  metricName: { type: "string" },
27326
27329
  metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
27327
27330
  metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
27331
+ metricDirection: { type: "string", enum: ["at_least", "at_most"] },
27328
27332
  metricUnit: { type: "string" },
27329
27333
  metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
27330
27334
  metricNotes: { type: "string" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/tools",
3
- "version": "0.308.6",
3
+ "version": "0.308.7",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack built-in tools: read/write/edit, bash/exec, grep/glob, git, fetch, test, lint, and more.",
6
6
  "repository": {
@@ -253,9 +253,9 @@
253
253
  "turndown": "^7.2.4",
254
254
  "undici": "^8.10.0",
255
255
  "web-tree-sitter": "0.26.12",
256
- "@wrongstack/kanban": "0.308.6",
257
- "@wrongstack/core": "0.308.6",
258
- "@wrongstack/persistence": "0.308.6"
256
+ "@wrongstack/core": "0.308.7",
257
+ "@wrongstack/persistence": "0.308.7",
258
+ "@wrongstack/kanban": "0.308.7"
259
259
  },
260
260
  "devDependencies": {
261
261
  "@types/node": "^26.2.0",