@crossdelta/platform-sdk 0.19.0 → 0.19.3

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 (46) hide show
  1. package/README.md +27 -5
  2. package/bin/chunk-634PL24Z.mjs +20 -0
  3. package/bin/cli.mjs +604 -0
  4. package/bin/config-CKQHYOF4.mjs +2 -0
  5. package/bin/docs/generators/code-style.md +79 -0
  6. package/bin/docs/generators/natural-language.md +117 -0
  7. package/bin/docs/generators/service.md +129 -60
  8. package/bin/templates/hono-microservice/Dockerfile.hbs +3 -1
  9. package/bin/templates/hono-microservice/src/config/env.ts.hbs +3 -0
  10. package/bin/templates/nest-microservice/Dockerfile.hbs +6 -2
  11. package/bin/templates/nest-microservice/src/config/env.ts.hbs +17 -0
  12. package/bin/templates/nest-microservice/src/main.ts.hbs +2 -1
  13. package/bin/templates/workspace/.github/actions/prepare-build-context/action.yml +58 -6
  14. package/bin/templates/workspace/.github/workflows/build-and-deploy.yml.hbs +25 -3
  15. package/bin/templates/workspace/.github/workflows/publish-packages.yml +6 -8
  16. package/bin/templates/workspace/biome.json.hbs +4 -1
  17. package/bin/templates/workspace/infra/package.json.hbs +2 -2
  18. package/bin/templates/workspace/package.json.hbs +1 -0
  19. package/bin/templates/workspace/packages/contracts/README.md.hbs +5 -5
  20. package/bin/templates/workspace/packages/contracts/package.json.hbs +15 -6
  21. package/bin/templates/workspace/packages/contracts/src/index.ts +1 -1
  22. package/bin/templates/workspace/packages/contracts/tsconfig.json.hbs +6 -1
  23. package/bin/templates/workspace/turbo.json +8 -11
  24. package/bin/templates/workspace/turbo.json.hbs +6 -5
  25. package/dist/facade.d.mts +840 -0
  26. package/dist/facade.d.ts +840 -0
  27. package/dist/facade.js +2294 -0
  28. package/dist/facade.js.map +1 -0
  29. package/dist/facade.mjs +2221 -0
  30. package/dist/facade.mjs.map +1 -0
  31. package/dist/plugin-types-DQOv97Zh.d.mts +180 -0
  32. package/dist/plugin-types-DQOv97Zh.d.ts +180 -0
  33. package/dist/plugin-types.d.mts +1 -0
  34. package/dist/plugin-types.d.ts +1 -0
  35. package/dist/plugin-types.js +19 -0
  36. package/dist/plugin-types.js.map +1 -0
  37. package/dist/plugin-types.mjs +1 -0
  38. package/dist/plugin-types.mjs.map +1 -0
  39. package/dist/plugin.d.mts +31 -0
  40. package/dist/plugin.d.ts +31 -0
  41. package/dist/plugin.js +105 -0
  42. package/dist/plugin.js.map +1 -0
  43. package/dist/plugin.mjs +75 -0
  44. package/dist/plugin.mjs.map +1 -0
  45. package/package.json +118 -99
  46. package/bin/cli.js +0 -540
@@ -0,0 +1,840 @@
1
+ import { FlowContext, FlowRunOptions, FlowResult } from '@crossdelta/flowcore';
2
+ export { FlowContext, FlowResult, FlowRunOptions } from '@crossdelta/flowcore';
3
+ import { P as PfWorkspaceContext, g as PfEffect, a as PfPluginContext, L as LoadedPlugin, b as PfPlugin } from './plugin-types-DQOv97Zh.mjs';
4
+ export { E as ElicitInputEffect, h as ElicitInputField, i as EnvAddEffect, F as FileWriteEffect, I as InfraAddEffect, c as PfCommand, d as PfCommandArg, e as PfCommandOption, j as PfCommandResult, k as isElicitInputEffect } from './plugin-types-DQOv97Zh.mjs';
5
+ export { deriveEventNames } from '@crossdelta/cloudevents';
6
+ import { z } from 'zod';
7
+
8
+ /**
9
+ * Capability Configuration
10
+ *
11
+ * Manages capability/provider configuration from workspace package.json.
12
+ * Single Source of Truth: workspaceConfig.pf.capabilities
13
+ *
14
+ * NO BUILT-IN DEFAULTS:
15
+ * - Provider metadata (deps/envVars/adapterFile) comes ONLY from workspace config
16
+ * - Unknown providers trigger elicitation (interactive) or error (strict)
17
+ * - This enables teams to define their own providers without hardcoded assumptions
18
+ */
19
+
20
+ declare const ProviderMetaSchema: z.ZodObject<{
21
+ dependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
22
+ envVars: z.ZodDefault<z.ZodArray<z.ZodObject<{
23
+ key: z.ZodString;
24
+ description: z.ZodString;
25
+ required: z.ZodDefault<z.ZodBoolean>;
26
+ }, z.core.$strip>>>;
27
+ adapterFile: z.ZodOptional<z.ZodString>;
28
+ }, z.core.$strip>;
29
+ type ProviderMeta = z.infer<typeof ProviderMetaSchema>;
30
+ declare const CapabilitiesConfigSchema: z.ZodObject<{
31
+ notifier: z.ZodOptional<z.ZodObject<{
32
+ defaults: z.ZodOptional<z.ZodObject<{
33
+ push: z.ZodOptional<z.ZodString>;
34
+ email: z.ZodOptional<z.ZodString>;
35
+ slack: z.ZodOptional<z.ZodString>;
36
+ sms: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>>;
38
+ providers: z.ZodOptional<z.ZodObject<{
39
+ push: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
40
+ dependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
41
+ envVars: z.ZodDefault<z.ZodArray<z.ZodObject<{
42
+ key: z.ZodString;
43
+ description: z.ZodString;
44
+ required: z.ZodDefault<z.ZodBoolean>;
45
+ }, z.core.$strip>>>;
46
+ adapterFile: z.ZodOptional<z.ZodString>;
47
+ }, z.core.$strip>>>;
48
+ email: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
49
+ dependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
50
+ envVars: z.ZodDefault<z.ZodArray<z.ZodObject<{
51
+ key: z.ZodString;
52
+ description: z.ZodString;
53
+ required: z.ZodDefault<z.ZodBoolean>;
54
+ }, z.core.$strip>>>;
55
+ adapterFile: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>>>;
57
+ slack: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
58
+ dependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
59
+ envVars: z.ZodDefault<z.ZodArray<z.ZodObject<{
60
+ key: z.ZodString;
61
+ description: z.ZodString;
62
+ required: z.ZodDefault<z.ZodBoolean>;
63
+ }, z.core.$strip>>>;
64
+ adapterFile: z.ZodOptional<z.ZodString>;
65
+ }, z.core.$strip>>>;
66
+ sms: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
67
+ dependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
68
+ envVars: z.ZodDefault<z.ZodArray<z.ZodObject<{
69
+ key: z.ZodString;
70
+ description: z.ZodString;
71
+ required: z.ZodDefault<z.ZodBoolean>;
72
+ }, z.core.$strip>>>;
73
+ adapterFile: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strip>>>;
75
+ }, z.core.$strip>>;
76
+ }, z.core.$strip>>;
77
+ }, z.core.$strip>;
78
+ type CapabilitiesConfig = z.infer<typeof CapabilitiesConfigSchema>;
79
+ type NotifierChannel = 'push' | 'email' | 'slack' | 'sms';
80
+ /**
81
+ * Get registered providers from workspace config.
82
+ * Returns empty arrays if no config - NO BUILT-IN FALLBACKS.
83
+ * Pure function.
84
+ */
85
+ declare const getRegisteredProviders: (workspaceConfig?: CapabilitiesConfig) => Record<NotifierChannel, string[]>;
86
+ interface ProviderLookupResult {
87
+ found: true;
88
+ provider: string;
89
+ meta: ProviderMeta;
90
+ source: 'workspace' | 'inferred';
91
+ }
92
+ interface ProviderNotFoundResult {
93
+ found: false;
94
+ channel: NotifierChannel;
95
+ provider: string;
96
+ availableProviders: string[];
97
+ configSnippet: string;
98
+ }
99
+ type ProviderLookup = ProviderLookupResult | ProviderNotFoundResult;
100
+ declare const lookupProvider: (channel: NotifierChannel, provider: string, workspaceConfig?: CapabilitiesConfig) => ProviderLookup;
101
+ interface ApplyDefaultResult {
102
+ provider: string;
103
+ source: 'explicit' | 'default';
104
+ }
105
+ interface NeedElicitationResult {
106
+ needsElicitation: true;
107
+ channel: NotifierChannel;
108
+ availableProviders: string[];
109
+ }
110
+ type ResolveProviderResult = ({
111
+ resolved: true;
112
+ } & ApplyDefaultResult) | ({
113
+ resolved: false;
114
+ } & NeedElicitationResult);
115
+ /**
116
+ * Resolve provider - use explicit if provided, else check defaults, else elicit.
117
+ * Pure function.
118
+ */
119
+ declare const resolveProvider: (channel: NotifierChannel, explicitProvider: string | undefined, workspaceConfig?: CapabilitiesConfig) => ResolveProviderResult;
120
+ /**
121
+ * Load capabilities config from workspace package.json.
122
+ * Returns undefined if no config or parsing fails.
123
+ *
124
+ * NOTE: This is the ONLY place that reads from workspace config.
125
+ * CLI and MCP both use this function via the capabilities module.
126
+ */
127
+ declare const loadCapabilitiesConfig: (workspacePkg: Record<string, unknown> | null) => CapabilitiesConfig | undefined;
128
+ /**
129
+ * Load capabilities config from workspace root.
130
+ * Convenience wrapper that integrates with packages/config.ts.
131
+ *
132
+ * Usage (CLI/MCP):
133
+ * ```ts
134
+ * import { loadCapabilitiesConfigFromWorkspace } from './capabilities/config'
135
+ * const config = loadCapabilitiesConfigFromWorkspace()
136
+ * const registry = createDefaultRegistry(config)
137
+ * ```
138
+ */
139
+ declare const loadCapabilitiesConfigFromWorkspace: (getWorkspacePackageJson: () => Record<string, unknown> | null) => CapabilitiesConfig | undefined;
140
+
141
+ /**
142
+ * Capability Types
143
+ *
144
+ * Core types for the deterministic planning system.
145
+ * AI generates content ONLY - paths/structure come from policy.
146
+ *
147
+ * Pipeline:
148
+ * 1. Parser: NL prompt -> ServiceSpec (with explicit provider if mentioned)
149
+ * 2. Lowering: ServiceSpec -> CapabilityInvocation[] (pure, deterministic)
150
+ * 3. Planning: Invocations -> GenerationPlan (deterministic, policy-based paths)
151
+ * 4. Content Generation: Plan.files -> AI fills content (constrained)
152
+ * 5. Validation: Check generated files against policy + patterns
153
+ */
154
+
155
+ declare const ServiceSpecSchema: z.ZodObject<{
156
+ serviceName: z.ZodString;
157
+ framework: z.ZodDefault<z.ZodEnum<{
158
+ hono: "hono";
159
+ nest: "nest";
160
+ }>>;
161
+ triggers: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
162
+ type: z.ZodLiteral<"event">;
163
+ eventType: z.ZodString;
164
+ stream: z.ZodOptional<z.ZodString>;
165
+ }, z.core.$strip>, z.ZodObject<{
166
+ type: z.ZodLiteral<"http">;
167
+ method: z.ZodOptional<z.ZodEnum<{
168
+ POST: "POST";
169
+ GET: "GET";
170
+ PUT: "PUT";
171
+ DELETE: "DELETE";
172
+ PATCH: "PATCH";
173
+ }>>;
174
+ path: z.ZodOptional<z.ZodString>;
175
+ }, z.core.$strip>], "type">>;
176
+ actions: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
177
+ type: z.ZodLiteral<"emit.event">;
178
+ eventType: z.ZodString;
179
+ }, z.core.$strip>, z.ZodObject<{
180
+ type: z.ZodLiteral<"notify">;
181
+ channel: z.ZodEnum<{
182
+ push: "push";
183
+ email: "email";
184
+ slack: "slack";
185
+ sms: "sms";
186
+ }>;
187
+ provider: z.ZodOptional<z.ZodString>;
188
+ }, z.core.$strip>, z.ZodObject<{
189
+ type: z.ZodLiteral<"call.http">;
190
+ name: z.ZodOptional<z.ZodString>;
191
+ baseUrl: z.ZodOptional<z.ZodString>;
192
+ }, z.core.$strip>, z.ZodObject<{
193
+ type: z.ZodLiteral<"persist">;
194
+ store: z.ZodEnum<{
195
+ db: "db";
196
+ kv: "kv";
197
+ cache: "cache";
198
+ }>;
199
+ entity: z.ZodOptional<z.ZodString>;
200
+ }, z.core.$strip>], "type">>>;
201
+ }, z.core.$strip>;
202
+ type ServiceSpec = z.infer<typeof ServiceSpecSchema>;
203
+ interface ElicitField {
204
+ path: string;
205
+ prompt: string;
206
+ type: 'string' | 'enum';
207
+ options?: string[];
208
+ required: boolean;
209
+ }
210
+ type ParseResult = {
211
+ complete: true;
212
+ spec: ServiceSpec;
213
+ } | {
214
+ complete: false;
215
+ fields: ElicitField[];
216
+ partialSpec: Partial<ServiceSpec>;
217
+ };
218
+
219
+ /**
220
+ * Capability Lowering
221
+ *
222
+ * Converts ServiceSpec to metadata (files, deps, env vars, postCommands).
223
+ * Pure, deterministic - no side effects, no defaults, no guessing.
224
+ */
225
+
226
+ interface ServiceMetadata {
227
+ files: {
228
+ path: string;
229
+ intent: string;
230
+ inputs?: Record<string, unknown>;
231
+ layer?: 'handler' | 'useCase' | 'adapter' | 'service';
232
+ kind?: 'event-consumer' | 'notifier' | 'http-client' | 'persistence';
233
+ }[];
234
+ dependencies: Record<string, string>;
235
+ envVars: {
236
+ key: string;
237
+ description: string;
238
+ required: boolean;
239
+ }[];
240
+ postCommands: string[];
241
+ }
242
+ /**
243
+ * Lower ServiceSpec to ServiceMetadata (files, deps, env vars, postCommands).
244
+ * AI generates file content based on intents.
245
+ */
246
+ declare const lowerSpecToCapabilities: (spec: ServiceSpec, serviceDir: string) => ServiceMetadata;
247
+
248
+ /**
249
+ * ServiceSpec Parser
250
+ *
251
+ * Converts natural language prompts to validated ServiceSpec.
252
+ * CRITICAL: Explicit provider mentions MUST land in spec - NO defaults.
253
+ * Missing required info triggers elicitation.
254
+ *
255
+ * Provider detection uses keyword matching + workspace config validation.
256
+ * Pure functions - no side effects, AI abstracted behind interface.
257
+ */
258
+
259
+ interface RawServiceSpec {
260
+ serviceName?: string;
261
+ framework?: string;
262
+ triggers?: Array<Record<string, unknown>>;
263
+ actions?: Array<Record<string, unknown>>;
264
+ }
265
+ interface PromptInterpreter {
266
+ extract(prompt: string): Promise<RawServiceSpec>;
267
+ }
268
+ interface ParseOptions {
269
+ interpreter?: PromptInterpreter;
270
+ workspaceConfig?: CapabilitiesConfig;
271
+ }
272
+ /**
273
+ * Parse natural language prompt to ServiceSpec.
274
+ * Uses interpreter for extraction, with pattern matching fallback.
275
+ * Supports workspace config for defaults and provider detection.
276
+ */
277
+ declare const parseServicePrompt: (prompt: string, options?: ParseOptions | PromptInterpreter) => Promise<ParseResult>;
278
+
279
+ /**
280
+ * Effect Handlers
281
+ *
282
+ * pf applies domain effects returned by plugin commands.
283
+ * Handlers are keyed by effect kind - clean data-driven dispatch.
284
+ */
285
+
286
+ /**
287
+ * Runtime context for effect handlers
288
+ */
289
+ interface EffectRuntimeContext {
290
+ workspace: PfWorkspaceContext;
291
+ logger: {
292
+ debug: (message: string) => void;
293
+ info: (message: string) => void;
294
+ warn: (message: string) => void;
295
+ error: (message: string) => void;
296
+ };
297
+ }
298
+ /**
299
+ * Represents a planned change (for dry-run mode)
300
+ */
301
+ interface Change {
302
+ type: 'create' | 'update' | 'delete';
303
+ path: string;
304
+ description: string;
305
+ preview?: string;
306
+ }
307
+ /**
308
+ * Result of applying an effect
309
+ */
310
+ interface EffectResult {
311
+ success: boolean;
312
+ message?: string;
313
+ changes?: Change[];
314
+ }
315
+ /**
316
+ * Options for effect handlers
317
+ */
318
+ interface EffectHandlerOptions {
319
+ dryRun?: boolean;
320
+ }
321
+ /**
322
+ * Apply a list of effects
323
+ *
324
+ * Iterates through effects and dispatches to registered handlers.
325
+ * Unknown effects are logged and skipped (not fatal).
326
+ *
327
+ * @param effects - List of effects to apply
328
+ * @param context - Runtime context with workspace and logger
329
+ * @param options - Optional settings (e.g., dryRun for plan mode)
330
+ * @returns Array of effect results
331
+ */
332
+ declare const applyEffects: (effects: PfEffect[], context: EffectRuntimeContext, options?: EffectHandlerOptions) => EffectResult[];
333
+
334
+ /**
335
+ * Change Aggregation Utilities
336
+ *
337
+ * For plan mode (dry-run) - aggregate and format change previews.
338
+ *
339
+ * Code organization: types → pure functions → higher-order functions
340
+ */
341
+
342
+ /**
343
+ * Aggregate all changes from effect results
344
+ *
345
+ * Filters successful results and flattens their changes arrays.
346
+ */
347
+ declare const aggregateChanges: (results: EffectResult[]) => Change[];
348
+ /**
349
+ * Format change summary for display
350
+ *
351
+ * Groups by type and shows counts + file list.
352
+ */
353
+ declare const formatChangeSummary: (changes: Change[]) => string;
354
+ /**
355
+ * Format detailed change preview (with code snippets)
356
+ */
357
+ declare const formatChangeDetails: (changes: Change[]) => string;
358
+
359
+ /**
360
+ * Operation Result Types
361
+ *
362
+ * Standard result shape for all pf operations.
363
+ * Enables consistent MCP tool responses and plan/apply workflows.
364
+ */
365
+
366
+ /**
367
+ * Artifact generated by an operation
368
+ */
369
+ interface Artifact {
370
+ /** Artifact type (file, config, env, etc.) */
371
+ type: 'file' | 'config' | 'env' | 'stream' | 'service';
372
+ /** Path or identifier */
373
+ path: string;
374
+ /** Human-readable description */
375
+ description: string;
376
+ }
377
+ /**
378
+ * Diagnostic message from an operation
379
+ */
380
+ interface Diagnostic {
381
+ /** Severity level */
382
+ level: 'info' | 'warning' | 'error';
383
+ /** Diagnostic message */
384
+ message: string;
385
+ /** Optional: Location (file path, line number) */
386
+ location?: string;
387
+ }
388
+ /**
389
+ * Suggested next action after operation
390
+ */
391
+ interface NextAction {
392
+ /** Command to run */
393
+ command: string;
394
+ /** Description of what the command does */
395
+ description: string;
396
+ }
397
+ /**
398
+ * Standard operation result
399
+ *
400
+ * All pf operations return this shape for consistency.
401
+ * Supports both plan mode (effects only) and apply mode (execution).
402
+ */
403
+ interface OperationResult<T = unknown> {
404
+ /** Operation succeeded */
405
+ ok: boolean;
406
+ /** Operation identifier (e.g., 'service.generate', 'event.add') */
407
+ operation: string;
408
+ /** Human-readable summary */
409
+ summary: string;
410
+ /** Generated artifacts */
411
+ artifacts: Artifact[];
412
+ /** Structured changes (effects) for plan/apply */
413
+ changes: PfEffect[];
414
+ /** Non-blocking diagnostics */
415
+ diagnostics: Diagnostic[];
416
+ /** Optional: Suggested next actions */
417
+ next?: NextAction[];
418
+ /** Optional: Operation-specific data */
419
+ data?: T;
420
+ }
421
+ /**
422
+ * Create a successful operation result
423
+ */
424
+ declare const ok: <T>(operation: string, summary: string, options?: {
425
+ artifacts?: Artifact[];
426
+ changes?: PfEffect[];
427
+ diagnostics?: Diagnostic[];
428
+ next?: NextAction[];
429
+ data?: T;
430
+ }) => OperationResult<T>;
431
+ /**
432
+ * Create a failed operation result
433
+ */
434
+ declare const err: (operation: string, error: string, options?: {
435
+ diagnostics?: Diagnostic[];
436
+ data?: unknown;
437
+ }) => OperationResult;
438
+
439
+ /**
440
+ * Template Engine Types
441
+ *
442
+ * Type-safe service generation templates.
443
+ * Templates define the structure (files, dependencies, config).
444
+ */
445
+ /**
446
+ * Environment variable definition for service config
447
+ */
448
+ interface EnvVarDef {
449
+ key: string;
450
+ description?: string;
451
+ required?: boolean;
452
+ }
453
+ /**
454
+ * Variables passed to template functions
455
+ */
456
+ interface TemplateVars {
457
+ /** Service name (kebab-case) */
458
+ serviceName: string;
459
+ /** Package name with scope (@org/service-name) */
460
+ packageName: string;
461
+ /** Service path relative to workspace root */
462
+ servicePath: string;
463
+ /** Assigned port for the service */
464
+ port: number;
465
+ /** Environment variable name for port (SCREAMING_SNAKE_CASE) */
466
+ envVarName: string;
467
+ /** Whether service has event consumers */
468
+ hasEvents: boolean;
469
+ /** NATS stream names if hasEvents is true */
470
+ streams: string[];
471
+ /** Event types to consume (e.g., ['order.created']) */
472
+ events: string[];
473
+ /** Workspace scope (@org) */
474
+ workspaceScope: string;
475
+ /** Additional features */
476
+ features?: string[];
477
+ /** Environment variables from capability plan (Pusher, etc.) */
478
+ envVars?: EnvVarDef[];
479
+ }
480
+
481
+ /**
482
+ * Template System
483
+ *
484
+ * Includes:
485
+ * - Handlebars renderer (existing)
486
+ * - String helpers (existing)
487
+ * - Service templates (new)
488
+ */
489
+
490
+ /**
491
+ * Template type for selection
492
+ */
493
+ type TemplateType = 'hono-bun' | 'hono-micro' | 'nest' | 'nest-micro';
494
+
495
+ /**
496
+ * Service Generation Flow
497
+ *
498
+ * Deterministic flow for generating microservices from templates.
499
+ * Supports plan/apply separation for MCP integration.
500
+ */
501
+
502
+ /**
503
+ * Service generation inputs
504
+ */
505
+ interface ServiceGenerationInputs {
506
+ /** Template type (hono-bun, hono-micro, nest, nest-micro) */
507
+ type: TemplateType;
508
+ /** Service name (kebab-case) */
509
+ name: string;
510
+ /** Optional: Custom service path (default: services/<name>) */
511
+ path?: string;
512
+ /** Optional: Enable event consumers (auto-set if events provided) */
513
+ hasEvents?: boolean;
514
+ /** Optional: NATS streams to consume from (auto-derived if events provided) */
515
+ streams?: string[];
516
+ /** Optional: Event types to consume (e.g., ['order.created']) */
517
+ events?: string[];
518
+ /** Optional: Workspace root (auto-detected if not provided) */
519
+ workspaceRoot?: string;
520
+ /** Optional: Explicit port (for deterministic generation) */
521
+ port?: number;
522
+ /** Optional: Environment variables from capability plan (for env.ts) */
523
+ envVars?: EnvVarDef[];
524
+ }
525
+ /**
526
+ * Service metadata
527
+ */
528
+ interface ServiceMeta {
529
+ serviceName: string;
530
+ servicePath: string;
531
+ port: number;
532
+ vars: TemplateVars;
533
+ }
534
+ /**
535
+ * Plan service generation (returns OperationResult)
536
+ *
537
+ * This is the MCP-ready interface that returns a structured result
538
+ * with effects that can be inspected before execution.
539
+ */
540
+ declare const planServiceGeneration: (inputs: ServiceGenerationInputs) => OperationResult<ServiceMeta>;
541
+
542
+ /**
543
+ * Find the workspace root by looking for workspace indicators
544
+ * Throws if not in a workspace
545
+ */
546
+ declare const findWorkspaceRoot: () => string;
547
+
548
+ /**
549
+ * Service Layout Policy (v1)
550
+ *
551
+ * Machine-readable policy for service file layouts and coding constraints.
552
+ * Enforces consistent structure across generators (CLI + MCP).
553
+ *
554
+ * - Hono: Use-cases for business logic (src/use-cases/*.use-case.ts)
555
+ * - NestJS: Services following NestJS conventions
556
+ *
557
+ * Features:
558
+ * - PathGuards: Forbidden directories per framework
559
+ * - CodingConstraints: Forbidden patterns in domain/use-case code
560
+ */
561
+ /** Policy version for backward compatibility */
562
+ declare const SERVICE_LAYOUT_POLICY_VERSION = 1;
563
+ /**
564
+ * Supported service frameworks
565
+ */
566
+ type ServiceFramework = 'hono' | 'nestjs';
567
+ /**
568
+ * Forbidden pattern for coding constraints
569
+ */
570
+ interface ForbiddenPattern {
571
+ /** Pattern to match (string or regex source) */
572
+ pattern: string;
573
+ /** Human-readable description */
574
+ description: string;
575
+ /** Error code for structured reporting */
576
+ code: string;
577
+ }
578
+ /**
579
+ * Coding constraints for business logic code
580
+ */
581
+ interface CodingConstraints {
582
+ /** Directories where constraints apply (relative to service root) */
583
+ appliesTo: readonly string[];
584
+ /** Forbidden patterns in code */
585
+ forbiddenPatterns: readonly ForbiddenPattern[];
586
+ }
587
+ /**
588
+ * Path guards for framework
589
+ */
590
+ interface PathGuards {
591
+ /** Directories that must not be used for business logic */
592
+ forbidDirs: readonly string[];
593
+ }
594
+ /**
595
+ * Framework-specific layout configuration
596
+ */
597
+ interface FrameworkLayout {
598
+ /** Directory for business logic (relative to src/) */
599
+ businessLogicDir: string;
600
+ /** Directory for event handlers (relative to src/) */
601
+ eventsDir: string;
602
+ /** File naming pattern. Placeholders: {name} */
603
+ filePattern: string;
604
+ /** File suffix (e.g., 'use-case', 'service') */
605
+ suffix: string;
606
+ /** Whether event handlers should delegate to business logic */
607
+ handlerDelegatesToBusinessLogic: boolean;
608
+ /** Path guards for this framework */
609
+ pathGuards: PathGuards;
610
+ /** Coding constraints for business logic */
611
+ codingConstraints: CodingConstraints;
612
+ }
613
+ /**
614
+ * Service layout policy
615
+ *
616
+ * Defines where business logic files should be placed for each framework.
617
+ * This is the single source of truth for service structure.
618
+ */
619
+ declare const serviceLayoutPolicy: Record<ServiceFramework, FrameworkLayout>;
620
+ /**
621
+ * Policy violation details
622
+ */
623
+ interface PolicyViolation {
624
+ /** Error code for structured handling */
625
+ code: string;
626
+ /** Human-readable message */
627
+ message: string;
628
+ /** File path that caused the violation */
629
+ path: string;
630
+ /** Line number (if applicable) */
631
+ line?: number;
632
+ }
633
+ /**
634
+ * Validation result for generated files
635
+ */
636
+ interface PolicyValidationResult {
637
+ /** Whether validation passed */
638
+ valid: boolean;
639
+ /** List of violations (empty if valid) */
640
+ violations: PolicyViolation[];
641
+ }
642
+ /**
643
+ * Planned file for validation
644
+ */
645
+ interface PlannedFile {
646
+ /** Relative path within service (e.g., 'src/services/foo.ts') */
647
+ path: string;
648
+ /** File content */
649
+ content: string;
650
+ }
651
+ /**
652
+ * Validate generated files against service policy
653
+ *
654
+ * Call this before applying effects to ensure compliance.
655
+ * Returns violations that MUST block generation.
656
+ *
657
+ * @param framework - Target framework
658
+ * @param files - Planned files to validate
659
+ * @returns Validation result with any violations
660
+ *
661
+ * @example
662
+ * const result = validateGeneratedFiles('hono', [
663
+ * { path: 'src/services/foo.ts', content: '...' }
664
+ * ])
665
+ * if (!result.valid) {
666
+ * throw new PolicyViolationError(result.violations)
667
+ * }
668
+ */
669
+ declare const validateGeneratedFiles: (framework: ServiceFramework, files: readonly PlannedFile[]) => PolicyValidationResult;
670
+ /**
671
+ * Get policy for a specific framework
672
+ *
673
+ * Useful for MCP/CLI to pass policy data to templates.
674
+ */
675
+ declare const getFrameworkPolicy: (framework: ServiceFramework) => FrameworkLayout;
676
+
677
+ /**
678
+ * Context Factory
679
+ *
680
+ * Functions for creating plugin contexts from workspace configuration.
681
+ */
682
+
683
+ /**
684
+ * Create plugin context by auto-discovering workspace configuration
685
+ *
686
+ * Reads workspace config from package.json (pf.* fields) and discovers
687
+ * contracts path, services, etc. This is the recommended way to create context.
688
+ *
689
+ * @param workspaceRoot - Optional workspace root (defaults to auto-discovery from cwd)
690
+ * @param logger - Optional logger (defaults to console)
691
+ * @returns Plugin context ready for use
692
+ *
693
+ * @example
694
+ * // Auto-discover workspace from current directory
695
+ * const context = await createContextFromWorkspace()
696
+ *
697
+ * @example
698
+ * // Specify workspace root explicitly
699
+ * const context = await createContextFromWorkspace('/path/to/workspace')
700
+ */
701
+ declare const createContextFromWorkspace: (workspaceRoot?: string, logger?: PfPluginContext["logger"]) => Promise<PfPluginContext>;
702
+ /**
703
+ * Create a plugin context from workspace information (manual)
704
+ *
705
+ * Use this when you need full control over workspace configuration.
706
+ * For most cases, prefer `createContextFromWorkspace()` which auto-discovers config.
707
+ *
708
+ * @param workspace - Workspace context with paths and configuration
709
+ * @param logger - Optional logger (defaults to console)
710
+ * @returns Plugin context ready for use
711
+ *
712
+ * @example
713
+ * const context = createContext({
714
+ * workspaceRoot: '/path/to/workspace',
715
+ * contracts: {
716
+ * path: '/path/to/contracts',
717
+ * packageName: '@my-org/contracts'
718
+ * },
719
+ * availableServices: ['orders', 'notifications']
720
+ * })
721
+ */
722
+ declare const createContext: (workspace: PfWorkspaceContext, logger?: PfPluginContext["logger"]) => PfPluginContext;
723
+
724
+ /**
725
+ * Facade Types
726
+ *
727
+ * Public type definitions for external integrations.
728
+ */
729
+
730
+ /**
731
+ * Tool specification for external integrations (MCP, VS Code, etc.)
732
+ */
733
+ interface ToolSpec {
734
+ /** Tool name (e.g., 'event.add', 'service.create') */
735
+ name: string;
736
+ /** Human-readable description */
737
+ description: string;
738
+ /** Input schema (JSON Schema format) */
739
+ inputSchema: ToolInputSchema;
740
+ }
741
+ interface ToolInputSchema {
742
+ type: 'object';
743
+ properties: Record<string, ToolPropertySchema>;
744
+ required?: string[];
745
+ }
746
+ interface ToolPropertySchema {
747
+ type: string;
748
+ description: string;
749
+ default?: unknown;
750
+ }
751
+ /**
752
+ * Result from a legacy command execution (plan-like wrapper)
753
+ */
754
+ interface CommandLikeResult {
755
+ ok: boolean;
756
+ operation: string;
757
+ summary: string;
758
+ effects: PfEffect[];
759
+ output?: string | string[];
760
+ }
761
+ /**
762
+ * Executable tool specification
763
+ *
764
+ * Extends ToolSpec with an execute function for direct dispatch.
765
+ * Returns OperationResult for consistency with plan/apply workflows.
766
+ */
767
+ interface ExecutableToolSpec extends ToolSpec {
768
+ /** Execute the tool with given args (returns OperationResult or CommandLikeResult) */
769
+ execute: (args: Record<string, unknown>) => Promise<OperationResult | CommandLikeResult>;
770
+ }
771
+
772
+ /**
773
+ * Tool Collection
774
+ *
775
+ * Functions for transforming plugin commands into tool specifications.
776
+ * Shared schema building logic to avoid duplication.
777
+ */
778
+
779
+ /**
780
+ * Collect tool specifications from loaded plugins
781
+ *
782
+ * Transforms plugin commands into a unified tool specification format.
783
+ * This abstraction allows different consumers (MCP, VS Code) to use the same data.
784
+ *
785
+ * @param plugins - Array of loaded plugins
786
+ * @returns Array of tool specifications with schema information
787
+ *
788
+ * @example
789
+ * const tools = collectToolSpecs(plugins)
790
+ * // Returns: [{ name: 'event.add', description: '...', inputSchema: {...} }]
791
+ */
792
+ declare const collectToolSpecs: (plugins: LoadedPlugin[]) => ToolSpec[];
793
+ /**
794
+ * Collect executable tool specifications from loaded plugins
795
+ *
796
+ * Transforms plugin commands into executable tool specs with dispatch functions.
797
+ * Each tool's execute() returns a plan-like result without applying effects.
798
+ *
799
+ * @param plugins - Array of loaded plugins
800
+ * @param context - Plugin context for command execution
801
+ * @returns Array of executable tool specifications
802
+ *
803
+ * @example
804
+ * const tools = collectExecutableToolSpecs(plugins, context)
805
+ * const result = await tools[0].execute({ eventType: 'order.created' })
806
+ */
807
+ declare const collectExecutableToolSpecs: (plugins: LoadedPlugin[], _context: PfPluginContext) => ExecutableToolSpec[];
808
+
809
+ /**
810
+ * Platform SDK Facade
811
+ *
812
+ * Stable API surface for external integrations (MCP adapters, extensions, etc.)
813
+ * This facade isolates internal implementation details and provides version stability.
814
+ *
815
+ * Design Philosophy:
816
+ * - Minimal surface area: Only expose what's needed for tool/flow execution
817
+ * - Semantic versioning: Breaking changes bump major version
818
+ * - Internal freedom: Implementation can change without affecting consumers
819
+ *
820
+ * Consumers:
821
+ * - @crossdelta/pf-mcp (MCP server adapter)
822
+ * - Future extensions (VS Code, etc.)
823
+ */
824
+
825
+ declare const loadPlugins: (moduleNames: string[], context: PfPluginContext) => Promise<LoadedPlugin[]>;
826
+ declare const runFlow: <TContext extends FlowContext = FlowContext>(plugin: PfPlugin, flowName: string, options: FlowRunOptions<TContext>) => Promise<FlowResult<TContext>>;
827
+ /**
828
+ * Get the absolute path to the generator docs directory
829
+ *
830
+ * @returns Absolute path to packages/platform-sdk/bin/docs/generators (built artifacts)
831
+ */
832
+ declare const getGeneratorDocsDir: () => string;
833
+ /**
834
+ * List all available generator documentation files
835
+ *
836
+ * @returns Array of doc filenames (without .md extension)
837
+ */
838
+ declare const listGeneratorDocs: () => Promise<string[]>;
839
+
840
+ export { type Artifact, type CapabilitiesConfig, type Change, type CodingConstraints, type CommandLikeResult, type Diagnostic, type EffectHandlerOptions, type EffectResult, type EffectRuntimeContext, type ExecutableToolSpec, type ForbiddenPattern, type FrameworkLayout, LoadedPlugin, type NextAction, type OperationResult, type ParseResult, type PathGuards, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, type PlannedFile, type PolicyValidationResult, type PolicyViolation, type ProviderLookup, SERVICE_LAYOUT_POLICY_VERSION, type ServiceFramework, type ServiceGenerationInputs, type ServiceMeta, type ServiceMetadata, type ServiceSpec, type ToolInputSchema, type ToolPropertySchema, type ToolSpec, aggregateChanges, applyEffects, collectExecutableToolSpecs, collectToolSpecs, createContext, createContextFromWorkspace, err as createErrResult, ok as createOkResult, findWorkspaceRoot, formatChangeDetails, formatChangeSummary, getFrameworkPolicy, getGeneratorDocsDir, getRegisteredProviders, listGeneratorDocs, loadCapabilitiesConfig, loadCapabilitiesConfigFromWorkspace, loadPlugins, lookupProvider, lowerSpecToCapabilities, parseServicePrompt, planServiceGeneration, resolveProvider, runFlow, serviceLayoutPolicy, validateGeneratedFiles };