@cat-factory/agents 0.94.0 → 0.96.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/dist/agents/kinds/registry.d.ts +25 -0
- package/dist/agents/kinds/registry.d.ts.map +1 -1
- package/dist/agents/kinds/registry.js +39 -0
- package/dist/agents/kinds/registry.js.map +1 -1
- package/dist/agents/kinds/traits.d.ts +22 -0
- package/dist/agents/kinds/traits.d.ts.map +1 -1
- package/dist/agents/kinds/traits.js +42 -3
- package/dist/agents/kinds/traits.js.map +1 -1
- package/dist/agents/kinds/variants.d.ts +115 -0
- package/dist/agents/kinds/variants.d.ts.map +1 -0
- package/dist/agents/kinds/variants.js +35 -0
- package/dist/agents/kinds/variants.js.map +1 -0
- package/dist/agents/prompts/bespoke-kinds.d.ts +72 -0
- package/dist/agents/prompts/bespoke-kinds.d.ts.map +1 -0
- package/dist/agents/prompts/bespoke-kinds.js +114 -0
- package/dist/agents/prompts/bespoke-kinds.js.map +1 -0
- package/dist/foundationalServices/FoundationalServiceCatalogService.d.ts +65 -0
- package/dist/foundationalServices/FoundationalServiceCatalogService.d.ts.map +1 -0
- package/dist/foundationalServices/FoundationalServiceCatalogService.js +284 -0
- package/dist/foundationalServices/FoundationalServiceCatalogService.js.map +1 -0
- package/dist/foundationalServices/FoundationalServiceRunResolver.d.ts +37 -0
- package/dist/foundationalServices/FoundationalServiceRunResolver.d.ts.map +1 -0
- package/dist/foundationalServices/FoundationalServiceRunResolver.js +92 -0
- package/dist/foundationalServices/FoundationalServiceRunResolver.js.map +1 -0
- package/dist/foundationalServices/FoundationalServiceSourceService.d.ts +86 -0
- package/dist/foundationalServices/FoundationalServiceSourceService.d.ts.map +1 -0
- package/dist/foundationalServices/FoundationalServiceSourceService.js +346 -0
- package/dist/foundationalServices/FoundationalServiceSourceService.js.map +1 -0
- package/dist/foundationalServices/contract-validation.d.ts +8 -0
- package/dist/foundationalServices/contract-validation.d.ts.map +1 -0
- package/dist/foundationalServices/contract-validation.js +43 -0
- package/dist/foundationalServices/contract-validation.js.map +1 -0
- package/dist/foundationalServices/foundational-catalog.d.ts +22 -0
- package/dist/foundationalServices/foundational-catalog.d.ts.map +1 -0
- package/dist/foundationalServices/foundational-catalog.js +58 -0
- package/dist/foundationalServices/foundational-catalog.js.map +1 -0
- package/dist/foundationalServices/foundational-source.logic.d.ts +51 -0
- package/dist/foundationalServices/foundational-source.logic.d.ts.map +1 -0
- package/dist/foundationalServices/foundational-source.logic.js +109 -0
- package/dist/foundationalServices/foundational-source.logic.js.map +1 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { baseSystemPromptFor } from '../catalog.js';
|
|
2
|
+
import { INLINE_ENGINE_SYSTEM_PROMPTS } from './inline-engine.js';
|
|
3
|
+
import { FINAL_ANSWER_IN_REPLY } from './shared.js';
|
|
4
|
+
// The two bespoke CONTAINER prompts (`merger`, `on-call`) and the map that collects every kind
|
|
5
|
+
// whose prompt is a bespoke constant rather than a `systemPromptFor` composition.
|
|
6
|
+
//
|
|
7
|
+
// Each is declared as a ROLE half and a DIRECTIVES half rather than one string, because a
|
|
8
|
+
// workspace can replace the role from the pipeline builder (and a registered agent-kind VARIANT
|
|
9
|
+
// can replace it in code — see ../kinds/variants.ts). The directives half is what
|
|
10
|
+
// `applySurfaceDirectives` is for every other kind — the read-only guardrail, the machine-parsed
|
|
11
|
+
// output contract, and the answer-in-your-reply rule — so it must survive a replacement rather
|
|
12
|
+
// than be editable prose inside it. Each `*_DIRECTIVES` string CARRIES ITS OWN LEADING SEPARATOR,
|
|
13
|
+
// exactly as the appended directives do on the `systemPromptFor` path (where they are recovered
|
|
14
|
+
// by slicing the base off), so `role + directives` is the shipped prompt byte for byte.
|
|
15
|
+
// `promptOverrides.spec.ts` pins that.
|
|
16
|
+
//
|
|
17
|
+
// This lives in `@cat-factory/agents` rather than beside the container executor that dispatches
|
|
18
|
+
// the two kinds because the ENGINE needs the same answer: it resolves a variant's prompt against
|
|
19
|
+
// the SHIPPED base once per dispatch, and a bespoke kind's shipped base is its role half, not
|
|
20
|
+
// what `baseSystemPromptFor` would return. With the map in the HTTP layer the engine could only
|
|
21
|
+
// have guessed, and would have folded a variant's addition onto the wrong text for exactly the
|
|
22
|
+
// two kinds whose prompts carry a parsed output contract.
|
|
23
|
+
/**
|
|
24
|
+
* The EDITABLE half of the `merger` prompt: what the agent is for. Replaced wholesale by a
|
|
25
|
+
* workspace override, so it must carry no invariant the engine depends on.
|
|
26
|
+
*/
|
|
27
|
+
export const MERGER_ROLE_PROMPT = 'You are a release manager assessing a pull request before merge. Inspect the ' +
|
|
28
|
+
'change (the diff between the pull-request branch(es) and their base) and judge three axes, ' +
|
|
29
|
+
'each as a number from 0 (trivial/safe) to 1 (severe): complexity (how intricate the ' +
|
|
30
|
+
'change is), risk (how likely it is to break something), and impact (blast radius ' +
|
|
31
|
+
'if it does). When the change spans several repositories, weigh the COMBINED cross-repo ' +
|
|
32
|
+
'change as one and return a single assessment. Be conservative.';
|
|
33
|
+
/**
|
|
34
|
+
* The NON-EDITABLE half: the JSON contract `resolveMergerStep` parses, and the rule that keeps a
|
|
35
|
+
* reasoning model's answer out of its hidden channel. Re-appended on top of an override — an
|
|
36
|
+
* override that could drop these fails the run in exactly the ways they exist to prevent (an
|
|
37
|
+
* empty visible reply the harness reads as unusable; a merge decision with nothing to parse).
|
|
38
|
+
*/
|
|
39
|
+
export const MERGER_DIRECTIVES = ' Respond with ONLY a JSON ' +
|
|
40
|
+
'object of shape {"complexity":0.0,"risk":0.0,"impact":0.0,"rationale":"…"} — no prose, ' +
|
|
41
|
+
'no code fences. ' +
|
|
42
|
+
FINAL_ANSWER_IN_REPLY;
|
|
43
|
+
/** Role prompt the `merger` step runs under (scores the PR; returns JSON only). */
|
|
44
|
+
export const MERGER_SYSTEM_PROMPT = MERGER_ROLE_PROMPT + MERGER_DIRECTIVES;
|
|
45
|
+
/**
|
|
46
|
+
* The EDITABLE half of the `on-call` prompt: what the agent is investigating and how to weigh
|
|
47
|
+
* it. Replaced wholesale by a workspace override — note that the read-only guardrail is
|
|
48
|
+
* deliberately NOT here, since an on-call agent that could be told to commit is the specific
|
|
49
|
+
* accident this split prevents.
|
|
50
|
+
*/
|
|
51
|
+
export const ON_CALL_ROLE_PROMPT = 'You are an on-call engineer investigating a possible post-release regression. A ' +
|
|
52
|
+
'recently merged pull request shipped, and the evidence below (alerting Datadog ' +
|
|
53
|
+
'monitors/SLOs and recent error logs) suggests the service regressed afterward. Read ' +
|
|
54
|
+
'the PR diff on the head branch and weigh whether THIS change is the likely cause — ' +
|
|
55
|
+
'beware correlation vs causation; a coincident deploy is not proof.';
|
|
56
|
+
/**
|
|
57
|
+
* The NON-EDITABLE half: the read-only guardrail (this kind investigates, a human decides
|
|
58
|
+
* whether to revert — see `resolveOnCallStep`), the JSON contract the engine parses, and the
|
|
59
|
+
* answer-in-your-reply rule. Re-appended on top of an override.
|
|
60
|
+
*/
|
|
61
|
+
export const ON_CALL_DIRECTIVES = ' You may read and ' +
|
|
62
|
+
'inspect any file, but you MUST NOT modify, commit or revert anything; a human decides ' +
|
|
63
|
+
'whether to revert. Respond with ONLY a JSON object of shape ' +
|
|
64
|
+
'{"culpritConfidence":0.0,"recommendation":"revert"|"hold"|"monitor","rationale":"…",' +
|
|
65
|
+
'"evidence":["…"]} — no prose, no code fences. ' +
|
|
66
|
+
FINAL_ANSWER_IN_REPLY;
|
|
67
|
+
/** Role prompt the `on-call` step runs under (investigates a regression; returns JSON only). */
|
|
68
|
+
export const ON_CALL_SYSTEM_PROMPT = ON_CALL_ROLE_PROMPT + ON_CALL_DIRECTIVES;
|
|
69
|
+
/**
|
|
70
|
+
* Every kind whose prompt is a bespoke constant rather than a `systemPromptFor` composition,
|
|
71
|
+
* keyed by agent kind and SPLIT at the boundary a replacement may cross
|
|
72
|
+
* ({@link BespokeSystemPrompt}).
|
|
73
|
+
*
|
|
74
|
+
* Two families, for the same reason. The container kinds `merger` and `on-call` dispatch a
|
|
75
|
+
* bespoke constant (both return a strict JSON assessment whose contract is stated in that
|
|
76
|
+
* prompt); the inline ENGINE steps — the requirements + clarity reviewers, both brainstorm
|
|
77
|
+
* stages, their rework editors and the Requirement Writer — are driven by
|
|
78
|
+
* `IterativeReviewService` as bare inline calls. Neither family passes through `systemPromptFor`,
|
|
79
|
+
* so neither gets its override applied or its invariants re-appended by that seam.
|
|
80
|
+
*
|
|
81
|
+
* Collected here so the prompt EDITOR, the RUN and a code-registered VARIANT agree on what "the
|
|
82
|
+
* built-in prompt for this kind" is. With the constants only inlined, an editor built on
|
|
83
|
+
* `systemPromptFor` showed the merger's thin one-line role — and the requirements reviewer's
|
|
84
|
+
* `roles.ts` line — as the baseline while something else entirely ran: "restore the built-in"
|
|
85
|
+
* restored a prompt that was never running, and a diff against the baseline was noise.
|
|
86
|
+
*
|
|
87
|
+
* Adding another such kind means adding it here, SPLIT — a kind added with its directives inside
|
|
88
|
+
* `role` compiles and runs fine, and fails only later, as a workspace that edited it loses its
|
|
89
|
+
* guardrail or its JSON contract.
|
|
90
|
+
*
|
|
91
|
+
* The two container kind ids are bare literals: their canonical constants live in kernel
|
|
92
|
+
* (`ON_CALL_AGENT_KIND`) and orchestration (`MERGER_AGENT_KIND`), and this package sits below
|
|
93
|
+
* both. Pinned by `promptOverrides.spec.ts`, which resolves them through those constants.
|
|
94
|
+
*/
|
|
95
|
+
export const BESPOKE_SYSTEM_PROMPTS = {
|
|
96
|
+
...INLINE_ENGINE_SYSTEM_PROMPTS,
|
|
97
|
+
merger: { role: MERGER_ROLE_PROMPT, directives: MERGER_DIRECTIVES },
|
|
98
|
+
'on-call': { role: ON_CALL_ROLE_PROMPT, directives: ON_CALL_DIRECTIVES },
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* The SHIPPED prompt for a kind — the unit a per-workspace override or a registered variant
|
|
102
|
+
* REPLACES, and what the prompt editor shows as the baseline to diff against and restore to.
|
|
103
|
+
*
|
|
104
|
+
* It excludes the surface directives and trait guidance `systemPromptFor` layers on (and, for a
|
|
105
|
+
* bespoke kind, its `directives` half), because those are invariants of how the platform runs
|
|
106
|
+
* the kind (a read-only kind must not edit; a reasoning kind's answer must land in its visible
|
|
107
|
+
* reply) rather than editorial content. They are re-applied on top of a replacement, so handing
|
|
108
|
+
* them to an editor would only let someone delete something that comes back anyway — or, worse,
|
|
109
|
+
* duplicate it on save.
|
|
110
|
+
*/
|
|
111
|
+
export function shippedBasePromptFor(kind, registry) {
|
|
112
|
+
return BESPOKE_SYSTEM_PROMPTS[kind]?.role ?? baseSystemPromptFor(kind, registry);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=bespoke-kinds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bespoke-kinds.js","sourceRoot":"","sources":["../../../src/agents/prompts/bespoke-kinds.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,+FAA+F;AAC/F,kFAAkF;AAClF,EAAE;AACF,0FAA0F;AAC1F,gGAAgG;AAChG,kFAAkF;AAClF,iGAAiG;AACjG,+FAA+F;AAC/F,kGAAkG;AAClG,gGAAgG;AAChG,wFAAwF;AACxF,uCAAuC;AACvC,EAAE;AACF,gGAAgG;AAChG,iGAAiG;AACjG,8FAA8F;AAC9F,gGAAgG;AAChG,+FAA+F;AAC/F,0DAA0D;AAE1D;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,+EAA+E;IAC/E,6FAA6F;IAC7F,sFAAsF;IACtF,mFAAmF;IACnF,yFAAyF;IACzF,gEAAgE,CAAA;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC5B,4BAA4B;IAC5B,yFAAyF;IACzF,kBAAkB;IAClB,qBAAqB,CAAA;AAEvB,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,iBAAiB,CAAA;AAE1E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAC9B,kFAAkF;IAClF,iFAAiF;IACjF,sFAAsF;IACtF,qFAAqF;IACrF,oEAAoE,CAAA;AAEtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,oBAAoB;IACpB,wFAAwF;IACxF,8DAA8D;IAC9D,sFAAsF;IACtF,gDAAgD;IAChD,qBAAqB,CAAA;AAEvB,gGAAgG;AAChG,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,GAAG,kBAAkB,CAAA;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAoD;IACrF,GAAG,4BAA4B;IAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,iBAAiB,EAAE;IACnE,SAAS,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,kBAAkB,EAAE;CACzE,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAe,EAAE,QAA2B;IAC/E,OAAO,sBAAsB,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AAClF,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ApiContractDocument, CreateFoundationalServiceInput, FoundationalService, FoundationalServiceOwnerKind, ResolvedFoundationalService, UpdateFoundationalServiceInput } from '@cat-factory/contracts';
|
|
2
|
+
import type { ApiContractRepository, Clock, FoundationalServiceRepository, GroupCacheHandle, WorkspaceRepository } from '@cat-factory/kernel';
|
|
3
|
+
export interface FoundationalServiceCatalogDependencies {
|
|
4
|
+
foundationalServiceRepository: FoundationalServiceRepository;
|
|
5
|
+
apiContractRepository: ApiContractRepository;
|
|
6
|
+
workspaceRepository: WorkspaceRepository;
|
|
7
|
+
clock: Clock;
|
|
8
|
+
/** The merged per-workspace catalog cache. Absent (tests) ⇒ every resolve reads through. */
|
|
9
|
+
catalogCache?: GroupCacheHandle<ResolvedFoundationalService[]>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The foundational-services catalog (docs/initiatives/foundational-services.md): per-tier CRUD
|
|
13
|
+
* plus the merged account ⊕ workspace resolve every design dispatch reads.
|
|
14
|
+
*
|
|
15
|
+
* Two properties are load-bearing and are why this is a service rather than a repository call:
|
|
16
|
+
*
|
|
17
|
+
* - **The catalog never carries a contract BODY.** `listTier` and `resolve` join the contract
|
|
18
|
+
* MANIFEST (id, format, title, byte size, operation names) onto each service in ONE extra
|
|
19
|
+
* query for the whole tier. The documents are read only by {@link contractsFor}, and only for
|
|
20
|
+
* the ids a caller asks for.
|
|
21
|
+
* - **A workspace row wins over an account row of the same id, and a workspace TOMBSTONE
|
|
22
|
+
* suppresses one.** That is what lets a board opt out of an org-wide service without an
|
|
23
|
+
* account admin, and it is why the merge reads the workspace tier `includeDeleted`.
|
|
24
|
+
*/
|
|
25
|
+
export declare class FoundationalServiceCatalogService {
|
|
26
|
+
private readonly deps;
|
|
27
|
+
constructor(deps: FoundationalServiceCatalogDependencies);
|
|
28
|
+
/** One tier's registered services, contract manifests joined on. Raw — not merged. */
|
|
29
|
+
listTier(ownerKind: FoundationalServiceOwnerKind, ownerId: string): Promise<FoundationalService[]>;
|
|
30
|
+
/** Register a service at a tier. */
|
|
31
|
+
create(ownerKind: FoundationalServiceOwnerKind, ownerId: string, input: CreateFoundationalServiceInput): Promise<FoundationalService>;
|
|
32
|
+
/** Patch a registered service. `contracts`, when present, replaces the whole set. */
|
|
33
|
+
update(ownerKind: FoundationalServiceOwnerKind, ownerId: string, serviceId: string, input: UpdateFoundationalServiceInput): Promise<FoundationalService>;
|
|
34
|
+
/**
|
|
35
|
+
* Remove a service from a tier. A WORKSPACE removal writes a tombstone (which is also how a
|
|
36
|
+
* board suppresses an inherited account service); an ACCOUNT removal drops the row and its
|
|
37
|
+
* documents outright, since there is no higher tier for it to shadow.
|
|
38
|
+
*/
|
|
39
|
+
remove(ownerKind: FoundationalServiceOwnerKind, ownerId: string, serviceId: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Suppress an ACCOUNT service for one workspace by writing a workspace-tier tombstone. The
|
|
42
|
+
* row carries no content of its own — it exists only to lose the merge — so it is written
|
|
43
|
+
* here rather than through {@link create}, which would demand a name and summary for
|
|
44
|
+
* something that is never rendered.
|
|
45
|
+
*/
|
|
46
|
+
suppressForWorkspace(workspaceId: string, serviceId: string): Promise<void>;
|
|
47
|
+
/** The merged catalog a workspace's agents see, cached per workspace. */
|
|
48
|
+
resolve(workspaceId: string): Promise<ResolvedFoundationalService[]>;
|
|
49
|
+
/**
|
|
50
|
+
* The LAZY contract read: full documents for the named services, resolved against the same
|
|
51
|
+
* account ⊕ workspace precedence the catalog uses. One batched query per tier — never a
|
|
52
|
+
* per-service read — and an empty `serviceIds` returns `[]` without touching the store.
|
|
53
|
+
*
|
|
54
|
+
* Precedence matters here as much as in the catalog: a workspace that overrode a service
|
|
55
|
+
* must hand out ITS documents, or the design would be reviewed against the org's spec while
|
|
56
|
+
* the code is written against the board's.
|
|
57
|
+
*/
|
|
58
|
+
contractsFor(workspaceId: string, serviceIds: string[]): Promise<Map<string, ApiContractDocument[]>>;
|
|
59
|
+
/** Drop a tier's cached catalog. An account write invalidates every workspace's. */
|
|
60
|
+
invalidate(ownerKind: FoundationalServiceOwnerKind, ownerId: string): Promise<void>;
|
|
61
|
+
private loadCatalog;
|
|
62
|
+
private require;
|
|
63
|
+
private buildUploadedContracts;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=FoundationalServiceCatalogService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FoundationalServiceCatalogService.d.ts","sourceRoot":"","sources":["../../src/foundationalServices/FoundationalServiceCatalogService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,8BAA8B,EAC9B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,8BAA8B,EAC/B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAGV,qBAAqB,EACrB,KAAK,EAEL,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,qBAAqB,CAAA;AAU5B,MAAM,WAAW,sCAAsC;IACrD,6BAA6B,EAAE,6BAA6B,CAAA;IAC5D,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;IACZ,4FAA4F;IAC5F,YAAY,CAAC,EAAE,gBAAgB,CAAC,2BAA2B,EAAE,CAAC,CAAA;CAC/D;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,iCAAiC;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,sCAAsC,EAAI;IAE7E,sFAAsF;IAChF,QAAQ,CACZ,SAAS,EAAE,4BAA4B,EACvC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAOhC;IAED,oCAAoC;IAC9B,MAAM,CACV,SAAS,EAAE,4BAA4B,EACvC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,mBAAmB,CAAC,CAsC9B;IAED,qFAAqF;IAC/E,MAAM,CACV,SAAS,EAAE,4BAA4B,EACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,mBAAmB,CAAC,CAmC9B;IAED;;;;OAIG;IACG,MAAM,CACV,SAAS,EAAE,4BAA4B,EACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAKf;IAED;;;;;OAKG;IACG,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhF;IAED,yEAAyE;IACnE,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,EAAE,CAAC,CAGzE;IAED;;;;;;;;OAQG;IACG,YAAY,CAChB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC,CA0B7C;IAED,oFAAoF;IAC9E,UAAU,CAAC,SAAS,EAAE,4BAA4B,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxF;YAEa,WAAW;YAoBX,OAAO;IAUrB,OAAO,CAAC,sBAAsB;CAyC/B"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { ConflictError, NotFoundError, ValidationError, summarizeContract, } from '@cat-factory/kernel';
|
|
2
|
+
import { mergeFoundationalTiers, toWire } from './foundational-catalog.js';
|
|
3
|
+
import { validateUploadedContract } from './contract-validation.js';
|
|
4
|
+
/**
|
|
5
|
+
* The foundational-services catalog (docs/initiatives/foundational-services.md): per-tier CRUD
|
|
6
|
+
* plus the merged account ⊕ workspace resolve every design dispatch reads.
|
|
7
|
+
*
|
|
8
|
+
* Two properties are load-bearing and are why this is a service rather than a repository call:
|
|
9
|
+
*
|
|
10
|
+
* - **The catalog never carries a contract BODY.** `listTier` and `resolve` join the contract
|
|
11
|
+
* MANIFEST (id, format, title, byte size, operation names) onto each service in ONE extra
|
|
12
|
+
* query for the whole tier. The documents are read only by {@link contractsFor}, and only for
|
|
13
|
+
* the ids a caller asks for.
|
|
14
|
+
* - **A workspace row wins over an account row of the same id, and a workspace TOMBSTONE
|
|
15
|
+
* suppresses one.** That is what lets a board opt out of an org-wide service without an
|
|
16
|
+
* account admin, and it is why the merge reads the workspace tier `includeDeleted`.
|
|
17
|
+
*/
|
|
18
|
+
export class FoundationalServiceCatalogService {
|
|
19
|
+
deps;
|
|
20
|
+
constructor(deps) {
|
|
21
|
+
this.deps = deps;
|
|
22
|
+
}
|
|
23
|
+
/** One tier's registered services, contract manifests joined on. Raw — not merged. */
|
|
24
|
+
async listTier(ownerKind, ownerId) {
|
|
25
|
+
const [records, manifest] = await Promise.all([
|
|
26
|
+
this.deps.foundationalServiceRepository.listByOwner(ownerKind, ownerId),
|
|
27
|
+
this.deps.apiContractRepository.listManifestByOwner(ownerKind, ownerId),
|
|
28
|
+
]);
|
|
29
|
+
const byService = indexManifest(manifest);
|
|
30
|
+
return records.map((record) => toWire(record, byService.get(record.serviceId) ?? []));
|
|
31
|
+
}
|
|
32
|
+
/** Register a service at a tier. */
|
|
33
|
+
async create(ownerKind, ownerId, input) {
|
|
34
|
+
const existing = await this.deps.foundationalServiceRepository.get(ownerKind, ownerId, input.id);
|
|
35
|
+
// A LIVE row is a conflict; a tombstoned one is revived by this write. Refusing the
|
|
36
|
+
// revival would leave an id permanently unusable after one delete.
|
|
37
|
+
if (existing && !existing.deletedAt) {
|
|
38
|
+
throw new ConflictError(`Foundational service '${input.id}' already exists at this scope`, 'foundational_service_exists', { serviceId: input.id });
|
|
39
|
+
}
|
|
40
|
+
const now = this.deps.clock.now();
|
|
41
|
+
const record = {
|
|
42
|
+
serviceId: input.id,
|
|
43
|
+
ownerKind,
|
|
44
|
+
ownerId,
|
|
45
|
+
name: input.name,
|
|
46
|
+
summary: input.summary,
|
|
47
|
+
description: input.description,
|
|
48
|
+
capabilities: input.capabilities ?? [],
|
|
49
|
+
sourceId: null,
|
|
50
|
+
sourcePath: null,
|
|
51
|
+
pinnedCommit: null,
|
|
52
|
+
createdAt: existing?.createdAt ?? now,
|
|
53
|
+
updatedAt: now,
|
|
54
|
+
deletedAt: null,
|
|
55
|
+
};
|
|
56
|
+
await this.deps.foundationalServiceRepository.upsert(record);
|
|
57
|
+
const contracts = this.buildUploadedContracts(ownerKind, ownerId, input.id, input.contracts, now);
|
|
58
|
+
await this.deps.apiContractRepository.replaceForService(ownerKind, ownerId, input.id, contracts);
|
|
59
|
+
await this.invalidate(ownerKind, ownerId);
|
|
60
|
+
return toWire(record, contracts.map(manifestOf));
|
|
61
|
+
}
|
|
62
|
+
/** Patch a registered service. `contracts`, when present, replaces the whole set. */
|
|
63
|
+
async update(ownerKind, ownerId, serviceId, input) {
|
|
64
|
+
const existing = await this.require(ownerKind, ownerId, serviceId);
|
|
65
|
+
const now = this.deps.clock.now();
|
|
66
|
+
const record = {
|
|
67
|
+
...existing,
|
|
68
|
+
name: input.name ?? existing.name,
|
|
69
|
+
summary: input.summary ?? existing.summary,
|
|
70
|
+
description: input.description ?? existing.description,
|
|
71
|
+
capabilities: input.capabilities ?? existing.capabilities,
|
|
72
|
+
updatedAt: now,
|
|
73
|
+
};
|
|
74
|
+
await this.deps.foundationalServiceRepository.upsert(record);
|
|
75
|
+
let manifest;
|
|
76
|
+
if (input.contracts) {
|
|
77
|
+
const contracts = this.buildUploadedContracts(ownerKind, ownerId, serviceId, input.contracts, now);
|
|
78
|
+
await this.deps.apiContractRepository.replaceForService(ownerKind, ownerId, serviceId, contracts);
|
|
79
|
+
manifest = contracts.map(manifestOf);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
manifest = (await this.deps.apiContractRepository.listManifestByOwner(ownerKind, ownerId)).filter((entry) => entry.serviceId === serviceId);
|
|
83
|
+
}
|
|
84
|
+
await this.invalidate(ownerKind, ownerId);
|
|
85
|
+
return toWire(record, manifest);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Remove a service from a tier. A WORKSPACE removal writes a tombstone (which is also how a
|
|
89
|
+
* board suppresses an inherited account service); an ACCOUNT removal drops the row and its
|
|
90
|
+
* documents outright, since there is no higher tier for it to shadow.
|
|
91
|
+
*/
|
|
92
|
+
async remove(ownerKind, ownerId, serviceId) {
|
|
93
|
+
const now = this.deps.clock.now();
|
|
94
|
+
await this.deps.foundationalServiceRepository.softDelete(ownerKind, ownerId, serviceId, now);
|
|
95
|
+
await this.deps.apiContractRepository.deleteForService(ownerKind, ownerId, serviceId);
|
|
96
|
+
await this.invalidate(ownerKind, ownerId);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Suppress an ACCOUNT service for one workspace by writing a workspace-tier tombstone. The
|
|
100
|
+
* row carries no content of its own — it exists only to lose the merge — so it is written
|
|
101
|
+
* here rather than through {@link create}, which would demand a name and summary for
|
|
102
|
+
* something that is never rendered.
|
|
103
|
+
*/
|
|
104
|
+
async suppressForWorkspace(workspaceId, serviceId) {
|
|
105
|
+
const now = this.deps.clock.now();
|
|
106
|
+
await this.deps.foundationalServiceRepository.upsert({
|
|
107
|
+
serviceId,
|
|
108
|
+
ownerKind: 'workspace',
|
|
109
|
+
ownerId: workspaceId,
|
|
110
|
+
name: '',
|
|
111
|
+
summary: '',
|
|
112
|
+
description: '',
|
|
113
|
+
capabilities: [],
|
|
114
|
+
sourceId: null,
|
|
115
|
+
sourcePath: null,
|
|
116
|
+
pinnedCommit: null,
|
|
117
|
+
createdAt: now,
|
|
118
|
+
updatedAt: now,
|
|
119
|
+
deletedAt: now,
|
|
120
|
+
});
|
|
121
|
+
await this.invalidate('workspace', workspaceId);
|
|
122
|
+
}
|
|
123
|
+
/** The merged catalog a workspace's agents see, cached per workspace. */
|
|
124
|
+
async resolve(workspaceId) {
|
|
125
|
+
if (!this.deps.catalogCache)
|
|
126
|
+
return this.loadCatalog(workspaceId);
|
|
127
|
+
return this.deps.catalogCache.get(workspaceId, workspaceId, () => this.loadCatalog(workspaceId));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The LAZY contract read: full documents for the named services, resolved against the same
|
|
131
|
+
* account ⊕ workspace precedence the catalog uses. One batched query per tier — never a
|
|
132
|
+
* per-service read — and an empty `serviceIds` returns `[]` without touching the store.
|
|
133
|
+
*
|
|
134
|
+
* Precedence matters here as much as in the catalog: a workspace that overrode a service
|
|
135
|
+
* must hand out ITS documents, or the design would be reviewed against the org's spec while
|
|
136
|
+
* the code is written against the board's.
|
|
137
|
+
*/
|
|
138
|
+
async contractsFor(workspaceId, serviceIds) {
|
|
139
|
+
const wanted = [...new Set(serviceIds)].filter(Boolean);
|
|
140
|
+
if (wanted.length === 0)
|
|
141
|
+
return new Map();
|
|
142
|
+
const accountId = await this.deps.workspaceRepository.accountOf(workspaceId);
|
|
143
|
+
const [workspaceDocs, accountDocs] = await Promise.all([
|
|
144
|
+
this.deps.apiContractRepository.listByServiceIds('workspace', workspaceId, wanted),
|
|
145
|
+
accountId
|
|
146
|
+
? this.deps.apiContractRepository.listByServiceIds('account', accountId, wanted)
|
|
147
|
+
: Promise.resolve([]),
|
|
148
|
+
]);
|
|
149
|
+
// Which TIER won for each id is decided by the catalog merge, not by which tier happens to
|
|
150
|
+
// hold documents: a workspace row that overrides an account one but ships no contract of
|
|
151
|
+
// its own must NOT silently inherit the account's documents, or the override reads as
|
|
152
|
+
// partially applied. So resolve the winning tier first, then take that tier's documents.
|
|
153
|
+
const catalog = await this.resolve(workspaceId);
|
|
154
|
+
const tierById = new Map(catalog.map((entry) => [entry.id, entry.tier]));
|
|
155
|
+
const out = new Map();
|
|
156
|
+
for (const id of wanted) {
|
|
157
|
+
const tier = tierById.get(id);
|
|
158
|
+
if (!tier)
|
|
159
|
+
continue;
|
|
160
|
+
const docs = (tier === 'workspace' ? workspaceDocs : accountDocs).filter((doc) => doc.serviceId === id);
|
|
161
|
+
out.set(id, docs.map(documentOf));
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
/** Drop a tier's cached catalog. An account write invalidates every workspace's. */
|
|
166
|
+
async invalidate(ownerKind, ownerId) {
|
|
167
|
+
if (!this.deps.catalogCache)
|
|
168
|
+
return;
|
|
169
|
+
// A workspace write affects exactly one group; an account write affects every workspace in
|
|
170
|
+
// the account, and enumerating them would be a read per invalidation — over-invalidation is
|
|
171
|
+
// always safe, so the account path drops everything (the same call `FragmentLibraryService`
|
|
172
|
+
// makes for the same reason).
|
|
173
|
+
if (ownerKind === 'workspace')
|
|
174
|
+
await this.deps.catalogCache.invalidateGroup(ownerId);
|
|
175
|
+
else
|
|
176
|
+
await this.deps.catalogCache.invalidateAll();
|
|
177
|
+
}
|
|
178
|
+
async loadCatalog(workspaceId) {
|
|
179
|
+
const accountId = await this.deps.workspaceRepository.accountOf(workspaceId);
|
|
180
|
+
const [workspaceRows, accountRows, workspaceManifest, accountManifest] = await Promise.all([
|
|
181
|
+
this.deps.foundationalServiceRepository.listByOwner('workspace', workspaceId, true),
|
|
182
|
+
accountId
|
|
183
|
+
? this.deps.foundationalServiceRepository.listByOwner('account', accountId)
|
|
184
|
+
: Promise.resolve([]),
|
|
185
|
+
this.deps.apiContractRepository.listManifestByOwner('workspace', workspaceId),
|
|
186
|
+
accountId
|
|
187
|
+
? this.deps.apiContractRepository.listManifestByOwner('account', accountId)
|
|
188
|
+
: Promise.resolve([]),
|
|
189
|
+
]);
|
|
190
|
+
return mergeFoundationalTiers({
|
|
191
|
+
accountRows,
|
|
192
|
+
workspaceRows,
|
|
193
|
+
accountManifest: indexManifest(accountManifest),
|
|
194
|
+
workspaceManifest: indexManifest(workspaceManifest),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async require(ownerKind, ownerId, serviceId) {
|
|
198
|
+
const record = await this.deps.foundationalServiceRepository.get(ownerKind, ownerId, serviceId);
|
|
199
|
+
if (!record || record.deletedAt)
|
|
200
|
+
throw new NotFoundError('FoundationalService', serviceId);
|
|
201
|
+
return record;
|
|
202
|
+
}
|
|
203
|
+
buildUploadedContracts(ownerKind, ownerId, serviceId, uploads, now) {
|
|
204
|
+
const seen = new Set();
|
|
205
|
+
return (uploads ?? []).map((upload) => {
|
|
206
|
+
if (seen.has(upload.contractId)) {
|
|
207
|
+
throw new ValidationError(`Duplicate contract id '${upload.contractId}'`, {
|
|
208
|
+
reason: 'duplicate_contract_id',
|
|
209
|
+
contractId: upload.contractId,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
seen.add(upload.contractId);
|
|
213
|
+
validateUploadedContract(upload);
|
|
214
|
+
const summary = summarizeContract({
|
|
215
|
+
contractId: upload.contractId,
|
|
216
|
+
format: upload.format,
|
|
217
|
+
title: upload.title,
|
|
218
|
+
path: null,
|
|
219
|
+
body: upload.body,
|
|
220
|
+
});
|
|
221
|
+
return {
|
|
222
|
+
ownerKind,
|
|
223
|
+
ownerId,
|
|
224
|
+
serviceId,
|
|
225
|
+
contractId: upload.contractId,
|
|
226
|
+
format: upload.format,
|
|
227
|
+
title: upload.title,
|
|
228
|
+
body: upload.body,
|
|
229
|
+
operations: summary.operations,
|
|
230
|
+
omittedOperations: summary.omittedOperations,
|
|
231
|
+
sourcePath: null,
|
|
232
|
+
sourceSha: null,
|
|
233
|
+
createdAt: now,
|
|
234
|
+
updatedAt: now,
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function indexManifest(entries) {
|
|
240
|
+
const map = new Map();
|
|
241
|
+
for (const entry of entries) {
|
|
242
|
+
const list = map.get(entry.serviceId);
|
|
243
|
+
if (list)
|
|
244
|
+
list.push(entry);
|
|
245
|
+
else
|
|
246
|
+
map.set(entry.serviceId, [entry]);
|
|
247
|
+
}
|
|
248
|
+
return map;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* A just-written contract record → its manifest entry. The operation index is recomputed from
|
|
252
|
+
* the body here rather than read back, so a create/update response describes exactly what was
|
|
253
|
+
* stored without a second round trip.
|
|
254
|
+
*/
|
|
255
|
+
function manifestOf(record) {
|
|
256
|
+
return {
|
|
257
|
+
serviceId: record.serviceId,
|
|
258
|
+
contractId: record.contractId,
|
|
259
|
+
format: record.format,
|
|
260
|
+
title: record.title,
|
|
261
|
+
size: record.body.length,
|
|
262
|
+
operations: record.operations,
|
|
263
|
+
omittedOperations: record.omittedOperations,
|
|
264
|
+
sourcePath: record.sourcePath,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* A stored record → the wire document. The operation index is read off the ROW rather than
|
|
269
|
+
* recomputed: it is the same index the catalog showed, so a consumer can never see a document
|
|
270
|
+
* whose operation list disagrees with the one the design was chosen from.
|
|
271
|
+
*/
|
|
272
|
+
function documentOf(record) {
|
|
273
|
+
return {
|
|
274
|
+
contractId: record.contractId,
|
|
275
|
+
format: record.format,
|
|
276
|
+
title: record.title,
|
|
277
|
+
size: record.body.length,
|
|
278
|
+
path: record.sourcePath,
|
|
279
|
+
operations: record.operations,
|
|
280
|
+
omittedOperations: record.omittedOperations,
|
|
281
|
+
body: record.body,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=FoundationalServiceCatalogService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FoundationalServiceCatalogService.js","sourceRoot":"","sources":["../../src/foundationalServices/FoundationalServiceCatalogService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FoundationalServiceSelection } from '@cat-factory/contracts';
|
|
2
|
+
import type { FoundationalCatalogView, InjectedContextFile } from '@cat-factory/kernel';
|
|
3
|
+
import type { FoundationalServiceCatalogService } from './FoundationalServiceCatalogService.js';
|
|
4
|
+
/**
|
|
5
|
+
* The engine-facing seam over the foundational-services catalog
|
|
6
|
+
* (docs/initiatives/foundational-services.md). Two reads, deliberately separate, because they
|
|
7
|
+
* serve the two halves of the feature:
|
|
8
|
+
*
|
|
9
|
+
* - {@link catalogFor} is the DESIGN-time read: identity, capabilities and operation names for
|
|
10
|
+
* every registered service, no document bodies. Folded into the Architect's prompt.
|
|
11
|
+
* - {@link contextFilesFor} is the CONSUMER-time read: the full contract documents, for exactly
|
|
12
|
+
* the ids the design declared, materialised as `.cat-context/foundational-services/*` files.
|
|
13
|
+
*
|
|
14
|
+
* Implemented against the catalog SERVICE rather than the repositories so both reads go through
|
|
15
|
+
* the same tier merge and the same cache — a consumer can never be handed the account's
|
|
16
|
+
* document for a service the design chose at the workspace tier.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FoundationalServiceRunResolver {
|
|
19
|
+
private readonly catalog;
|
|
20
|
+
constructor(catalog: FoundationalServiceCatalogService);
|
|
21
|
+
/** The catalog the design step is shown. Empty array when nothing is registered. */
|
|
22
|
+
catalogFor(workspaceId: string): Promise<FoundationalCatalogView[]>;
|
|
23
|
+
/** Just the ids in the merged catalog — the check a settled design's declaration runs against. */
|
|
24
|
+
catalogIdsFor(workspaceId: string): Promise<string[]>;
|
|
25
|
+
/**
|
|
26
|
+
* The injected context files a consumer kind receives for a design's declared services: one
|
|
27
|
+
* markdown file per service carrying its contract documents, plus an index.
|
|
28
|
+
*
|
|
29
|
+
* The INDEX is always produced, even when nothing was declared and nothing resolved. That is
|
|
30
|
+
* the "degrade loudly" half: a coder handed no foundational context cannot otherwise tell
|
|
31
|
+
* "the design decided none apply" from "the design step never ran" from "the design named a
|
|
32
|
+
* service this deployment does not have", and those need three different reactions.
|
|
33
|
+
*/
|
|
34
|
+
contextFilesFor(workspaceId: string, selection: FoundationalServiceSelection | undefined): Promise<InjectedContextFile[]>;
|
|
35
|
+
private hasCatalog;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=FoundationalServiceRunResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FoundationalServiceRunResolver.d.ts","sourceRoot":"","sources":["../../src/foundationalServices/FoundationalServiceRunResolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAOvF,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAA;AAE/F;;;;;;;;;;;;;GAaG;AACH,qBAAa,8BAA8B;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,iCAAiC,EAAI;IAE3E,oFAAoF;IAC9E,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAUxE;IAED,kGAAkG;IAC5F,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE1D;IAED;;;;;;;;OAQG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,4BAA4B,GAAG,SAAS,GAClD,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAyChC;YAEa,UAAU;CAGzB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { FOUNDATIONAL_INDEX_FILE, contextFileFor, renderContractDocument, renderFoundationalIndex, } from '@cat-factory/kernel';
|
|
2
|
+
/**
|
|
3
|
+
* The engine-facing seam over the foundational-services catalog
|
|
4
|
+
* (docs/initiatives/foundational-services.md). Two reads, deliberately separate, because they
|
|
5
|
+
* serve the two halves of the feature:
|
|
6
|
+
*
|
|
7
|
+
* - {@link catalogFor} is the DESIGN-time read: identity, capabilities and operation names for
|
|
8
|
+
* every registered service, no document bodies. Folded into the Architect's prompt.
|
|
9
|
+
* - {@link contextFilesFor} is the CONSUMER-time read: the full contract documents, for exactly
|
|
10
|
+
* the ids the design declared, materialised as `.cat-context/foundational-services/*` files.
|
|
11
|
+
*
|
|
12
|
+
* Implemented against the catalog SERVICE rather than the repositories so both reads go through
|
|
13
|
+
* the same tier merge and the same cache — a consumer can never be handed the account's
|
|
14
|
+
* document for a service the design chose at the workspace tier.
|
|
15
|
+
*/
|
|
16
|
+
export class FoundationalServiceRunResolver {
|
|
17
|
+
catalog;
|
|
18
|
+
constructor(catalog) {
|
|
19
|
+
this.catalog = catalog;
|
|
20
|
+
}
|
|
21
|
+
/** The catalog the design step is shown. Empty array when nothing is registered. */
|
|
22
|
+
async catalogFor(workspaceId) {
|
|
23
|
+
const resolved = await this.catalog.resolve(workspaceId);
|
|
24
|
+
return resolved.map((service) => ({
|
|
25
|
+
id: service.id,
|
|
26
|
+
name: service.name,
|
|
27
|
+
summary: service.summary,
|
|
28
|
+
description: service.description,
|
|
29
|
+
capabilities: service.capabilities,
|
|
30
|
+
contracts: service.contracts,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
/** Just the ids in the merged catalog — the check a settled design's declaration runs against. */
|
|
34
|
+
async catalogIdsFor(workspaceId) {
|
|
35
|
+
return (await this.catalog.resolve(workspaceId)).map((service) => service.id);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The injected context files a consumer kind receives for a design's declared services: one
|
|
39
|
+
* markdown file per service carrying its contract documents, plus an index.
|
|
40
|
+
*
|
|
41
|
+
* The INDEX is always produced, even when nothing was declared and nothing resolved. That is
|
|
42
|
+
* the "degrade loudly" half: a coder handed no foundational context cannot otherwise tell
|
|
43
|
+
* "the design decided none apply" from "the design step never ran" from "the design named a
|
|
44
|
+
* service this deployment does not have", and those need three different reactions.
|
|
45
|
+
*/
|
|
46
|
+
async contextFilesFor(workspaceId, selection) {
|
|
47
|
+
const declared = selection?.declared ?? [];
|
|
48
|
+
const unknown = selection?.unknown ?? [];
|
|
49
|
+
const noDeclaration = selection === undefined;
|
|
50
|
+
// Nothing to say and nothing to warn about: a run in a deployment that registers no
|
|
51
|
+
// foundational services at all would otherwise pay for an index file on every dispatch
|
|
52
|
+
// saying so. A declaration that resolved to nothing is DIFFERENT and does get the file.
|
|
53
|
+
if (noDeclaration && unknown.length === 0 && !(await this.hasCatalog(workspaceId)))
|
|
54
|
+
return [];
|
|
55
|
+
const documents = await this.catalog.contractsFor(workspaceId, declared);
|
|
56
|
+
const resolved = await this.catalog.resolve(workspaceId);
|
|
57
|
+
const byId = new Map(resolved.map((service) => [service.id, service]));
|
|
58
|
+
const bundles = declared
|
|
59
|
+
.map((id) => {
|
|
60
|
+
const service = byId.get(id);
|
|
61
|
+
if (!service)
|
|
62
|
+
return null;
|
|
63
|
+
return {
|
|
64
|
+
id: service.id,
|
|
65
|
+
name: service.name,
|
|
66
|
+
summary: service.summary,
|
|
67
|
+
description: service.description,
|
|
68
|
+
contracts: (documents.get(id) ?? []).map((doc) => ({
|
|
69
|
+
contractId: doc.contractId,
|
|
70
|
+
format: doc.format,
|
|
71
|
+
title: doc.title,
|
|
72
|
+
body: doc.body,
|
|
73
|
+
})),
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
.filter((bundle) => bundle !== null);
|
|
77
|
+
const files = [
|
|
78
|
+
{
|
|
79
|
+
path: FOUNDATIONAL_INDEX_FILE,
|
|
80
|
+
content: renderFoundationalIndex({ bundles, unknown, noDeclaration }),
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
for (const bundle of bundles) {
|
|
84
|
+
files.push({ path: contextFileFor(bundle.id), content: renderContractDocument(bundle) });
|
|
85
|
+
}
|
|
86
|
+
return files;
|
|
87
|
+
}
|
|
88
|
+
async hasCatalog(workspaceId) {
|
|
89
|
+
return (await this.catalog.resolve(workspaceId)).length > 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=FoundationalServiceRunResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FoundationalServiceRunResolver.js","sourceRoot":"","sources":["../../src/foundationalServices/FoundationalServiceRunResolver.ts"],"names":[],"mappings":"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"}
|