@orchestrator-claude/definitions 3.43.1 → 3.44.1

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.
Files changed (53) hide show
  1. package/agents/adversarial-reviewer.md +35 -29
  2. package/agents/agentic-architect.md +1 -1
  3. package/agents/api-extractor.md +1 -1
  4. package/agents/architecture-mediator.md +1 -1
  5. package/agents/azure-devops-engineer.md +1 -1
  6. package/agents/backend-architect.md +1 -1
  7. package/agents/business-rule-miner.md +1 -1
  8. package/agents/cicd-platform-engineer.md +1 -1
  9. package/agents/ciclo-engineer.md +1 -1
  10. package/agents/code-archaeologist.md +1 -1
  11. package/agents/contract-architect.md +1 -1
  12. package/agents/datamodel-architect.md +1 -1
  13. package/agents/frontend-architect.md +1 -1
  14. package/agents/frontend-engineer.md +1 -1
  15. package/agents/harness-architect.md +1 -1
  16. package/agents/harness-engineer.md +1 -1
  17. package/agents/implementer.md +1 -1
  18. package/agents/infra-architect.md +1 -1
  19. package/agents/legacy-discoverer.md +1 -1
  20. package/agents/legacy-synthesizer.md +1 -1
  21. package/agents/methodology-researcher.md +2 -1
  22. package/agents/operational-artifact-builder.md +1 -1
  23. package/agents/planner.md +1 -1
  24. package/agents/presentation-engineer.md +1 -1
  25. package/agents/python-data-engineer.md +1 -1
  26. package/agents/researcher.md +1 -1
  27. package/agents/reviewer.md +1 -1
  28. package/agents/schema-extractor.md +1 -1
  29. package/agents/specifier.md +1 -1
  30. package/agents/task-generator.md +1 -1
  31. package/hooks/agent-git-guard.mjs +0 -2
  32. package/hooks/dangling-guard.mjs +18 -3
  33. package/hooks/gate-guardian.mjs +8617 -273
  34. package/hooks/gate-guardian.ts +296 -62
  35. package/hooks/lib/api-client.ts +154 -28
  36. package/hooks/lib/artifact-gate.ts +518 -0
  37. package/hooks/lib/artifact-producers.ts +106 -0
  38. package/hooks/lib/gate-logic.ts +6 -5
  39. package/hooks/lib/workflow-artifact-client.ts +351 -0
  40. package/hooks/mailbox-listener.mjs +0 -2
  41. package/hooks/playwright-output-guard.mjs +0 -2
  42. package/hooks/post-implement.mjs +18 -3
  43. package/hooks/pre-agent-dispatch.mjs +18 -3
  44. package/hooks/security-gate-honest.mjs +0 -2
  45. package/hooks/session-start.mjs +18 -3
  46. package/hooks/subagent-start.mjs +18 -3
  47. package/hooks/subagent-stop.mjs +18 -3
  48. package/hooks/user-prompt.mjs +18 -3
  49. package/hooks/verification-before-completion.mjs +0 -2
  50. package/hooks/workflow-guard.mjs +504 -29
  51. package/hooks/workflow-guard.ts +370 -27
  52. package/manifest.json +46 -46
  53. package/package.json +1 -1
@@ -0,0 +1,351 @@
1
+ /**
2
+ * workflow-artifact-client.ts — the hooks' tagged HTTP client of the workflow-artifacts contract
3
+ * (RFC-044 F3, S4: PL-ADR-5, M4, M5, R1, R2, R3).
4
+ *
5
+ * Unlike apiGet/apiPost in api-client.ts (which answer null for every failure), every call here returns a
6
+ * discriminated result: each failure is a `kind`/`cause` of its own, and nothing throws to the caller. The
7
+ * callers (workflow-guard R7 in S4; gate-guardian in S5) fail CLOSED on anything that is not `ok`.
8
+ *
9
+ * The contract types come from `@orchestrator-claude/vault-projection/workflow-artifact` (wire.ts): this file
10
+ * imports them, it does not declare them (M4). The client rules it implements:
11
+ * R1 a non-2xx is classified by its problem code (problemCode: `code`, or the house `type`), never by the
12
+ * status alone; a non-2xx without a KNOWN code is `unavailable` -- a route that is not deployed answers
13
+ * 404 without a code, and must not read as "workflow not found".
14
+ * R2 verify-observed is decided by its per-item `results` (checked item by item against the request).
15
+ * R3 verifyObserved probes the workflow first (M5): verify-observed does not check that it exists.
16
+ *
17
+ * api-client.ts is NOT edited (PL-ADR-8: editing it re-bundles every hook): the URL is read from the same env
18
+ * var with the same default, and the token/project come from its existing exports.
19
+ */
20
+ import {
21
+ LEDGER_FRONTMATTER_FIELDS,
22
+ VERIFY_VERDICT_CODES,
23
+ WORKFLOW_ARTIFACT_ERROR_CODES,
24
+ problemCode,
25
+ projectLedgerFrontmatter,
26
+ type RegisterWorkflowArtifactRequest,
27
+ type RegisterWorkflowArtifactResponse,
28
+ type VerifyItemFailed,
29
+ type VerifyItemResult,
30
+ type VerifyObservedItem,
31
+ type VerifyObservedRequest,
32
+ type VerifyObservedResponse,
33
+ } from '@orchestrator-claude/vault-projection/workflow-artifact';
34
+ import { getEffectiveProjectId, getToken } from './api-client.js';
35
+
36
+ export interface ClientDeps {
37
+ fetch: typeof fetch;
38
+ getToken: () => Promise<string | null>;
39
+ getProjectId: () => string;
40
+ apiUrl: string;
41
+ timeoutMs: number;
42
+ }
43
+
44
+ /** Same env var and default as api-client.ts (`API_URL`, not exported there on purpose, PL-ADR-8). */
45
+ export function defaultClientDeps(): ClientDeps {
46
+ const envUrl = process.env.ORCHESTRATOR_API_URL;
47
+ return {
48
+ fetch: (input, init) => fetch(input, init),
49
+ getToken,
50
+ getProjectId: getEffectiveProjectId,
51
+ // An EMPTY value falls back too, exactly like api-client.ts (`||` there).
52
+ apiUrl: envUrl !== undefined && envUrl !== '' ? envUrl : 'http://localhost:3001',
53
+ timeoutMs: 5000,
54
+ };
55
+ }
56
+
57
+ export type UnavailableCause =
58
+ | 'no-token'
59
+ | 'unauthorized'
60
+ | 'timeout'
61
+ | 'network'
62
+ | 'http-5xx'
63
+ | 'unknown-response'
64
+ | 'bad-body'
65
+ | 'exception';
66
+
67
+ export interface Unavailable {
68
+ kind: 'unavailable';
69
+ cause: UnavailableCause;
70
+ httpStatus?: number;
71
+ code?: string;
72
+ detail?: string;
73
+ }
74
+
75
+ export type ProbeResult =
76
+ | { kind: 'ok'; workflowId: string; status: string; currentPhase: string | null }
77
+ | { kind: 'not-found' }
78
+ | Unavailable;
79
+
80
+ export interface Rejected {
81
+ kind: 'rejected';
82
+ httpStatus: number;
83
+ code: string;
84
+ detail?: string;
85
+ }
86
+
87
+ export type RegisterResult =
88
+ | { kind: 'ok'; response: RegisterWorkflowArtifactResponse }
89
+ | Rejected
90
+ | Unavailable;
91
+
92
+ /** A registered host file nobody showed (S3c, M6): derived from the wire type, not redeclared. */
93
+ export type UnobservedArtifact = NonNullable<VerifyObservedResponse['unobserved']>[number];
94
+
95
+ /** `exhaustive` of the wire request (S3c, M6, D-469). */
96
+ export interface VerifyOptions {
97
+ exhaustive?: NonNullable<VerifyObservedRequest['exhaustive']>;
98
+ }
99
+
100
+ export type VerifyResult =
101
+ | {
102
+ kind: 'ok';
103
+ results: VerifyItemResult[];
104
+ failed: VerifyItemFailed[];
105
+ /** Present exactly when the request carried `exhaustive`. */
106
+ unobserved?: UnobservedArtifact[];
107
+ }
108
+ | { kind: 'probe-failed'; probe: Exclude<ProbeResult, { kind: 'ok' }> }
109
+ | Rejected
110
+ | Unavailable;
111
+
112
+ /** The register input: a whole-file frontmatter is accepted and projected on the ledger fields (M4). */
113
+ export type RegisterInput = Omit<RegisterWorkflowArtifactRequest, 'frontmatter'> & {
114
+ frontmatter: Readonly<Record<string, unknown>>;
115
+ };
116
+
117
+ const AUTH_CODES: ReadonlySet<string> = new Set(['unauthorized', 'forbidden']);
118
+ /** Request errors of the two workflow-artifacts routes a caller can act on (INTERNAL_ERROR is a 5xx). */
119
+ const REJECT_CODES: ReadonlySet<string> = new Set([
120
+ ...WORKFLOW_ARTIFACT_ERROR_CODES.filter((c) => c !== 'INTERNAL_ERROR'),
121
+ 'FST_ERR_VALIDATION',
122
+ ]);
123
+ const VERDICTS: ReadonlySet<string> = new Set(VERIFY_VERDICT_CODES);
124
+
125
+ type Sent = { ok: false; failure: Unavailable } | { ok: true; resp: Response };
126
+
127
+ const isObject = (v: unknown): v is Record<string, unknown> =>
128
+ typeof v === 'object' && v !== null && !Array.isArray(v);
129
+
130
+ function causeOfThrow(e: unknown): UnavailableCause {
131
+ const name = (e as { name?: unknown } | null)?.name;
132
+ return name === 'TimeoutError' || name === 'AbortError' ? 'timeout' : 'network';
133
+ }
134
+
135
+ async function readJson(
136
+ resp: Response
137
+ ): Promise<{ parsed: true; body: unknown } | { parsed: false }> {
138
+ try {
139
+ return { parsed: true, body: (await resp.json()) as unknown };
140
+ } catch {
141
+ return { parsed: false };
142
+ }
143
+ }
144
+
145
+ /** One HTTP exchange; transport failures become `unavailable`, an HTTP answer of any status is returned. */
146
+ async function send(deps: ClientDeps, path: string, body?: unknown): Promise<Sent> {
147
+ const token = await deps.getToken();
148
+ if (token === null || token === '') {
149
+ return { ok: false, failure: { kind: 'unavailable', cause: 'no-token' } };
150
+ }
151
+ const headers: Record<string, string> = {
152
+ Authorization: `Bearer ${token}`,
153
+ 'X-Project-ID': deps.getProjectId(),
154
+ };
155
+ if (body !== undefined) headers['Content-Type'] = 'application/json';
156
+ try {
157
+ const resp = await deps.fetch(`${deps.apiUrl}${path}`, {
158
+ method: body === undefined ? 'GET' : 'POST',
159
+ headers,
160
+ ...(body !== undefined && { body: JSON.stringify(body) }),
161
+ signal: AbortSignal.timeout(deps.timeoutMs),
162
+ });
163
+ return { ok: true, resp };
164
+ } catch (e) {
165
+ return { ok: false, failure: { kind: 'unavailable', cause: causeOfThrow(e) } };
166
+ }
167
+ }
168
+
169
+ /**
170
+ * R1: classifies a non-2xx. `known` are the codes the caller acts on as a typed rejection; auth codes are
171
+ * `unavailable(unauthorized)`; a 5xx is `http-5xx`; everything else (no code, or a code nobody published)
172
+ * is `unavailable(unknown-response)`.
173
+ */
174
+ async function classifyFailure(
175
+ resp: Response,
176
+ known: ReadonlySet<string>
177
+ ): Promise<Rejected | Unavailable | { kind: 'code'; code: string }> {
178
+ const read = await readJson(resp);
179
+ const code = read.parsed ? problemCode(read.body) : null;
180
+ const detail =
181
+ read.parsed && isObject(read.body) && typeof read.body.detail === 'string'
182
+ ? read.body.detail
183
+ : undefined;
184
+ const base = {
185
+ httpStatus: resp.status,
186
+ ...(code !== null && { code }),
187
+ ...(detail !== undefined && { detail }),
188
+ };
189
+ if (resp.status >= 500) return { kind: 'unavailable', cause: 'http-5xx', ...base };
190
+ if (code !== null && AUTH_CODES.has(code)) {
191
+ return { kind: 'unavailable', cause: 'unauthorized', ...base };
192
+ }
193
+ if (code !== null && known.has(code)) {
194
+ return {
195
+ kind: 'rejected',
196
+ httpStatus: resp.status,
197
+ code,
198
+ ...(detail !== undefined && { detail }),
199
+ };
200
+ }
201
+ return { kind: 'unavailable', cause: 'unknown-response', ...base };
202
+ }
203
+
204
+ const badBody = (httpStatus: number): Unavailable => ({
205
+ kind: 'unavailable',
206
+ cause: 'bad-body',
207
+ httpStatus,
208
+ });
209
+
210
+ async function guard<T>(run: () => Promise<T | Unavailable>): Promise<T | Unavailable> {
211
+ try {
212
+ return await run();
213
+ } catch (e) {
214
+ return {
215
+ kind: 'unavailable',
216
+ cause: 'exception',
217
+ detail: e instanceof Error ? e.message : String(e),
218
+ };
219
+ }
220
+ }
221
+
222
+ /** GET /api/v1/workflows/:id/status, by the id given (the id of the PATH for R7; never "the active one"). */
223
+ export function probeWorkflow(
224
+ workflowId: string,
225
+ deps: ClientDeps = defaultClientDeps()
226
+ ): Promise<ProbeResult> {
227
+ return guard<ProbeResult>(async () => {
228
+ const sent = await send(deps, `/api/v1/workflows/${encodeURIComponent(workflowId)}/status`);
229
+ if (!sent.ok) return sent.failure;
230
+ const { resp } = sent;
231
+ if (!resp.ok) {
232
+ const failure = await classifyFailure(resp, new Set(['not-found']));
233
+ return failure.kind === 'rejected' ? { kind: 'not-found' } : (failure as Unavailable);
234
+ }
235
+ const read = await readJson(resp);
236
+ if (!read.parsed || !isObject(read.body)) return badBody(resp.status);
237
+ const { workflowId: id, status, currentPhase } = read.body;
238
+ const phaseOk = currentPhase === null || typeof currentPhase === 'string';
239
+ if (id !== workflowId || typeof status !== 'string' || !phaseOk) return badBody(resp.status);
240
+ return { kind: 'ok', workflowId: id, status, currentPhase };
241
+ });
242
+ }
243
+
244
+ function isRegisterResponse(v: unknown): v is RegisterWorkflowArtifactResponse {
245
+ return (
246
+ isObject(v) &&
247
+ (v.status === 'recorded' || v.status === 'unchanged') &&
248
+ Number.isInteger(v.revision) &&
249
+ typeof v.rowId === 'string'
250
+ );
251
+ }
252
+
253
+ /** POST /api/v1/workflow-artifacts. The frontmatter is projected on LEDGER_FRONTMATTER_FIELDS first. */
254
+ export function registerArtifact(
255
+ input: RegisterInput,
256
+ deps: ClientDeps = defaultClientDeps()
257
+ ): Promise<RegisterResult> {
258
+ return guard<RegisterResult>(async () => {
259
+ const request: RegisterWorkflowArtifactRequest = {
260
+ ...input,
261
+ frontmatter: projectLedgerFrontmatter(input.frontmatter),
262
+ };
263
+ const sent = await send(deps, '/api/v1/workflow-artifacts', request);
264
+ if (!sent.ok) return sent.failure;
265
+ const { resp } = sent;
266
+ if (!resp.ok) return (await classifyFailure(resp, REJECT_CODES)) as Rejected | Unavailable;
267
+ const read = await readJson(resp);
268
+ if (!read.parsed || !isRegisterResponse(read.body)) return badBody(resp.status);
269
+ const { status, revision, rowId } = read.body;
270
+ return { kind: 'ok', response: { status, revision, rowId } };
271
+ });
272
+ }
273
+
274
+ /** R2: one result per item, in the request's order, each a well-formed verdict; anything else is bad-body. */
275
+ function checkResults(
276
+ body: unknown,
277
+ items: readonly VerifyObservedItem[]
278
+ ): VerifyItemResult[] | null {
279
+ if (!isObject(body) || !Array.isArray(body.results)) return null;
280
+ const results = body.results as unknown[];
281
+ if (results.length !== items.length) return null;
282
+ const checked: VerifyItemResult[] = [];
283
+ for (const [i, r] of results.entries()) {
284
+ const item = items[i] as VerifyObservedItem;
285
+ if (!isObject(r)) return null;
286
+ if (r.phase !== item.phase || r.artifactType !== item.artifactType) return null;
287
+ if (r.ok === true && Number.isInteger(r.revision)) {
288
+ checked.push(r as unknown as VerifyItemResult);
289
+ } else if (r.ok === false && typeof r.code === 'string' && VERDICTS.has(r.code)) {
290
+ checked.push(r as unknown as VerifyItemResult);
291
+ } else {
292
+ return null;
293
+ }
294
+ }
295
+ return checked;
296
+ }
297
+
298
+ /**
299
+ * `unobserved` of an exhaustive answer: an array of {phase, artifactType, revision}. Anything else (absent: an
300
+ * API that ignored `exhaustive`; a malformed entry) is null, which the caller turns into bad-body (fail closed).
301
+ */
302
+ function checkUnobserved(body: unknown): UnobservedArtifact[] | null {
303
+ if (!isObject(body) || !Array.isArray(body.unobserved)) return null;
304
+ const checked: UnobservedArtifact[] = [];
305
+ for (const u of body.unobserved as unknown[]) {
306
+ if (!isObject(u)) return null;
307
+ const { phase, artifactType, revision } = u;
308
+ if (typeof phase !== 'string' || typeof artifactType !== 'string') return null;
309
+ if (typeof revision !== 'number' || !Number.isInteger(revision)) return null;
310
+ checked.push({ phase, artifactType, revision });
311
+ }
312
+ return checked;
313
+ }
314
+
315
+ /**
316
+ * POST /api/v1/workflow-artifacts/verify-observed, AFTER probeWorkflow (M5, R3): an unknown or unreachable
317
+ * workflow stops at the probe, so it can never read as ARTIFACT_NOT_REGISTERED. Decided per item (R2).
318
+ * With `options.exhaustive` (S3c, M6, D-469) the request says "this is everything the host has outside
319
+ * excludePhases", and the answer must carry `unobserved` (the registered host files nobody showed).
320
+ */
321
+ export function verifyObserved(
322
+ workflowId: string,
323
+ items: readonly VerifyObservedItem[],
324
+ deps: ClientDeps = defaultClientDeps(),
325
+ options: VerifyOptions = {}
326
+ ): Promise<VerifyResult> {
327
+ return guard<VerifyResult>(async () => {
328
+ const probe = await probeWorkflow(workflowId, deps);
329
+ if (probe.kind !== 'ok') return { kind: 'probe-failed', probe };
330
+ const request: VerifyObservedRequest = {
331
+ workflowId,
332
+ items: [...items],
333
+ ...(options.exhaustive !== undefined && { exhaustive: options.exhaustive }),
334
+ };
335
+ const sent = await send(deps, '/api/v1/workflow-artifacts/verify-observed', request);
336
+ if (!sent.ok) return sent.failure;
337
+ const { resp } = sent;
338
+ if (!resp.ok) return (await classifyFailure(resp, REJECT_CODES)) as Rejected | Unavailable;
339
+ const read = await readJson(resp);
340
+ const results = read.parsed ? checkResults(read.body, items) : null;
341
+ if (results === null) return badBody(resp.status);
342
+ const failed = results.filter((r): r is VerifyItemFailed => !r.ok);
343
+ if (options.exhaustive === undefined) return { kind: 'ok', results, failed };
344
+ const unobserved = checkUnobserved(read.parsed ? read.body : undefined);
345
+ if (unobserved === null) return badBody(resp.status);
346
+ return { kind: 'ok', results, failed, unobserved };
347
+ });
348
+ }
349
+
350
+ /** Re-exported so a caller can tell which frontmatter keys travel (the rest stays in the file). */
351
+ export { LEDGER_FRONTMATTER_FIELDS };
@@ -74,8 +74,6 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
74
74
  );
75
75
  }
76
76
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
77
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
78
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
79
77
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
80
78
  function resolveHookProjectRoot(cwd) {
81
79
  return resolveProjectRoot(cwd);
@@ -64,8 +64,6 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
64
64
  );
65
65
  }
66
66
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
67
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
68
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
69
67
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
70
68
  function resolveHookProjectRoot(cwd) {
71
69
  return resolveProjectRoot(cwd);
@@ -61,8 +61,15 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
61
61
  );
62
62
  }
63
63
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
64
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
65
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
64
+ var DEFAULT_AUTH_EMAIL = "system@orchestrator.local";
65
+ var MISSING_CREDENTIAL_MESSAGE = "no credential configured (ORCHESTRATOR_ADMIN_PASSWORD / ORCHESTRATOR_AUTH_PASSWORD unset or empty) - login not attempted";
66
+ var missingCredentialLogged = false;
67
+ function resolveAuthCredentials() {
68
+ const password = (process.env.ORCHESTRATOR_ADMIN_PASSWORD ?? "").trim() || (process.env.ORCHESTRATOR_AUTH_PASSWORD ?? "").trim();
69
+ if (!password) return null;
70
+ const email = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || DEFAULT_AUTH_EMAIL;
71
+ return { email, password };
72
+ }
66
73
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
67
74
  function resolveHookProjectRoot(cwd) {
68
75
  return resolveProjectRoot(cwd);
@@ -121,6 +128,14 @@ function getCachedToken() {
121
128
  return null;
122
129
  }
123
130
  async function login() {
131
+ const credentials = resolveAuthCredentials();
132
+ if (credentials === null) {
133
+ if (!missingCredentialLogged) {
134
+ missingCredentialLogged = true;
135
+ log("API-CLIENT", MISSING_CREDENTIAL_MESSAGE);
136
+ }
137
+ return null;
138
+ }
124
139
  try {
125
140
  const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
126
141
  method: "POST",
@@ -128,7 +143,7 @@ async function login() {
128
143
  "Content-Type": "application/json",
129
144
  "X-Project-ID": PROJECT_ID
130
145
  },
131
- body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
146
+ body: JSON.stringify({ email: credentials.email, password: credentials.password }),
132
147
  signal: AbortSignal.timeout(5e3)
133
148
  });
134
149
  if (!resp.ok) return null;
@@ -64,8 +64,15 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
64
64
  );
65
65
  }
66
66
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
67
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
68
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
67
+ var DEFAULT_AUTH_EMAIL = "system@orchestrator.local";
68
+ var MISSING_CREDENTIAL_MESSAGE = "no credential configured (ORCHESTRATOR_ADMIN_PASSWORD / ORCHESTRATOR_AUTH_PASSWORD unset or empty) - login not attempted";
69
+ var missingCredentialLogged = false;
70
+ function resolveAuthCredentials() {
71
+ const password = (process.env.ORCHESTRATOR_ADMIN_PASSWORD ?? "").trim() || (process.env.ORCHESTRATOR_AUTH_PASSWORD ?? "").trim();
72
+ if (!password) return null;
73
+ const email = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || DEFAULT_AUTH_EMAIL;
74
+ return { email, password };
75
+ }
69
76
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
70
77
  function resolveHookProjectRoot(cwd) {
71
78
  return resolveProjectRoot(cwd);
@@ -128,6 +135,14 @@ function getCachedToken() {
128
135
  return null;
129
136
  }
130
137
  async function login() {
138
+ const credentials = resolveAuthCredentials();
139
+ if (credentials === null) {
140
+ if (!missingCredentialLogged) {
141
+ missingCredentialLogged = true;
142
+ log("API-CLIENT", MISSING_CREDENTIAL_MESSAGE);
143
+ }
144
+ return null;
145
+ }
131
146
  try {
132
147
  const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
133
148
  method: "POST",
@@ -135,7 +150,7 @@ async function login() {
135
150
  "Content-Type": "application/json",
136
151
  "X-Project-ID": PROJECT_ID
137
152
  },
138
- body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
153
+ body: JSON.stringify({ email: credentials.email, password: credentials.password }),
139
154
  signal: AbortSignal.timeout(5e3)
140
155
  });
141
156
  if (!resp.ok) return null;
@@ -61,8 +61,6 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
61
61
  );
62
62
  }
63
63
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
64
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
65
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
66
64
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
67
65
  function resolveHookProjectRoot(cwd) {
68
66
  return resolveProjectRoot(cwd);
@@ -7387,8 +7387,15 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
7387
7387
  );
7388
7388
  }
7389
7389
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
7390
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
7391
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
7390
+ var DEFAULT_AUTH_EMAIL = "system@orchestrator.local";
7391
+ var MISSING_CREDENTIAL_MESSAGE = "no credential configured (ORCHESTRATOR_ADMIN_PASSWORD / ORCHESTRATOR_AUTH_PASSWORD unset or empty) - login not attempted";
7392
+ var missingCredentialLogged = false;
7393
+ function resolveAuthCredentials() {
7394
+ const password = (process.env.ORCHESTRATOR_ADMIN_PASSWORD ?? "").trim() || (process.env.ORCHESTRATOR_AUTH_PASSWORD ?? "").trim();
7395
+ if (!password) return null;
7396
+ const email = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || DEFAULT_AUTH_EMAIL;
7397
+ return { email, password };
7398
+ }
7392
7399
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
7393
7400
  function resolveHookProjectRoot(cwd) {
7394
7401
  return resolveProjectRoot(cwd);
@@ -7453,6 +7460,14 @@ function getCachedToken() {
7453
7460
  return null;
7454
7461
  }
7455
7462
  async function login() {
7463
+ const credentials = resolveAuthCredentials();
7464
+ if (credentials === null) {
7465
+ if (!missingCredentialLogged) {
7466
+ missingCredentialLogged = true;
7467
+ log("API-CLIENT", MISSING_CREDENTIAL_MESSAGE);
7468
+ }
7469
+ return null;
7470
+ }
7456
7471
  try {
7457
7472
  const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
7458
7473
  method: "POST",
@@ -7460,7 +7475,7 @@ async function login() {
7460
7475
  "Content-Type": "application/json",
7461
7476
  "X-Project-ID": PROJECT_ID
7462
7477
  },
7463
- body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
7478
+ body: JSON.stringify({ email: credentials.email, password: credentials.password }),
7464
7479
  signal: AbortSignal.timeout(5e3)
7465
7480
  });
7466
7481
  if (!resp.ok) return null;
@@ -7385,8 +7385,15 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
7385
7385
  );
7386
7386
  }
7387
7387
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
7388
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
7389
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
7388
+ var DEFAULT_AUTH_EMAIL = "system@orchestrator.local";
7389
+ var MISSING_CREDENTIAL_MESSAGE = "no credential configured (ORCHESTRATOR_ADMIN_PASSWORD / ORCHESTRATOR_AUTH_PASSWORD unset or empty) - login not attempted";
7390
+ var missingCredentialLogged = false;
7391
+ function resolveAuthCredentials() {
7392
+ const password = (process.env.ORCHESTRATOR_ADMIN_PASSWORD ?? "").trim() || (process.env.ORCHESTRATOR_AUTH_PASSWORD ?? "").trim();
7393
+ if (!password) return null;
7394
+ const email = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || DEFAULT_AUTH_EMAIL;
7395
+ return { email, password };
7396
+ }
7390
7397
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
7391
7398
  function resolveHookProjectRoot(cwd) {
7392
7399
  return resolveProjectRoot(cwd);
@@ -7452,6 +7459,14 @@ function getCachedToken() {
7452
7459
  return null;
7453
7460
  }
7454
7461
  async function login() {
7462
+ const credentials = resolveAuthCredentials();
7463
+ if (credentials === null) {
7464
+ if (!missingCredentialLogged) {
7465
+ missingCredentialLogged = true;
7466
+ log("API-CLIENT", MISSING_CREDENTIAL_MESSAGE);
7467
+ }
7468
+ return null;
7469
+ }
7455
7470
  try {
7456
7471
  const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
7457
7472
  method: "POST",
@@ -7459,7 +7474,7 @@ async function login() {
7459
7474
  "Content-Type": "application/json",
7460
7475
  "X-Project-ID": PROJECT_ID
7461
7476
  },
7462
- body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
7477
+ body: JSON.stringify({ email: credentials.email, password: credentials.password }),
7463
7478
  signal: AbortSignal.timeout(5e3)
7464
7479
  });
7465
7480
  if (!resp.ok) return null;
@@ -7381,8 +7381,15 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
7381
7381
  );
7382
7382
  }
7383
7383
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
7384
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
7385
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
7384
+ var DEFAULT_AUTH_EMAIL = "system@orchestrator.local";
7385
+ var MISSING_CREDENTIAL_MESSAGE = "no credential configured (ORCHESTRATOR_ADMIN_PASSWORD / ORCHESTRATOR_AUTH_PASSWORD unset or empty) - login not attempted";
7386
+ var missingCredentialLogged = false;
7387
+ function resolveAuthCredentials() {
7388
+ const password = (process.env.ORCHESTRATOR_ADMIN_PASSWORD ?? "").trim() || (process.env.ORCHESTRATOR_AUTH_PASSWORD ?? "").trim();
7389
+ if (!password) return null;
7390
+ const email = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || DEFAULT_AUTH_EMAIL;
7391
+ return { email, password };
7392
+ }
7386
7393
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
7387
7394
  function resolveHookProjectRoot(cwd) {
7388
7395
  return resolveProjectRoot(cwd);
@@ -7448,6 +7455,14 @@ function getCachedToken() {
7448
7455
  return null;
7449
7456
  }
7450
7457
  async function login() {
7458
+ const credentials = resolveAuthCredentials();
7459
+ if (credentials === null) {
7460
+ if (!missingCredentialLogged) {
7461
+ missingCredentialLogged = true;
7462
+ log("API-CLIENT", MISSING_CREDENTIAL_MESSAGE);
7463
+ }
7464
+ return null;
7465
+ }
7451
7466
  try {
7452
7467
  const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
7453
7468
  method: "POST",
@@ -7455,7 +7470,7 @@ async function login() {
7455
7470
  "Content-Type": "application/json",
7456
7471
  "X-Project-ID": PROJECT_ID
7457
7472
  },
7458
- body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
7473
+ body: JSON.stringify({ email: credentials.email, password: credentials.password }),
7459
7474
  signal: AbortSignal.timeout(5e3)
7460
7475
  });
7461
7476
  if (!resp.ok) return null;
@@ -61,8 +61,15 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
61
61
  );
62
62
  }
63
63
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
64
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
65
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
64
+ var DEFAULT_AUTH_EMAIL = "system@orchestrator.local";
65
+ var MISSING_CREDENTIAL_MESSAGE = "no credential configured (ORCHESTRATOR_ADMIN_PASSWORD / ORCHESTRATOR_AUTH_PASSWORD unset or empty) - login not attempted";
66
+ var missingCredentialLogged = false;
67
+ function resolveAuthCredentials() {
68
+ const password = (process.env.ORCHESTRATOR_ADMIN_PASSWORD ?? "").trim() || (process.env.ORCHESTRATOR_AUTH_PASSWORD ?? "").trim();
69
+ if (!password) return null;
70
+ const email = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || DEFAULT_AUTH_EMAIL;
71
+ return { email, password };
72
+ }
66
73
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
67
74
  function resolveHookProjectRoot(cwd) {
68
75
  return resolveProjectRoot(cwd);
@@ -121,6 +128,14 @@ function getCachedToken() {
121
128
  return null;
122
129
  }
123
130
  async function login() {
131
+ const credentials = resolveAuthCredentials();
132
+ if (credentials === null) {
133
+ if (!missingCredentialLogged) {
134
+ missingCredentialLogged = true;
135
+ log("API-CLIENT", MISSING_CREDENTIAL_MESSAGE);
136
+ }
137
+ return null;
138
+ }
124
139
  try {
125
140
  const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
126
141
  method: "POST",
@@ -128,7 +143,7 @@ async function login() {
128
143
  "Content-Type": "application/json",
129
144
  "X-Project-ID": PROJECT_ID
130
145
  },
131
- body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
146
+ body: JSON.stringify({ email: credentials.email, password: credentials.password }),
132
147
  signal: AbortSignal.timeout(5e3)
133
148
  });
134
149
  if (!resp.ok) return null;
@@ -61,8 +61,6 @@ if ((STATE_DIR_OVERRIDE === void 0 || STATE_DIR_OVERRIDE === "") && PROJECT_ROOT
61
61
  );
62
62
  }
63
63
  var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
64
- var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
65
- var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
66
64
  var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
67
65
  function resolveHookProjectRoot(cwd) {
68
66
  return resolveProjectRoot(cwd);