@crossdelta/platform-sdk 0.21.12 → 0.21.14
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/bin/cli.mjs +47 -47
- package/bin/templates/workspace/infra/index.ts.hbs +65 -39
- package/bin/templates/workspace/infra/package.json.hbs +2 -2
- package/bin/templates/workspace/packages/contracts/package.json.hbs +2 -2
- package/dist/facade.d.mts +3 -3
- package/dist/facade.d.ts +3 -3
- package/dist/facade.js +2 -2
- package/dist/facade.mjs +3 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-types.d.ts +1 -1
- package/dist/plugin.d.mts +3 -3
- package/dist/plugin.d.ts +3 -3
- package/package.json +4 -3
- package/dist/plugin-types-DQOv97Zh.d.mts +0 -180
- package/dist/plugin-types-DQOv97Zh.d.ts +0 -180
|
@@ -1,56 +1,82 @@
|
|
|
1
|
-
import { join } from 'node:path'
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
createDOKSCluster,
|
|
3
|
+
createImagePullSecret,
|
|
4
|
+
createNamespace,
|
|
5
|
+
deployK8sServices,
|
|
6
|
+
deployRuntime,
|
|
7
|
+
discoverServiceConfigs,
|
|
8
|
+
materializeStreams,
|
|
10
9
|
} from '@crossdelta/infrastructure'
|
|
11
|
-
import
|
|
10
|
+
import * as contracts from '{{scope}}/contracts'
|
|
12
11
|
import { Config, getStack } from '@pulumi/pulumi'
|
|
13
12
|
|
|
14
|
-
const
|
|
15
|
-
const serviceConfigs = allServiceConfigs.filter((config) => !config.skip)
|
|
13
|
+
const stack = getStack()
|
|
16
14
|
const cfg = new Config()
|
|
17
|
-
const logtailToken = cfg.requireSecret('logtailToken')
|
|
18
15
|
const registryCredentials = cfg.requireSecret('registryCredentials')
|
|
19
16
|
|
|
20
|
-
const
|
|
17
|
+
const namespace = `{{projectName}}-${stack}`
|
|
21
18
|
|
|
22
|
-
const
|
|
19
|
+
const { provider, kubeconfig, endpoint } = createDOKSCluster({
|
|
20
|
+
name: '{{projectName}}-cluster',
|
|
21
|
+
clusterName: '{{projectName}}-cluster',
|
|
22
|
+
region: 'fra1',
|
|
23
|
+
ha: false,
|
|
24
|
+
version: '1.32.2-do.1',
|
|
25
|
+
nodePool: {
|
|
26
|
+
name: 'default',
|
|
27
|
+
size: 's-2vcpu-4gb',
|
|
28
|
+
nodeCount: 2,
|
|
29
|
+
labels: { environment: stack },
|
|
30
|
+
},
|
|
31
|
+
tags: ['{{projectName}}', `env:${stack}`],
|
|
32
|
+
})
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
spec: {
|
|
26
|
-
name: doAppName,
|
|
27
|
-
region: 'fra',
|
|
34
|
+
createNamespace(provider, namespace, { environment: stack })
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
const imagePullSecretName = 'ghcr-secret'
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
createImagePullSecret(provider, namespace, imagePullSecretName, {
|
|
39
|
+
registry: 'ghcr.io',
|
|
40
|
+
username: 'github',
|
|
41
|
+
password: registryCredentials,
|
|
42
|
+
})
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
const runtime = deployRuntime(provider, namespace, {
|
|
45
|
+
nats: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
config: {
|
|
48
|
+
replicas: 1,
|
|
49
|
+
jetstream: {
|
|
50
|
+
enabled: true,
|
|
51
|
+
storageSize: '1Gi',
|
|
52
|
+
storageClass: 'do-block-storage',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
})
|
|
37
57
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
registryCredentials,
|
|
41
|
-
logtailToken,
|
|
42
|
-
}),
|
|
58
|
+
if (runtime.natsUrl) {
|
|
59
|
+
const natsDepends = runtime.natsRelease ? [runtime.natsRelease] : []
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
61
|
+
materializeStreams(provider, namespace, {
|
|
62
|
+
natsUrl: runtime.natsUrl,
|
|
63
|
+
contracts,
|
|
64
|
+
dependsOn: natsDepends,
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const serviceConfigs = discoverServiceConfigs('services').map((config) => ({
|
|
69
|
+
...config,
|
|
70
|
+
env: {
|
|
71
|
+
...config.env,
|
|
72
|
+
...(runtime.natsUrl && { NATS_URL: runtime.natsUrl }),
|
|
47
73
|
},
|
|
74
|
+
}))
|
|
75
|
+
|
|
76
|
+
deployK8sServices(provider, namespace, serviceConfigs, {
|
|
77
|
+
imagePullSecretName,
|
|
48
78
|
})
|
|
49
79
|
|
|
50
|
-
|
|
51
|
-
export const
|
|
52
|
-
export const
|
|
53
|
-
export const internalUrls = buildInternalUrls(serviceConfigs)
|
|
54
|
-
export const serviceUrls = app.defaultIngress.apply((baseUrl) =>
|
|
55
|
-
buildExternalUrls(serviceConfigs, baseUrl ?? ''),
|
|
56
|
-
)
|
|
80
|
+
export const clusterEndpoint = endpoint
|
|
81
|
+
export const clusterKubeconfig = kubeconfig
|
|
82
|
+
export const natsInternalUrl = runtime.natsUrl
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"pulumi": "pulumi"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@crossdelta/cloudevents": "^0.
|
|
11
|
-
"@crossdelta/infrastructure": "^0.11.
|
|
10
|
+
"@crossdelta/cloudevents": "^0.8.1",
|
|
11
|
+
"@crossdelta/infrastructure": "^0.11.7",
|
|
12
12
|
"{{scope}}/contracts": "workspace:*",
|
|
13
13
|
"@pulumi/digitalocean": "^4.55.0",
|
|
14
14
|
"@pulumi/kubernetes": "^4.21.0",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"clean": "rm -rf dist"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@crossdelta/cloudevents": "^0.
|
|
23
|
-
"@crossdelta/infrastructure": "^0.11.
|
|
22
|
+
"@crossdelta/cloudevents": "^0.8.1",
|
|
23
|
+
"@crossdelta/infrastructure": "^0.11.7",
|
|
24
24
|
"zod": "^4.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
package/dist/facade.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlowContext, FlowRunOptions, FlowResult } from '@crossdelta/flowcore';
|
|
2
2
|
export { FlowContext, FlowResult, FlowRunOptions } from '@crossdelta/flowcore';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { PfWorkspaceContext, PfEffect, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
|
|
4
|
+
export { ElicitInputEffect, ElicitInputField, EnvAddEffect, FileWriteEffect, InfraAddEffect, LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfCommandResult, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, isElicitInputEffect } from '@crossdelta/shared/plugin-types';
|
|
5
5
|
export { deriveEventNames } from '@crossdelta/cloudevents';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
@@ -837,4 +837,4 @@ declare const getGeneratorDocsDir: () => string;
|
|
|
837
837
|
*/
|
|
838
838
|
declare const listGeneratorDocs: () => Promise<string[]>;
|
|
839
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,
|
|
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, type NextAction, type OperationResult, type ParseResult, type PathGuards, 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 };
|
package/dist/facade.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlowContext, FlowRunOptions, FlowResult } from '@crossdelta/flowcore';
|
|
2
2
|
export { FlowContext, FlowResult, FlowRunOptions } from '@crossdelta/flowcore';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { PfWorkspaceContext, PfEffect, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
|
|
4
|
+
export { ElicitInputEffect, ElicitInputField, EnvAddEffect, FileWriteEffect, InfraAddEffect, LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfCommandResult, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, isElicitInputEffect } from '@crossdelta/shared/plugin-types';
|
|
5
5
|
export { deriveEventNames } from '@crossdelta/cloudevents';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
@@ -837,4 +837,4 @@ declare const getGeneratorDocsDir: () => string;
|
|
|
837
837
|
*/
|
|
838
838
|
declare const listGeneratorDocs: () => Promise<string[]>;
|
|
839
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,
|
|
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, type NextAction, type OperationResult, type ParseResult, type PathGuards, 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 };
|
package/dist/facade.js
CHANGED
|
@@ -383,7 +383,7 @@ __export(facade_exports, {
|
|
|
383
383
|
getFrameworkPolicy: () => getFrameworkPolicy,
|
|
384
384
|
getGeneratorDocsDir: () => getGeneratorDocsDir,
|
|
385
385
|
getRegisteredProviders: () => getRegisteredProviders,
|
|
386
|
-
isElicitInputEffect: () => isElicitInputEffect,
|
|
386
|
+
isElicitInputEffect: () => import_plugin_types.isElicitInputEffect,
|
|
387
387
|
listGeneratorDocs: () => listGeneratorDocs,
|
|
388
388
|
loadCapabilitiesConfig: () => loadCapabilitiesConfig,
|
|
389
389
|
loadCapabilitiesConfigFromWorkspace: () => loadCapabilitiesConfigFromWorkspace,
|
|
@@ -2166,7 +2166,7 @@ var planServiceGeneration = (inputs) => {
|
|
|
2166
2166
|
init_config();
|
|
2167
2167
|
|
|
2168
2168
|
// cli/src/core/plugins/types.ts
|
|
2169
|
-
var
|
|
2169
|
+
var import_plugin_types = require("@crossdelta/shared/plugin-types");
|
|
2170
2170
|
|
|
2171
2171
|
// cli/src/core/facade/context.ts
|
|
2172
2172
|
init_config();
|
package/dist/facade.mjs
CHANGED
|
@@ -2095,7 +2095,9 @@ var planServiceGeneration = (inputs) => {
|
|
|
2095
2095
|
init_config();
|
|
2096
2096
|
|
|
2097
2097
|
// cli/src/core/plugins/types.ts
|
|
2098
|
-
|
|
2098
|
+
import {
|
|
2099
|
+
isElicitInputEffect
|
|
2100
|
+
} from "@crossdelta/shared/plugin-types";
|
|
2099
2101
|
|
|
2100
2102
|
// cli/src/core/facade/context.ts
|
|
2101
2103
|
init_config();
|
package/dist/plugin-types.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext } from '@crossdelta/shared/plugin-types';
|
package/dist/plugin-types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext } from '@crossdelta/shared/plugin-types';
|
package/dist/plugin.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { PfWorkspaceContext, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
|
|
2
|
+
export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext, PfWorkspaceContext } from '@crossdelta/shared/plugin-types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Plugin Loader
|
|
@@ -28,4 +28,4 @@ declare const createPluginContext: (workspace: PfWorkspaceContext, logger?: PfPl
|
|
|
28
28
|
*/
|
|
29
29
|
declare const loadPluginFromModule: (moduleName: string, context: PfPluginContext) => Promise<LoadedPlugin>;
|
|
30
30
|
|
|
31
|
-
export {
|
|
31
|
+
export { createPluginContext, loadPluginFromModule, validatePlugin, validatePluginStrict };
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { PfWorkspaceContext, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
|
|
2
|
+
export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext, PfWorkspaceContext } from '@crossdelta/shared/plugin-types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Plugin Loader
|
|
@@ -28,4 +28,4 @@ declare const createPluginContext: (workspace: PfWorkspaceContext, logger?: PfPl
|
|
|
28
28
|
*/
|
|
29
29
|
declare const loadPluginFromModule: (moduleName: string, context: PfPluginContext) => Promise<LoadedPlugin>;
|
|
30
30
|
|
|
31
|
-
export {
|
|
31
|
+
export { createPluginContext, loadPluginFromModule, validatePlugin, validatePluginStrict };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crossdelta/platform-sdk",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.14",
|
|
4
4
|
"description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -118,8 +118,9 @@
|
|
|
118
118
|
"@ai-sdk/anthropic": "^2.0.53",
|
|
119
119
|
"@ai-sdk/openai": "^2.0.79",
|
|
120
120
|
"@angular-devkit/core": "^21.0.0",
|
|
121
|
-
"@crossdelta/cloudevents": "^0.
|
|
121
|
+
"@crossdelta/cloudevents": "^0.8.1",
|
|
122
122
|
"@crossdelta/flowcore": "^0.1.2",
|
|
123
|
+
"@crossdelta/shared": "^0.1.0",
|
|
123
124
|
"@faker-js/faker": "^9.8.0",
|
|
124
125
|
"@inquirer/prompts": "^7.5.0",
|
|
125
126
|
"@listr2/prompt-adapter-enquirer": "^2.0.15",
|
|
@@ -144,7 +145,7 @@
|
|
|
144
145
|
"zod": "^4.0.0"
|
|
145
146
|
},
|
|
146
147
|
"peerDependencies": {
|
|
147
|
-
"@crossdelta/infrastructure": "^0.11.
|
|
148
|
+
"@crossdelta/infrastructure": "^0.11.7",
|
|
148
149
|
"@nestjs/schematics": "^11.0.5",
|
|
149
150
|
"turbo": "^2.0.0"
|
|
150
151
|
},
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin System Types
|
|
3
|
-
*
|
|
4
|
-
* pf owns and defines these interfaces.
|
|
5
|
-
* Plugins MUST adapt to these interfaces.
|
|
6
|
-
* pf is strict and predictable - no duck-typing, no fallbacks.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Base effect type - all domain effects must have a kind
|
|
10
|
-
* pf handles effects generically via kind-based handler registry
|
|
11
|
-
*/
|
|
12
|
-
interface PfEffect {
|
|
13
|
-
readonly kind: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* File write effect - write content to a file
|
|
17
|
-
*/
|
|
18
|
-
interface FileWriteEffect extends PfEffect {
|
|
19
|
-
readonly kind: 'file:write';
|
|
20
|
-
readonly path: string;
|
|
21
|
-
readonly content: string;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Infrastructure service configuration effect
|
|
25
|
-
*/
|
|
26
|
-
interface InfraAddEffect extends PfEffect {
|
|
27
|
-
readonly kind: 'infra:add';
|
|
28
|
-
readonly serviceName: string;
|
|
29
|
-
readonly port: number;
|
|
30
|
-
readonly framework: string;
|
|
31
|
-
readonly runtime: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Environment variable effect
|
|
35
|
-
*/
|
|
36
|
-
interface EnvAddEffect extends PfEffect {
|
|
37
|
-
readonly kind: 'env:add';
|
|
38
|
-
readonly key: string;
|
|
39
|
-
readonly value: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Field definition for input elicitation
|
|
43
|
-
*
|
|
44
|
-
* Describes a single field that needs user input.
|
|
45
|
-
* Host-agnostic - CLI and MCP interpret this differently.
|
|
46
|
-
*/
|
|
47
|
-
interface ElicitInputField {
|
|
48
|
-
/** Field name (used as key in response) */
|
|
49
|
-
readonly name: string;
|
|
50
|
-
/** Human-readable prompt/question */
|
|
51
|
-
readonly prompt: string;
|
|
52
|
-
/** Whether the field is required */
|
|
53
|
-
readonly required?: boolean;
|
|
54
|
-
/** Detailed description (shown as help text) */
|
|
55
|
-
readonly description?: string;
|
|
56
|
-
/** Default value if user provides nothing */
|
|
57
|
-
readonly defaultValue?: unknown;
|
|
58
|
-
/** Allowed values (enum constraint) */
|
|
59
|
-
readonly enum?: readonly string[];
|
|
60
|
-
/** Field type hint */
|
|
61
|
-
readonly type?: 'string' | 'number' | 'boolean';
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Input elicitation effect
|
|
65
|
-
*
|
|
66
|
-
* Returned by tools when required inputs are missing.
|
|
67
|
-
* Pure data - no MCP SDK imports, no host-specific logic.
|
|
68
|
-
*
|
|
69
|
-
* Hosts interpret this effect differently:
|
|
70
|
-
* - CLI: Interactive prompt
|
|
71
|
-
* - MCP: server.elicitInput() or structured error
|
|
72
|
-
*/
|
|
73
|
-
interface ElicitInputEffect extends PfEffect {
|
|
74
|
-
readonly kind: 'elicit:input';
|
|
75
|
-
/** Message explaining what's needed */
|
|
76
|
-
readonly message: string;
|
|
77
|
-
/** Fields to collect from user */
|
|
78
|
-
readonly fields: readonly ElicitInputField[];
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Type guard for ElicitInputEffect
|
|
82
|
-
*/
|
|
83
|
-
declare const isElicitInputEffect: (effect: PfEffect) => effect is ElicitInputEffect;
|
|
84
|
-
/**
|
|
85
|
-
* Result of running a command
|
|
86
|
-
*/
|
|
87
|
-
interface PfCommandResult {
|
|
88
|
-
/** Domain effects to be applied by the runtime */
|
|
89
|
-
effects: PfEffect[];
|
|
90
|
-
/** Optional output to display (for read-only commands) */
|
|
91
|
-
output?: string | string[];
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Command argument definition
|
|
95
|
-
*/
|
|
96
|
-
interface PfCommandArg {
|
|
97
|
-
name: string;
|
|
98
|
-
description: string;
|
|
99
|
-
required: boolean;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Command option definition
|
|
103
|
-
*/
|
|
104
|
-
interface PfCommandOption {
|
|
105
|
-
flags: string;
|
|
106
|
-
description: string;
|
|
107
|
-
default?: unknown;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* A CLI command provided by a plugin
|
|
111
|
-
*
|
|
112
|
-
* Plugins MUST implement this exact interface.
|
|
113
|
-
*/
|
|
114
|
-
interface PfCommand {
|
|
115
|
-
name: string;
|
|
116
|
-
description: string;
|
|
117
|
-
args: PfCommandArg[];
|
|
118
|
-
options: PfCommandOption[];
|
|
119
|
-
run(args: Record<string, unknown>, options: Record<string, unknown>): Promise<PfCommandResult>;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* An interactive flow provided by a plugin
|
|
123
|
-
*/
|
|
124
|
-
interface PfFlow {
|
|
125
|
-
name: string;
|
|
126
|
-
description: string;
|
|
127
|
-
getSteps(initialContext?: Record<string, unknown>): Promise<unknown[]>;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Workspace context with all discovered information
|
|
131
|
-
* pf owns this - plugins receive it during setup
|
|
132
|
-
*/
|
|
133
|
-
interface PfWorkspaceContext {
|
|
134
|
-
/** Absolute path to workspace root */
|
|
135
|
-
workspaceRoot: string;
|
|
136
|
-
/** Discovered services (relative paths like 'services/api-gateway') */
|
|
137
|
-
availableServices: string[];
|
|
138
|
-
/** Contracts package configuration */
|
|
139
|
-
contracts: {
|
|
140
|
-
/** Relative path to contracts source (e.g., 'packages/contracts/src') */
|
|
141
|
-
path: string;
|
|
142
|
-
/** Package name (e.g., '@my-platform/contracts') */
|
|
143
|
-
packageName?: string;
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Plugin context provided by pf during setup
|
|
148
|
-
*/
|
|
149
|
-
interface PfPluginContext {
|
|
150
|
-
workspace: PfWorkspaceContext;
|
|
151
|
-
logger: {
|
|
152
|
-
debug: (message: string) => void;
|
|
153
|
-
info: (message: string) => void;
|
|
154
|
-
warn: (message: string) => void;
|
|
155
|
-
error: (message: string) => void;
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* A plugin that can be loaded by pf
|
|
160
|
-
*
|
|
161
|
-
* Plugins MUST implement this exact interface.
|
|
162
|
-
* If a plugin has a different internal API, it must provide an adapter.
|
|
163
|
-
*/
|
|
164
|
-
interface PfPlugin {
|
|
165
|
-
name: string;
|
|
166
|
-
version: string;
|
|
167
|
-
description?: string;
|
|
168
|
-
commands: PfCommand[];
|
|
169
|
-
flows: PfFlow[];
|
|
170
|
-
setup: (context: PfPluginContext) => Promise<void> | void;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Result of loading a plugin
|
|
174
|
-
*/
|
|
175
|
-
interface LoadedPlugin {
|
|
176
|
-
plugin: PfPlugin;
|
|
177
|
-
source: string;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export { type ElicitInputEffect as E, type FileWriteEffect as F, type InfraAddEffect as I, type LoadedPlugin as L, type PfWorkspaceContext as P, type PfPluginContext as a, type PfPlugin as b, type PfCommand as c, type PfCommandArg as d, type PfCommandOption as e, type PfFlow as f, type PfEffect as g, type ElicitInputField as h, type EnvAddEffect as i, type PfCommandResult as j, isElicitInputEffect as k };
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin System Types
|
|
3
|
-
*
|
|
4
|
-
* pf owns and defines these interfaces.
|
|
5
|
-
* Plugins MUST adapt to these interfaces.
|
|
6
|
-
* pf is strict and predictable - no duck-typing, no fallbacks.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Base effect type - all domain effects must have a kind
|
|
10
|
-
* pf handles effects generically via kind-based handler registry
|
|
11
|
-
*/
|
|
12
|
-
interface PfEffect {
|
|
13
|
-
readonly kind: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* File write effect - write content to a file
|
|
17
|
-
*/
|
|
18
|
-
interface FileWriteEffect extends PfEffect {
|
|
19
|
-
readonly kind: 'file:write';
|
|
20
|
-
readonly path: string;
|
|
21
|
-
readonly content: string;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Infrastructure service configuration effect
|
|
25
|
-
*/
|
|
26
|
-
interface InfraAddEffect extends PfEffect {
|
|
27
|
-
readonly kind: 'infra:add';
|
|
28
|
-
readonly serviceName: string;
|
|
29
|
-
readonly port: number;
|
|
30
|
-
readonly framework: string;
|
|
31
|
-
readonly runtime: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Environment variable effect
|
|
35
|
-
*/
|
|
36
|
-
interface EnvAddEffect extends PfEffect {
|
|
37
|
-
readonly kind: 'env:add';
|
|
38
|
-
readonly key: string;
|
|
39
|
-
readonly value: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Field definition for input elicitation
|
|
43
|
-
*
|
|
44
|
-
* Describes a single field that needs user input.
|
|
45
|
-
* Host-agnostic - CLI and MCP interpret this differently.
|
|
46
|
-
*/
|
|
47
|
-
interface ElicitInputField {
|
|
48
|
-
/** Field name (used as key in response) */
|
|
49
|
-
readonly name: string;
|
|
50
|
-
/** Human-readable prompt/question */
|
|
51
|
-
readonly prompt: string;
|
|
52
|
-
/** Whether the field is required */
|
|
53
|
-
readonly required?: boolean;
|
|
54
|
-
/** Detailed description (shown as help text) */
|
|
55
|
-
readonly description?: string;
|
|
56
|
-
/** Default value if user provides nothing */
|
|
57
|
-
readonly defaultValue?: unknown;
|
|
58
|
-
/** Allowed values (enum constraint) */
|
|
59
|
-
readonly enum?: readonly string[];
|
|
60
|
-
/** Field type hint */
|
|
61
|
-
readonly type?: 'string' | 'number' | 'boolean';
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Input elicitation effect
|
|
65
|
-
*
|
|
66
|
-
* Returned by tools when required inputs are missing.
|
|
67
|
-
* Pure data - no MCP SDK imports, no host-specific logic.
|
|
68
|
-
*
|
|
69
|
-
* Hosts interpret this effect differently:
|
|
70
|
-
* - CLI: Interactive prompt
|
|
71
|
-
* - MCP: server.elicitInput() or structured error
|
|
72
|
-
*/
|
|
73
|
-
interface ElicitInputEffect extends PfEffect {
|
|
74
|
-
readonly kind: 'elicit:input';
|
|
75
|
-
/** Message explaining what's needed */
|
|
76
|
-
readonly message: string;
|
|
77
|
-
/** Fields to collect from user */
|
|
78
|
-
readonly fields: readonly ElicitInputField[];
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Type guard for ElicitInputEffect
|
|
82
|
-
*/
|
|
83
|
-
declare const isElicitInputEffect: (effect: PfEffect) => effect is ElicitInputEffect;
|
|
84
|
-
/**
|
|
85
|
-
* Result of running a command
|
|
86
|
-
*/
|
|
87
|
-
interface PfCommandResult {
|
|
88
|
-
/** Domain effects to be applied by the runtime */
|
|
89
|
-
effects: PfEffect[];
|
|
90
|
-
/** Optional output to display (for read-only commands) */
|
|
91
|
-
output?: string | string[];
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Command argument definition
|
|
95
|
-
*/
|
|
96
|
-
interface PfCommandArg {
|
|
97
|
-
name: string;
|
|
98
|
-
description: string;
|
|
99
|
-
required: boolean;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Command option definition
|
|
103
|
-
*/
|
|
104
|
-
interface PfCommandOption {
|
|
105
|
-
flags: string;
|
|
106
|
-
description: string;
|
|
107
|
-
default?: unknown;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* A CLI command provided by a plugin
|
|
111
|
-
*
|
|
112
|
-
* Plugins MUST implement this exact interface.
|
|
113
|
-
*/
|
|
114
|
-
interface PfCommand {
|
|
115
|
-
name: string;
|
|
116
|
-
description: string;
|
|
117
|
-
args: PfCommandArg[];
|
|
118
|
-
options: PfCommandOption[];
|
|
119
|
-
run(args: Record<string, unknown>, options: Record<string, unknown>): Promise<PfCommandResult>;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* An interactive flow provided by a plugin
|
|
123
|
-
*/
|
|
124
|
-
interface PfFlow {
|
|
125
|
-
name: string;
|
|
126
|
-
description: string;
|
|
127
|
-
getSteps(initialContext?: Record<string, unknown>): Promise<unknown[]>;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Workspace context with all discovered information
|
|
131
|
-
* pf owns this - plugins receive it during setup
|
|
132
|
-
*/
|
|
133
|
-
interface PfWorkspaceContext {
|
|
134
|
-
/** Absolute path to workspace root */
|
|
135
|
-
workspaceRoot: string;
|
|
136
|
-
/** Discovered services (relative paths like 'services/api-gateway') */
|
|
137
|
-
availableServices: string[];
|
|
138
|
-
/** Contracts package configuration */
|
|
139
|
-
contracts: {
|
|
140
|
-
/** Relative path to contracts source (e.g., 'packages/contracts/src') */
|
|
141
|
-
path: string;
|
|
142
|
-
/** Package name (e.g., '@my-platform/contracts') */
|
|
143
|
-
packageName?: string;
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Plugin context provided by pf during setup
|
|
148
|
-
*/
|
|
149
|
-
interface PfPluginContext {
|
|
150
|
-
workspace: PfWorkspaceContext;
|
|
151
|
-
logger: {
|
|
152
|
-
debug: (message: string) => void;
|
|
153
|
-
info: (message: string) => void;
|
|
154
|
-
warn: (message: string) => void;
|
|
155
|
-
error: (message: string) => void;
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* A plugin that can be loaded by pf
|
|
160
|
-
*
|
|
161
|
-
* Plugins MUST implement this exact interface.
|
|
162
|
-
* If a plugin has a different internal API, it must provide an adapter.
|
|
163
|
-
*/
|
|
164
|
-
interface PfPlugin {
|
|
165
|
-
name: string;
|
|
166
|
-
version: string;
|
|
167
|
-
description?: string;
|
|
168
|
-
commands: PfCommand[];
|
|
169
|
-
flows: PfFlow[];
|
|
170
|
-
setup: (context: PfPluginContext) => Promise<void> | void;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Result of loading a plugin
|
|
174
|
-
*/
|
|
175
|
-
interface LoadedPlugin {
|
|
176
|
-
plugin: PfPlugin;
|
|
177
|
-
source: string;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export { type ElicitInputEffect as E, type FileWriteEffect as F, type InfraAddEffect as I, type LoadedPlugin as L, type PfWorkspaceContext as P, type PfPluginContext as a, type PfPlugin as b, type PfCommand as c, type PfCommandArg as d, type PfCommandOption as e, type PfFlow as f, type PfEffect as g, type ElicitInputField as h, type EnvAddEffect as i, type PfCommandResult as j, isElicitInputEffect as k };
|