@cat-factory/orchestration 0.260.0 → 0.261.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.
@@ -1,3 +1,4 @@
1
+ import { type TrackerWritebackFlags } from '@cat-factory/contracts';
1
2
  import type { Clock, PutTrackerSettingsInput, TrackerSettings, TrackerSettingsRepository, WorkspaceRepository } from '@cat-factory/kernel';
2
3
  export interface TrackerSettingsServiceDependencies {
3
4
  trackerSettingsRepository: TrackerSettingsRepository;
@@ -11,6 +12,38 @@ export declare class TrackerSettingsService {
11
12
  private readonly clock;
12
13
  constructor(deps: TrackerSettingsServiceDependencies);
13
14
  get(workspaceId: string): Promise<TrackerSettings>;
15
+ /**
16
+ * Replace the FILING selection, and move only the writeback actions the caller named.
17
+ *
18
+ * The filing half is wholesale: `tracker` is required, and its vendor target is cleared when the
19
+ * selection moves off that vendor, because those three fields are one decision and a caller
20
+ * editing it has just rendered all of it.
21
+ *
22
+ * The writeback half MERGES, which is the same rule {@link patchWriteback} follows. An omitted
23
+ * action is not a request to move it, on either door. It used to reset to the deployment default
24
+ * here, and that reading has no caller: the flags are booleans, so anyone who wants the defaults
25
+ * can send them. What it did have was a victim, the recurring-pipeline modal, which persists a
26
+ * tech-debt schedule's FILING tracker and names no writeback action at all. Under the reset rule
27
+ * that call re-enabled every action a workspace had deliberately turned off, silently and from a
28
+ * dialog about something else.
29
+ */
14
30
  put(workspaceId: string, input: PutTrackerSettingsInput): Promise<TrackerSettings>;
31
+ /**
32
+ * Change some writeback actions and leave everything else in the row exactly as it is.
33
+ *
34
+ * The `/api/v1` counterpart of {@link put}, and a different operation rather than a convenience
35
+ * over it: that one owns the filing selection, so a headless caller enabling one action through
36
+ * it would have to restate which tracker the workspace files tech-debt tickets on, which is a
37
+ * decision it never read and has no business in.
38
+ */
39
+ patchWriteback(workspaceId: string, patch: Partial<TrackerWritebackFlags>): Promise<TrackerSettings>;
40
+ /**
41
+ * The one write both doors go through: the named fields, merged onto the row in the STORE.
42
+ *
43
+ * Nothing is read first. A load-then-replace would let the SPA's panel and a headless patch race
44
+ * on the two halves of this row and lose one of them, and it is the half the loser did not name
45
+ * that would be silently rolled back to whatever it held when the winner loaded.
46
+ */
47
+ private write;
15
48
  }
16
49
  //# sourceMappingURL=TrackerSettingsService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TrackerSettingsService.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,uBAAuB,EACvB,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,qBAAqB,CAAA;AAG5B,MAAM,WAAW,kCAAkC;IACjD,yBAAyB,EAAE,yBAAyB,CAAA;IACpD,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;CACb;AAYD,gFAAgF;AAChF,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAE7B,YAAY,IAAI,EAAE,kCAAkC,EAInD;IAEK,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAGvD;IAEK,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmBvF;CACF"}
1
+ {"version":3,"file":"TrackerSettingsService.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC9F,OAAO,KAAK,EACV,KAAK,EACL,uBAAuB,EACvB,eAAe,EAEf,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,qBAAqB,CAAA;AAG5B,MAAM,WAAW,kCAAkC;IACjD,yBAAyB,EAAE,yBAAyB,CAAA;IACpD,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;CACb;AAaD,gFAAgF;AAChF,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAE7B,YAAY,IAAI,EAAE,kCAAkC,EAInD;IAEK,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAGvD;IAED;;;;;;;;;;;;;;OAcG;IACG,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CAYvF;IAED;;;;;;;OAOG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACpC,OAAO,CAAC,eAAe,CAAC,CAO1B;IAED;;;;;;OAMG;IACH,OAAO,CAAC,KAAK;CAGd"}
@@ -1,12 +1,14 @@
1
+ import { DEFAULT_TRACKER_WRITEBACK } from '@cat-factory/contracts';
1
2
  import { requireWorkspace } from '@cat-factory/kernel';
2
- /** The empty/unconfigured tracker settings returned before anything is set. */
3
+ /**
4
+ * The tracker settings returned before anything is set: nothing selected, and the writeback
5
+ * disposition every reader shares (`DEFAULT_TRACKER_WRITEBACK`, which says why it is ON).
6
+ */
3
7
  const EMPTY = {
4
8
  tracker: null,
5
9
  jiraProjectKey: null,
6
10
  linearTeamId: null,
7
- writebackCommentOnPrOpen: false,
8
- writebackResolveOnMerge: false,
9
- writebackQuestionsOnPark: false,
11
+ ...DEFAULT_TRACKER_WRITEBACK,
10
12
  };
11
13
  /** Read/write a workspace's issue-tracker selection (one row per workspace). */
12
14
  export class TrackerSettingsService {
@@ -22,25 +24,76 @@ export class TrackerSettingsService {
22
24
  await requireWorkspace(this.workspaceRepository, workspaceId);
23
25
  return (await this.repo.get(workspaceId)) ?? { ...EMPTY, updatedAt: 0 };
24
26
  }
27
+ /**
28
+ * Replace the FILING selection, and move only the writeback actions the caller named.
29
+ *
30
+ * The filing half is wholesale: `tracker` is required, and its vendor target is cleared when the
31
+ * selection moves off that vendor, because those three fields are one decision and a caller
32
+ * editing it has just rendered all of it.
33
+ *
34
+ * The writeback half MERGES, which is the same rule {@link patchWriteback} follows. An omitted
35
+ * action is not a request to move it, on either door. It used to reset to the deployment default
36
+ * here, and that reading has no caller: the flags are booleans, so anyone who wants the defaults
37
+ * can send them. What it did have was a victim, the recurring-pipeline modal, which persists a
38
+ * tech-debt schedule's FILING tracker and names no writeback action at all. Under the reset rule
39
+ * that call re-enabled every action a workspace had deliberately turned off, silently and from a
40
+ * dialog about something else.
41
+ */
25
42
  async put(workspaceId, input) {
26
43
  await requireWorkspace(this.workspaceRepository, workspaceId);
27
- const settings = {
44
+ return this.write(workspaceId, {
28
45
  tracker: input.tracker,
29
46
  // Only keep a Jira project key when Jira is the selected tracker.
30
47
  jiraProjectKey: input.tracker === 'jira' ? input.jiraProjectKey?.trim() || null : null,
31
48
  // Only keep a Linear team id when Linear is the selected tracker.
32
49
  linearTeamId: input.tracker === 'linear' ? input.linearTeamId?.trim() || null : null,
33
- // Writeback applies to a task's linked tracker issue(s) of any source, so it is
34
- // kept regardless of the filing tracker selection above. Default off.
35
- writebackCommentOnPrOpen: input.writebackCommentOnPrOpen ?? false,
36
- writebackResolveOnMerge: input.writebackResolveOnMerge ?? false,
37
- // The headless clarification loop's question echo (see the contract): only consulted for
38
- // runs started through the public API, so it is safe to keep alongside the PR toggles.
39
- writebackQuestionsOnPark: input.writebackQuestionsOnPark ?? false,
40
- updatedAt: this.clock.now(),
41
- };
42
- await this.repo.put(workspaceId, settings);
43
- return settings;
50
+ // Writeback applies to a task's linked tracker issue(s) of any source, so these ride along
51
+ // regardless of the filing selection above, and each is written only when named.
52
+ ...pickWriteback(input),
53
+ });
44
54
  }
55
+ /**
56
+ * Change some writeback actions and leave everything else in the row exactly as it is.
57
+ *
58
+ * The `/api/v1` counterpart of {@link put}, and a different operation rather than a convenience
59
+ * over it: that one owns the filing selection, so a headless caller enabling one action through
60
+ * it would have to restate which tracker the workspace files tech-debt tickets on, which is a
61
+ * decision it never read and has no business in.
62
+ */
63
+ async patchWriteback(workspaceId, patch) {
64
+ // An empty patch does not WRITE, because writing would be observable: it stamps `updatedAt`,
65
+ // which is how a reader tells a disposition somebody chose from the defaults nobody has
66
+ // touched. A no-op that quietly claims authorship of the defaults is the wrong no-op.
67
+ if (Object.keys(patch).length === 0)
68
+ return this.get(workspaceId);
69
+ await requireWorkspace(this.workspaceRepository, workspaceId);
70
+ return this.write(workspaceId, patch);
71
+ }
72
+ /**
73
+ * The one write both doors go through: the named fields, merged onto the row in the STORE.
74
+ *
75
+ * Nothing is read first. A load-then-replace would let the SPA's panel and a headless patch race
76
+ * on the two halves of this row and lose one of them, and it is the half the loser did not name
77
+ * that would be silently rolled back to whatever it held when the winner loaded.
78
+ */
79
+ write(workspaceId, patch) {
80
+ return this.repo.merge(workspaceId, patch, EMPTY, this.clock.now());
81
+ }
82
+ }
83
+ /** The writeback actions an input NAMED, with absence preserved rather than filled in. */
84
+ function pickWriteback(input) {
85
+ const patch = {};
86
+ if (input.writebackCommentOnPrOpen !== undefined) {
87
+ patch.writebackCommentOnPrOpen = input.writebackCommentOnPrOpen;
88
+ }
89
+ if (input.writebackResolveOnMerge !== undefined) {
90
+ patch.writebackResolveOnMerge = input.writebackResolveOnMerge;
91
+ }
92
+ // The headless clarification loop's question echo (see the contract): only consulted for runs
93
+ // started through the public API, so it is safe to keep alongside the PR toggles.
94
+ if (input.writebackQuestionsOnPark !== undefined) {
95
+ patch.writebackQuestionsOnPark = input.writebackQuestionsOnPark;
96
+ }
97
+ return patch;
45
98
  }
46
99
  //# sourceMappingURL=TrackerSettingsService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TrackerSettingsService.js","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAQtD,+EAA+E;AAC/E,MAAM,KAAK,GAAuC;IAChD,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,wBAAwB,EAAE,KAAK;IAC/B,uBAAuB,EAAE,KAAK;IAC9B,wBAAwB,EAAE,KAAK;CAChC,CAAA;AAED,gFAAgF;AAChF,MAAM,OAAO,sBAAsB;IAChB,IAAI,CAA2B;IAC/B,mBAAmB,CAAqB;IACxC,KAAK,CAAO;IAE7B,YAAY,IAAwC;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,yBAAyB,CAAA;QAC1C,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAA;QACnD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB;QAC3B,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;IACzE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,KAA8B;QAC3D,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAoB;YAChC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,kEAAkE;YAClE,cAAc,EAAE,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;YACtF,kEAAkE;YAClE,YAAY,EAAE,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;YACpF,gFAAgF;YAChF,sEAAsE;YACtE,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,KAAK;YACjE,uBAAuB,EAAE,KAAK,CAAC,uBAAuB,IAAI,KAAK;YAC/D,yFAAyF;YACzF,uFAAuF;YACvF,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,KAAK;YACjE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;SAC5B,CAAA;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QAC1C,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF"}
1
+ {"version":3,"file":"TrackerSettingsService.js","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/orchestration",
3
- "version": "0.260.0",
3
+ "version": "0.261.0",
4
4
  "description": "Delivery-workflow engine for the Agent Architecture Board (execution, bootstrap, pipelines, board, boardScan, requirements, and composition root).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,20 +25,20 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "ai": "^7.0.58",
28
- "@cat-factory/agents": "0.126.0",
29
- "@cat-factory/caching": "0.20.0",
30
- "@cat-factory/contracts": "0.297.0",
31
- "@cat-factory/integrations": "0.158.0",
32
- "@cat-factory/kernel": "0.288.0",
33
- "@cat-factory/prompt-fragments": "1.0.55",
34
- "@cat-factory/sandbox": "0.11.132",
35
- "@cat-factory/spend": "0.15.73",
36
- "@cat-factory/workspaces": "0.27.17"
28
+ "@cat-factory/agents": "0.126.2",
29
+ "@cat-factory/caching": "0.20.2",
30
+ "@cat-factory/contracts": "0.299.0",
31
+ "@cat-factory/integrations": "0.160.0",
32
+ "@cat-factory/kernel": "0.289.1",
33
+ "@cat-factory/prompt-fragments": "1.0.57",
34
+ "@cat-factory/sandbox": "0.11.134",
35
+ "@cat-factory/spend": "0.15.75",
36
+ "@cat-factory/workspaces": "0.27.19"
37
37
  },
38
38
  "devDependencies": {
39
39
  "typescript": "7.0.2",
40
40
  "vitest": "^4.1.10",
41
- "@cat-factory/sandbox-fixtures": "0.7.337"
41
+ "@cat-factory/sandbox-fixtures": "0.7.339"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc -b tsconfig.build.json",