@cat-factory/node-server 0.6.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/LICENSE +21 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +297 -0
- package/dist/config.js.map +1 -0
- package/dist/container.d.ts +88 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +937 -0
- package/dist/container.js.map +1 -0
- package/dist/db/client.d.ts +13 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +21 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/migrate.d.ts +12 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +40 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/schema.d.ts +7858 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +928 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/environments.d.ts +11 -0
- package/dist/environments.d.ts.map +1 -0
- package/dist/environments.js +31 -0
- package/dist/environments.js.map +1 -0
- package/dist/execution/bootstrapRunner.d.ts +27 -0
- package/dist/execution/bootstrapRunner.d.ts.map +1 -0
- package/dist/execution/bootstrapRunner.js +79 -0
- package/dist/execution/bootstrapRunner.js.map +1 -0
- package/dist/execution/config.d.ts +37 -0
- package/dist/execution/config.d.ts.map +1 -0
- package/dist/execution/config.js +86 -0
- package/dist/execution/config.js.map +1 -0
- package/dist/execution/drive.d.ts +6 -0
- package/dist/execution/drive.d.ts.map +1 -0
- package/dist/execution/drive.js +13 -0
- package/dist/execution/drive.js.map +1 -0
- package/dist/execution/pgBossRunner.d.ts +82 -0
- package/dist/execution/pgBossRunner.d.ts.map +1 -0
- package/dist/execution/pgBossRunner.js +163 -0
- package/dist/execution/pgBossRunner.js.map +1 -0
- package/dist/gateways.d.ts +4 -0
- package/dist/gateways.d.ts.map +1 -0
- package/dist/gateways.js +91 -0
- package/dist/gateways.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +9 -0
- package/dist/main.js.map +1 -0
- package/dist/modelProvider.d.ts +6 -0
- package/dist/modelProvider.d.ts.map +1 -0
- package/dist/modelProvider.js +72 -0
- package/dist/modelProvider.js.map +1 -0
- package/dist/realtime.d.ts +62 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +171 -0
- package/dist/realtime.js.map +1 -0
- package/dist/recurring.d.ts +11 -0
- package/dist/recurring.d.ts.map +1 -0
- package/dist/recurring.js +33 -0
- package/dist/recurring.js.map +1 -0
- package/dist/repositories/bootstrap.d.ts +25 -0
- package/dist/repositories/bootstrap.d.ts.map +1 -0
- package/dist/repositories/bootstrap.js +280 -0
- package/dist/repositories/bootstrap.js.map +1 -0
- package/dist/repositories/containerExecution.d.ts +33 -0
- package/dist/repositories/containerExecution.d.ts.map +1 -0
- package/dist/repositories/containerExecution.js +199 -0
- package/dist/repositories/containerExecution.js.map +1 -0
- package/dist/repositories/documents.d.ts +31 -0
- package/dist/repositories/documents.d.ts.map +1 -0
- package/dist/repositories/documents.js +176 -0
- package/dist/repositories/documents.js.map +1 -0
- package/dist/repositories/drizzle.d.ts +105 -0
- package/dist/repositories/drizzle.d.ts.map +1 -0
- package/dist/repositories/drizzle.js +1872 -0
- package/dist/repositories/drizzle.js.map +1 -0
- package/dist/repositories/environments.d.ts +23 -0
- package/dist/repositories/environments.d.ts.map +1 -0
- package/dist/repositories/environments.js +162 -0
- package/dist/repositories/environments.js.map +1 -0
- package/dist/repositories/fragments.d.ts +23 -0
- package/dist/repositories/fragments.d.ts.map +1 -0
- package/dist/repositories/fragments.js +190 -0
- package/dist/repositories/fragments.js.map +1 -0
- package/dist/repositories/github.d.ts +53 -0
- package/dist/repositories/github.d.ts.map +1 -0
- package/dist/repositories/github.js +441 -0
- package/dist/repositories/github.js.map +1 -0
- package/dist/repositories/localModelEndpoint.d.ts +12 -0
- package/dist/repositories/localModelEndpoint.d.ts.map +1 -0
- package/dist/repositories/localModelEndpoint.js +75 -0
- package/dist/repositories/localModelEndpoint.js.map +1 -0
- package/dist/repositories/notifications.d.ts +11 -0
- package/dist/repositories/notifications.d.ts.map +1 -0
- package/dist/repositories/notifications.js +88 -0
- package/dist/repositories/notifications.js.map +1 -0
- package/dist/repositories/personalSubscription.d.ts +22 -0
- package/dist/repositories/personalSubscription.d.ts.map +1 -0
- package/dist/repositories/personalSubscription.js +159 -0
- package/dist/repositories/personalSubscription.js.map +1 -0
- package/dist/repositories/providerApiKey.d.ts +18 -0
- package/dist/repositories/providerApiKey.d.ts.map +1 -0
- package/dist/repositories/providerApiKey.js +111 -0
- package/dist/repositories/providerApiKey.js.map +1 -0
- package/dist/repositories/providerSubscription.d.ts +16 -0
- package/dist/repositories/providerSubscription.d.ts.map +1 -0
- package/dist/repositories/providerSubscription.js +88 -0
- package/dist/repositories/providerSubscription.js.map +1 -0
- package/dist/repositories/slack.d.ts +23 -0
- package/dist/repositories/slack.d.ts.map +1 -0
- package/dist/repositories/slack.js +150 -0
- package/dist/repositories/slack.js.map +1 -0
- package/dist/repositories/tasks.d.ts +24 -0
- package/dist/repositories/tasks.d.ts.map +1 -0
- package/dist/repositories/tasks.js +194 -0
- package/dist/repositories/tasks.js.map +1 -0
- package/dist/retention.d.ts +38 -0
- package/dist/retention.d.ts.map +1 -0
- package/dist/retention.js +53 -0
- package/dist/retention.js.map +1 -0
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +13 -0
- package/dist/runtime.js.map +1 -0
- package/dist/server.d.ts +41 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +138 -0
- package/dist/server.js.map +1 -0
- package/dist/tasks/JiraProvider.d.ts +27 -0
- package/dist/tasks/JiraProvider.d.ts.map +1 -0
- package/dist/tasks/JiraProvider.js +79 -0
- package/dist/tasks/JiraProvider.js.map +1 -0
- package/drizzle/20260622175812_flashy_maginty/migration.sql +689 -0
- package/drizzle/20260622175812_flashy_maginty/snapshot.json +8318 -0
- package/drizzle/20260623172634_loud_wallop/migration.sql +11 -0
- package/drizzle/20260623172634_loud_wallop/snapshot.json +8439 -0
- package/drizzle/20260623174706_acoustic_zemo/migration.sql +16 -0
- package/drizzle/20260623174706_acoustic_zemo/snapshot.json +8506 -0
- package/drizzle/20260623184400_silent_cardiac/migration.sql +24 -0
- package/drizzle/20260623184400_silent_cardiac/snapshot.json +8639 -0
- package/drizzle/20260623205323_quick_arclight/migration.sql +1 -0
- package/drizzle/20260623205323_quick_arclight/snapshot.json +8963 -0
- package/drizzle/20260623221910_black_zombie/migration.sql +22 -0
- package/drizzle/20260623221910_black_zombie/snapshot.json +9189 -0
- package/drizzle/20260624131343_far_lily_hollister/migration.sql +3 -0
- package/drizzle/20260624131343_far_lily_hollister/snapshot.json +9228 -0
- package/drizzle/20260624135452_tiny_norman_osborn/migration.sql +11 -0
- package/drizzle/20260624135452_tiny_norman_osborn/snapshot.json +9126 -0
- package/drizzle/20260624140138_wandering_avengers/migration.sql +1 -0
- package/drizzle/20260624140138_wandering_avengers/snapshot.json +9045 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Igor Savin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,qBAAqB,CAAA;AA8FlF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAqOhE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { ALL_SUBSCRIPTION_VENDORS, effectiveCatalog, resolveModelRef, } from '@cat-factory/kernel';
|
|
2
|
+
import { DEFAULT_SPEND_PRICING, modelCostResolver } from '@cat-factory/spend';
|
|
3
|
+
// Translate the Node process environment into the shared AppConfig contract. This is
|
|
4
|
+
// the Node analogue of the Worker's `loadConfig(env)`: same SHAPE, different source.
|
|
5
|
+
// Integrations (GitHub/documents/tasks/environments/runners/fragment-library) default
|
|
6
|
+
// to disabled in this MVP; the core (board/workspaces/pipelines/executions/spend +
|
|
7
|
+
// auth) is fully configured from env.
|
|
8
|
+
const MIN_SESSION_SECRET_LENGTH = 32;
|
|
9
|
+
const PRODUCTION_ENVIRONMENTS = new Set(['production', 'prod', 'staging']);
|
|
10
|
+
function num(value) {
|
|
11
|
+
if (value === undefined || value.trim() === '')
|
|
12
|
+
return undefined;
|
|
13
|
+
const n = Number(value);
|
|
14
|
+
return Number.isFinite(n) ? n : undefined;
|
|
15
|
+
}
|
|
16
|
+
function csv(value) {
|
|
17
|
+
return (value ?? '')
|
|
18
|
+
.split(',')
|
|
19
|
+
.map((s) => s.trim())
|
|
20
|
+
.filter(Boolean);
|
|
21
|
+
}
|
|
22
|
+
// The task sources the Node facade can serve, mirroring the Worker's `ALL_SOURCES`.
|
|
23
|
+
// GitHub issues reuse the workspace's installed GitHub App (wired in the container
|
|
24
|
+
// only when a GitHub client is available); Jira carries its own per-workspace creds.
|
|
25
|
+
const NODE_TASK_SOURCES = ['jira', 'github'];
|
|
26
|
+
const ALL_DOCUMENT_SOURCES = ['confluence', 'notion', 'github'];
|
|
27
|
+
/** Parse the comma-separated `DOCUMENT_SOURCES` allow-list, defaulting to all. */
|
|
28
|
+
function parseDocumentSources(raw) {
|
|
29
|
+
const requested = csv(raw).map((s) => s.toLowerCase());
|
|
30
|
+
if (requested.length === 0)
|
|
31
|
+
return [...ALL_DOCUMENT_SOURCES];
|
|
32
|
+
const selected = ALL_DOCUMENT_SOURCES.filter((s) => requested.includes(s));
|
|
33
|
+
return selected.length > 0 ? selected : [...ALL_DOCUMENT_SOURCES];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Document-source integration config, mirroring the Worker's `loadDocumentsConfig`:
|
|
37
|
+
* always on (tenants connect Notion/Confluence/GitHub-docs through the UI), with the
|
|
38
|
+
* shared ENCRYPTION_KEY backing per-workspace credential encryption at rest. The
|
|
39
|
+
* planner defaults to LLM mode; the container only wires a model provider when one is
|
|
40
|
+
* configured, so absent that the planner degrades to its deterministic heading parser.
|
|
41
|
+
*/
|
|
42
|
+
function loadDocumentsConfig(env) {
|
|
43
|
+
const encryptionKey = env.ENCRYPTION_KEY?.trim();
|
|
44
|
+
if (!encryptionKey) {
|
|
45
|
+
throw new Error('ENCRYPTION_KEY is required: the document-source integration (Notion, Confluence, …) ' +
|
|
46
|
+
'encrypts per-workspace source credentials at rest. Set it to a base64-encoded key of ' +
|
|
47
|
+
'at least 32 bytes.');
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
enabled: true,
|
|
51
|
+
sources: parseDocumentSources(env.DOCUMENT_SOURCES),
|
|
52
|
+
planner: env.DOCUMENT_PLANNER?.trim() === 'headings' ? 'headings' : 'llm',
|
|
53
|
+
encryptionKey,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Task-source integration config, mirroring the Worker's `loadTasksConfig`: always on
|
|
58
|
+
* (tenants connect their own trackers through the UI, so there is no enable flag), with
|
|
59
|
+
* a mandatory encryption key so credentials are never stored in plaintext. The key is
|
|
60
|
+
* missing → fail loudly at config load rather than silently disabling the feature.
|
|
61
|
+
* `TASK_SOURCES` narrows the registered providers (defaults to all Node-supported ones).
|
|
62
|
+
*/
|
|
63
|
+
function loadTasksConfig(env) {
|
|
64
|
+
// The shared ENCRYPTION_KEY backs every integration (the cipher domain-separates per
|
|
65
|
+
// integration via its HKDF `info`, so one key safely backs them all).
|
|
66
|
+
const encryptionKey = env.ENCRYPTION_KEY?.trim();
|
|
67
|
+
if (!encryptionKey) {
|
|
68
|
+
throw new Error('ENCRYPTION_KEY is required: the task-source integration (Jira, …) encrypts ' +
|
|
69
|
+
'per-workspace source credentials at rest. Set it to a base64-encoded key of at ' +
|
|
70
|
+
'least 32 bytes.');
|
|
71
|
+
}
|
|
72
|
+
const requested = csv(env.TASK_SOURCES).map((s) => s.toLowerCase());
|
|
73
|
+
const sources = requested.length > 0
|
|
74
|
+
? NODE_TASK_SOURCES.filter((s) => requested.includes(s))
|
|
75
|
+
: [...NODE_TASK_SOURCES];
|
|
76
|
+
return {
|
|
77
|
+
enabled: true,
|
|
78
|
+
sources: sources.length > 0 ? sources : [...NODE_TASK_SOURCES],
|
|
79
|
+
encryptionKey,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function loadNodeConfig(env) {
|
|
83
|
+
// Deployment-level capabilities: direct keys are per-workspace (resolved at run time
|
|
84
|
+
// from the DB pool), so none are known here; Cloudflare Workers AI is opt-in over
|
|
85
|
+
// REST (account id + API token). The per-workspace `/models` endpoint recomputes
|
|
86
|
+
// selectability against each workspace's configured keys + subscriptions.
|
|
87
|
+
const caps = {
|
|
88
|
+
directProviders: new Set(),
|
|
89
|
+
subscriptionVendors: new Set(ALL_SUBSCRIPTION_VENDORS),
|
|
90
|
+
cloudflareEnabled: !!(env.CLOUDFLARE_ACCOUNT_ID && env.CLOUDFLARE_API_TOKEN),
|
|
91
|
+
};
|
|
92
|
+
// Default unpinned agents to Qwen (the Cloudflare flavour when enabled, upgraded to
|
|
93
|
+
// direct DashScope per-workspace by the executor when a Qwen key is configured); the
|
|
94
|
+
// agentic kinds default to GLM-5.2 — mirroring the Worker's routing.
|
|
95
|
+
const qwenDefault = resolveModelRef('qwen', caps);
|
|
96
|
+
const defaultConfig = {
|
|
97
|
+
ref: {
|
|
98
|
+
provider: env.AGENT_DEFAULT_PROVIDER ?? qwenDefault?.provider ?? 'workers-ai',
|
|
99
|
+
model: env.AGENT_DEFAULT_MODEL ?? qwenDefault?.model ?? '@cf/qwen/qwen3-30b-a3b-fp8',
|
|
100
|
+
},
|
|
101
|
+
temperature: num(env.AGENT_DEFAULT_TEMPERATURE) ?? 0.4,
|
|
102
|
+
maxOutputTokens: num(env.AGENT_MAX_OUTPUT_TOKENS) ?? 5000,
|
|
103
|
+
};
|
|
104
|
+
const agenticDefault = {
|
|
105
|
+
ref: { provider: 'workers-ai', model: '@cf/zai-org/glm-5.2' },
|
|
106
|
+
temperature: num(env.AGENT_DEFAULT_TEMPERATURE) ?? 0.3,
|
|
107
|
+
maxOutputTokens: num(env.AGENT_MAX_OUTPUT_TOKENS) ?? 5000,
|
|
108
|
+
};
|
|
109
|
+
// Companions (reviewer / spec-companion / architect-companion) return their whole
|
|
110
|
+
// verdict — rating + summary + per-item comments — as ONE inline JSON reply. On a
|
|
111
|
+
// reasoning model the <think> tokens share the output budget, so the 5000 cap can
|
|
112
|
+
// truncate the JSON mid-comment, leaving it unparseable. Give companions a larger
|
|
113
|
+
// budget so the verdict fits (mirrors the Worker's routing).
|
|
114
|
+
const companionDefault = {
|
|
115
|
+
ref: { provider: 'workers-ai', model: '@cf/zai-org/glm-5.2' },
|
|
116
|
+
temperature: num(env.AGENT_DEFAULT_TEMPERATURE) ?? 0.3,
|
|
117
|
+
maxOutputTokens: num(env.AGENT_MAX_OUTPUT_TOKENS) ?? 12000,
|
|
118
|
+
};
|
|
119
|
+
const sessionSecret = env.AUTH_SESSION_SECRET?.trim() ?? '';
|
|
120
|
+
// The GitHub App (private key + app id) backs container-agent runs: it mints the
|
|
121
|
+
// short-lived push token the harness clones/pushes with. Enable the integration
|
|
122
|
+
// only when both are present (the container executor also requires it — see
|
|
123
|
+
// container.ts), so a partial config doesn't half-enable repo-operating steps.
|
|
124
|
+
const githubAppId = env.GITHUB_APP_ID?.trim() ?? '';
|
|
125
|
+
const githubAppConfigured = githubAppId !== '' && (env.GITHUB_APP_PRIVATE_KEY?.trim() ?? '') !== '';
|
|
126
|
+
// Self-hosted runner pools encrypt their scheduler credentials at rest; opt-in via
|
|
127
|
+
// the enable flag, sealed with the shared ENCRYPTION_KEY (mirroring the Worker).
|
|
128
|
+
const runnersEncryptionKey = env.ENCRYPTION_KEY?.trim() ?? '';
|
|
129
|
+
// Slack notification transport: opt-in (SLACK_ENABLED), the per-account bot token
|
|
130
|
+
// sealed with the shared ENCRYPTION_KEY. OAuth credentials are optional (manual
|
|
131
|
+
// bot-token onboarding works without them); when set they enable "Add to Slack".
|
|
132
|
+
const slackEnabled = env.SLACK_ENABLED?.trim() === 'true';
|
|
133
|
+
const slackEncryptionKey = env.ENCRYPTION_KEY?.trim() ?? '';
|
|
134
|
+
const slackClientId = env.SLACK_CLIENT_ID?.trim() ?? '';
|
|
135
|
+
const slackClientSecret = env.SLACK_CLIENT_SECRET?.trim() ?? '';
|
|
136
|
+
const slackRedirectUrl = env.SLACK_REDIRECT_URL?.trim() ?? '';
|
|
137
|
+
const slackOAuth = slackClientId && slackClientSecret && slackRedirectUrl
|
|
138
|
+
? { clientId: slackClientId, clientSecret: slackClientSecret, redirectUrl: slackRedirectUrl }
|
|
139
|
+
: undefined;
|
|
140
|
+
const clientId = env.GITHUB_OAUTH_CLIENT_ID?.trim() ?? '';
|
|
141
|
+
const clientSecret = env.GITHUB_OAUTH_CLIENT_SECRET?.trim() ?? '';
|
|
142
|
+
const googleClientId = env.GOOGLE_OAUTH_CLIENT_ID?.trim() ?? '';
|
|
143
|
+
const googleClientSecret = env.GOOGLE_OAUTH_CLIENT_SECRET?.trim() ?? '';
|
|
144
|
+
const environment = env.ENVIRONMENT?.trim().toLowerCase() ?? '';
|
|
145
|
+
const ttlHours = num(env.AUTH_SESSION_TTL_HOURS);
|
|
146
|
+
const strongSecret = sessionSecret.length >= MIN_SESSION_SECRET_LENGTH;
|
|
147
|
+
const githubEnabled = clientId !== '' && clientSecret !== '' && strongSecret;
|
|
148
|
+
const googleEnabled = googleClientId !== '' && googleClientSecret !== '' && strongSecret;
|
|
149
|
+
const passwordEnabled = env.AUTH_PASSWORD_ENABLED?.trim() === 'true' && strongSecret;
|
|
150
|
+
const devOpen = env.AUTH_DEV_OPEN?.trim() === 'true' && !PRODUCTION_ENVIRONMENTS.has(environment);
|
|
151
|
+
// Fail fast on the silent-brick footgun: OAuth credentials are set (so real auth is
|
|
152
|
+
// intended) but the session secret is missing/too short, which would disable the auth
|
|
153
|
+
// gate and — with no dev-open fallback — make it fail closed, 503-ing every protected
|
|
154
|
+
// route with no hint why. Refuse to boot with a clear message instead.
|
|
155
|
+
if (clientId !== '' &&
|
|
156
|
+
clientSecret !== '' &&
|
|
157
|
+
sessionSecret.length < MIN_SESSION_SECRET_LENGTH &&
|
|
158
|
+
!devOpen) {
|
|
159
|
+
throw new Error(`AUTH_SESSION_SECRET must be at least ${MIN_SESSION_SECRET_LENGTH} characters when GitHub OAuth is configured ` +
|
|
160
|
+
`(got ${sessionSecret.length}). Set a longer secret or enable AUTH_DEV_OPEN in a non-production environment.`);
|
|
161
|
+
}
|
|
162
|
+
const spend = {
|
|
163
|
+
...DEFAULT_SPEND_PRICING,
|
|
164
|
+
currency: env.SPEND_CURRENCY?.trim() || DEFAULT_SPEND_PRICING.currency,
|
|
165
|
+
monthlyLimit: num(env.SPEND_MONTHLY_LIMIT) ?? DEFAULT_SPEND_PRICING.monthlyLimit,
|
|
166
|
+
};
|
|
167
|
+
return {
|
|
168
|
+
agents: {
|
|
169
|
+
routing: {
|
|
170
|
+
default: defaultConfig,
|
|
171
|
+
byKind: {
|
|
172
|
+
architect: agenticDefault,
|
|
173
|
+
coder: agenticDefault,
|
|
174
|
+
reviewer: companionDefault,
|
|
175
|
+
'spec-companion': companionDefault,
|
|
176
|
+
'architect-companion': companionDefault,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
resolveBlockModel: (modelId) => resolveModelRef(modelId, caps),
|
|
180
|
+
},
|
|
181
|
+
// Surface each model's informational list cost in the picker (from spend pricing).
|
|
182
|
+
models: effectiveCatalog(caps, modelCostResolver(spend)),
|
|
183
|
+
execution: {
|
|
184
|
+
decisionTimeout: env.DECISION_TIMEOUT?.trim() || '24 hours',
|
|
185
|
+
jobPollInterval: env.JOB_POLL_INTERVAL?.trim() || '15 seconds',
|
|
186
|
+
jobMaxPolls: num(env.JOB_MAX_POLLS) ?? 280,
|
|
187
|
+
jobPollFailureTolerance: num(env.JOB_POLL_FAILURE_TOLERANCE) ?? 6,
|
|
188
|
+
ciPollInterval: env.CI_POLL_INTERVAL?.trim() || '30 seconds',
|
|
189
|
+
ciMaxPolls: num(env.CI_MAX_POLLS) ?? 120,
|
|
190
|
+
containerMaxAgeMs: Math.max(75, num(env.CONTAINER_MAX_AGE_MINUTES) ?? 90) * 60_000,
|
|
191
|
+
},
|
|
192
|
+
spend,
|
|
193
|
+
github: {
|
|
194
|
+
enabled: githubAppConfigured,
|
|
195
|
+
appId: env.GITHUB_APP_ID?.trim() ?? '',
|
|
196
|
+
appSlug: env.GITHUB_APP_SLUG?.trim() ?? '',
|
|
197
|
+
apiBase: env.GITHUB_API_BASE?.trim() || 'https://api.github.com',
|
|
198
|
+
setupRedirectUrl: env.GITHUB_SETUP_REDIRECT_URL?.trim() || '/',
|
|
199
|
+
webhookSecret: env.GITHUB_WEBHOOK_SECRET ?? '',
|
|
200
|
+
},
|
|
201
|
+
auth: {
|
|
202
|
+
enabled: githubEnabled || googleEnabled || passwordEnabled,
|
|
203
|
+
devOpen,
|
|
204
|
+
githubEnabled,
|
|
205
|
+
clientId,
|
|
206
|
+
clientSecret,
|
|
207
|
+
sessionSecret,
|
|
208
|
+
apiBase: env.GITHUB_API_BASE?.trim() || 'https://api.github.com',
|
|
209
|
+
oauthBase: env.GITHUB_OAUTH_BASE?.trim() || 'https://github.com',
|
|
210
|
+
sessionTtlMs: (ttlHours !== undefined && ttlHours > 0 ? ttlHours : 168) * 60 * 60 * 1000,
|
|
211
|
+
successRedirectUrl: env.AUTH_SUCCESS_REDIRECT_URL?.trim() || '',
|
|
212
|
+
callbackUrl: env.AUTH_CALLBACK_URL?.trim() || '',
|
|
213
|
+
passwordEnabled,
|
|
214
|
+
...(googleEnabled
|
|
215
|
+
? {
|
|
216
|
+
google: {
|
|
217
|
+
clientId: googleClientId,
|
|
218
|
+
clientSecret: googleClientSecret,
|
|
219
|
+
redirectUrl: env.GOOGLE_OAUTH_REDIRECT_URL?.trim() || '',
|
|
220
|
+
},
|
|
221
|
+
}
|
|
222
|
+
: {}),
|
|
223
|
+
allowedEmailDomains: csv(env.AUTH_ALLOWED_EMAIL_DOMAINS).map((d) => d.toLowerCase()),
|
|
224
|
+
allowedLogins: csv(env.AUTH_ALLOWED_LOGINS).map((l) => l.toLowerCase()),
|
|
225
|
+
allowedOrgs: csv(env.AUTH_ALLOWED_ORGS).map((o) => o.toLowerCase()),
|
|
226
|
+
allowedRedirectOrigins: csv(env.AUTH_ALLOWED_REDIRECT_ORIGINS).map((o) => {
|
|
227
|
+
try {
|
|
228
|
+
return new URL(o).origin;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return o;
|
|
232
|
+
}
|
|
233
|
+
}),
|
|
234
|
+
},
|
|
235
|
+
email: env.EMAIL_ENABLED?.trim() === 'true' && env.ENCRYPTION_KEY?.trim()
|
|
236
|
+
? {
|
|
237
|
+
enabled: true,
|
|
238
|
+
encryptionKey: env.ENCRYPTION_KEY.trim(),
|
|
239
|
+
appBaseUrl: env.APP_BASE_URL?.trim() || env.AUTH_SUCCESS_REDIRECT_URL?.trim() || '',
|
|
240
|
+
}
|
|
241
|
+
: {
|
|
242
|
+
enabled: false,
|
|
243
|
+
appBaseUrl: env.APP_BASE_URL?.trim() || env.AUTH_SUCCESS_REDIRECT_URL?.trim() || '',
|
|
244
|
+
},
|
|
245
|
+
// Document-source integration: the providers (Confluence/Notion/GitHub-docs) are
|
|
246
|
+
// the shared `@cat-factory/integrations` fetch shells, wired in the container
|
|
247
|
+
// exactly like the Worker's `selectDocumentsDeps`. Always on (the shared
|
|
248
|
+
// ENCRYPTION_KEY backs credential encryption at rest).
|
|
249
|
+
documents: loadDocumentsConfig(env),
|
|
250
|
+
tasks: loadTasksConfig(env),
|
|
251
|
+
// Ephemeral-environment provider integration: opt-in (a tenant rolls its own
|
|
252
|
+
// environment-management API), gated on ENVIRONMENTS_ENABLED + the shared
|
|
253
|
+
// ENCRYPTION_KEY (credentials are encrypted at rest), mirroring the Worker.
|
|
254
|
+
environments: env.ENVIRONMENTS_ENABLED === 'true' && env.ENCRYPTION_KEY?.trim()
|
|
255
|
+
? { enabled: true, encryptionKey: env.ENCRYPTION_KEY.trim() }
|
|
256
|
+
: { enabled: false },
|
|
257
|
+
runners: runnersEncryptionKey
|
|
258
|
+
? { enabled: true, encryptionKey: runnersEncryptionKey }
|
|
259
|
+
: { enabled: false },
|
|
260
|
+
slack: slackEnabled && slackEncryptionKey
|
|
261
|
+
? {
|
|
262
|
+
enabled: true,
|
|
263
|
+
encryptionKey: slackEncryptionKey,
|
|
264
|
+
...(slackOAuth ? { oauth: slackOAuth } : {}),
|
|
265
|
+
}
|
|
266
|
+
: { enabled: false },
|
|
267
|
+
retention: {
|
|
268
|
+
tokenUsageMs: (num(env.TOKEN_USAGE_RETENTION_DAYS) ?? 395) * 24 * 60 * 60 * 1000,
|
|
269
|
+
rateLimitMs: (num(env.GITHUB_RATE_LIMIT_RETENTION_DAYS) ?? 7) * 24 * 60 * 60 * 1000,
|
|
270
|
+
commitMs: (num(env.GITHUB_COMMIT_RETENTION_DAYS) ?? 90) * 24 * 60 * 60 * 1000,
|
|
271
|
+
// Heavy full per-call prompt/response; pruned aggressively (default 3 days).
|
|
272
|
+
llmCallMetricsMs: (num(env.LLM_CALL_METRICS_RETENTION_DAYS) ?? 3) * 24 * 60 * 60 * 1000,
|
|
273
|
+
},
|
|
274
|
+
// Prompt-fragment library (ADR 0006): opt-in (`PROMPT_LIBRARY_ENABLED=true`),
|
|
275
|
+
// needs no encryption key (fragments are not secrets). Mirrors the Worker's
|
|
276
|
+
// mapping; `PROMPT_LIBRARY_SELECTOR=llm` ranks per run, else the deterministic
|
|
277
|
+
// tag matcher (which also backs the `llm` selector's graceful fallback).
|
|
278
|
+
fragmentLibrary: {
|
|
279
|
+
enabled: env.PROMPT_LIBRARY_ENABLED?.trim() === 'true',
|
|
280
|
+
selector: env.PROMPT_LIBRARY_SELECTOR?.trim() === 'llm' ? 'llm' : 'deterministic',
|
|
281
|
+
},
|
|
282
|
+
// Recording the complete prompts is on by default; opt out with
|
|
283
|
+
// `LLM_RECORD_PROMPTS=false` to keep the numeric telemetry but drop the prompt body.
|
|
284
|
+
observability: { recordPrompts: env.LLM_RECORD_PROMPTS?.trim() !== 'false' },
|
|
285
|
+
// Optional Langfuse trace sink: off unless `LANGFUSE_ENABLED=true` AND both keys are
|
|
286
|
+
// present (a half-configured sink silently does nothing). Mirrors the Worker mapping.
|
|
287
|
+
langfuse: {
|
|
288
|
+
enabled: env.LANGFUSE_ENABLED?.trim() === 'true' &&
|
|
289
|
+
!!env.LANGFUSE_PUBLIC_KEY?.trim() &&
|
|
290
|
+
!!env.LANGFUSE_SECRET_KEY?.trim(),
|
|
291
|
+
publicKey: env.LANGFUSE_PUBLIC_KEY?.trim(),
|
|
292
|
+
secretKey: env.LANGFUSE_SECRET_KEY?.trim(),
|
|
293
|
+
baseUrl: env.LANGFUSE_BASE_URL?.trim() || undefined,
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type GitHubClient, type GitHubInstallationRepository } from '@cat-factory/kernel';
|
|
2
|
+
import { type CoreDependencies } from '@cat-factory/orchestration';
|
|
3
|
+
import { type AppConfig, type ResolveRunnerTransport, type ServerContainer } from '@cat-factory/server';
|
|
4
|
+
import type { PgBoss } from 'pg-boss';
|
|
5
|
+
import type { DrizzleDb } from './db/client.js';
|
|
6
|
+
import { type NodeRealtimeHub } from './realtime.js';
|
|
7
|
+
import { createDrizzleRepositories } from './repositories/drizzle.js';
|
|
8
|
+
export interface NodeContainerOptions {
|
|
9
|
+
/** The Drizzle/Postgres client (the single persistence layer). */
|
|
10
|
+
db: DrizzleDb;
|
|
11
|
+
/**
|
|
12
|
+
* Pre-built repositories; defaults to building them from {@link db}. Lets the caller
|
|
13
|
+
* (e.g. {@link start}) share one set with the retention sweeper rather than rebuild.
|
|
14
|
+
*/
|
|
15
|
+
repos?: ReturnType<typeof createDrizzleRepositories>;
|
|
16
|
+
/**
|
|
17
|
+
* Started pg-boss instance for durable execution. When present the container wires
|
|
18
|
+
* a {@link PgBossWorkRunner}; otherwise runs fall back to the engine's NoopWorkRunner
|
|
19
|
+
* (the caller drives runs itself — e.g. tests).
|
|
20
|
+
*/
|
|
21
|
+
boss?: PgBoss;
|
|
22
|
+
/** Pre-resolved config; defaults to `loadNodeConfig(env)`. */
|
|
23
|
+
config?: AppConfig;
|
|
24
|
+
/** Environment source; defaults to `process.env`. */
|
|
25
|
+
env?: NodeJS.ProcessEnv;
|
|
26
|
+
/** Override core dependencies — used by tests (e.g. a fake agent executor). */
|
|
27
|
+
overrides?: Partial<CoreDependencies>;
|
|
28
|
+
/**
|
|
29
|
+
* Override the runner backend the container-agent steps dispatch to. When provided
|
|
30
|
+
* (even as `null`) it REPLACES the default self-hosted-pool resolution, so a sibling
|
|
31
|
+
* facade can supply its own transport (e.g. the local-mode Docker transport) without
|
|
32
|
+
* registering a runner pool. Undefined → the default Node behaviour (resolve a
|
|
33
|
+
* workspace's self-hosted pool when runner pools are enabled).
|
|
34
|
+
*/
|
|
35
|
+
resolveTransport?: ResolveRunnerTransport | null;
|
|
36
|
+
/**
|
|
37
|
+
* Override how the container executor mints the push/clone token. When provided it
|
|
38
|
+
* REPLACES the GitHub-App token mint, so a sibling facade can authenticate with a
|
|
39
|
+
* static credential instead of an App installation (e.g. a PAT in local mode). The
|
|
40
|
+
* `installationId` argument is then ignored. Undefined → mint via the GitHub App
|
|
41
|
+
* (requires `GITHUB_APP_PRIVATE_KEY`).
|
|
42
|
+
*/
|
|
43
|
+
mintInstallationToken?: (installationId: number) => Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* A GitHub client used to wire the CI gate + the merge / mergeability providers
|
|
46
|
+
* (so a run gates on real CI and merges for real). When provided, the
|
|
47
|
+
* `ciStatusProvider`, `mergeabilityProvider` and `pullRequestMerger` are wired from
|
|
48
|
+
* it + the resolved repo target. Undefined → those gates pass through (the existing
|
|
49
|
+
* Node behaviour). The local facade passes a PAT-backed client.
|
|
50
|
+
*/
|
|
51
|
+
githubClient?: GitHubClient;
|
|
52
|
+
/**
|
|
53
|
+
* Override the GitHub installation repository. When provided it REPLACES the default
|
|
54
|
+
* Drizzle one, so a sibling facade can wrap it — e.g. local mode decorates it to
|
|
55
|
+
* auto-provision a synthetic per-workspace installation for its PAT, since there is no
|
|
56
|
+
* GitHub-App connect flow. Undefined → the default Drizzle repository over {@link db}.
|
|
57
|
+
*/
|
|
58
|
+
githubInstallationRepository?: GitHubInstallationRepository;
|
|
59
|
+
/**
|
|
60
|
+
* Force the Cloudflare-AI opt-in flag (the cross-runtime conformance suite forces it
|
|
61
|
+
* off for parity). Undefined → derived from the REST credentials being present.
|
|
62
|
+
*/
|
|
63
|
+
cloudflareModelsEnabled?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* The real-time subscriber registry. When provided, the container wires a
|
|
66
|
+
* {@link NodeEventPublisher} (so the engine pushes execution/board/notification events
|
|
67
|
+
* to subscribed browsers) and composes an in-app notification channel. `start()`
|
|
68
|
+
* creates the hub and attaches it to the HTTP server via {@link attachRealtime};
|
|
69
|
+
* `createServer`/tests leave it unset and the engine falls back to the no-op publisher
|
|
70
|
+
* (no live push), exactly as before.
|
|
71
|
+
*/
|
|
72
|
+
realtimeHub?: NodeRealtimeHub;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The Node composition root: assemble the framework-agnostic domain `Core` with
|
|
76
|
+
* Drizzle/Postgres repositories + Node implementations of the runtime ports, then
|
|
77
|
+
* attach the shared-controller extras (`config`, the kind-spanning agent-run repo,
|
|
78
|
+
* the runtime gateways). The same persistence is used in dev, test and prod — tests
|
|
79
|
+
* run against a real Postgres, exactly as the Worker runs against a real D1.
|
|
80
|
+
*
|
|
81
|
+
* Repo-operating agent steps (coder, blueprints, merger, …) run in a container
|
|
82
|
+
* dispatched to a workspace's self-hosted runner pool — the shared
|
|
83
|
+
* `ContainerAgentExecutor`, exactly as on the Worker. When the prerequisites (GitHub
|
|
84
|
+
* App, `PUBLIC_URL`, `AUTH_SESSION_SECRET`, `ENCRYPTION_KEY`) are absent the
|
|
85
|
+
* composite still serves inline kinds but fails container kinds loudly.
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildNodeContainer(options: NodeContainerOptions): ServerContainer;
|
|
88
|
+
//# sourceMappingURL=container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AA0BA,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,4BAA4B,EAQlC,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,KAAK,gBAAgB,EAAc,MAAM,4BAA4B,CAAA;AAE9E,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EAsBrB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAO/C,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAqBxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAkMrE,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,EAAE,EAAE,SAAS,CAAA;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAA;IACpD;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACrC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAA;IAChD;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACnE;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,4BAA4B,CAAA;IAC3D;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,eAAe,CAAA;CAC9B;AA6UD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CAkcjF"}
|