@travetto/llm-support 8.0.0-alpha.20

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 (84) hide show
  1. package/README.md +101 -0
  2. package/__index__.ts +11 -0
  3. package/llm/consumer/INSTRUCTIONS.md +44 -0
  4. package/llm/maintainer/INSTRUCTIONS.md +37 -0
  5. package/package.json +56 -0
  6. package/resources/snippets/autograph-cli-orchestration.md +21 -0
  7. package/resources/snippets/code/aws-lambda-package-and-deploy.yml.tpl +36 -0
  8. package/resources/snippets/code/cache-enhancements.config.ts.tpl +6 -0
  9. package/resources/snippets/code/cache-enhancements.service.ts.tpl +16 -0
  10. package/resources/snippets/code/create-web-interceptor.ts.tpl +15 -0
  11. package/resources/snippets/code/create-web-route.controller.ts.tpl +15 -0
  12. package/resources/snippets/code/create-web-route.service.ts.tpl +8 -0
  13. package/resources/snippets/code/email-config.ts.tpl +6 -0
  14. package/resources/snippets/code/email-context-schema.ts.tpl +7 -0
  15. package/resources/snippets/code/email-create-template.mustache.tpl +2 -0
  16. package/resources/snippets/code/email-fixture.json.tpl +6 -0
  17. package/resources/snippets/code/email-preview-test.ts.tpl +14 -0
  18. package/resources/snippets/code/email-render-pipeline.ts.tpl +12 -0
  19. package/resources/snippets/code/email-send-controller.ts.tpl +18 -0
  20. package/resources/snippets/code/email-transport-provider.ts.tpl +8 -0
  21. package/resources/snippets/code/enable-auth-session.config.ts.tpl +34 -0
  22. package/resources/snippets/code/enable-auth-session.controller.ts.tpl +30 -0
  23. package/resources/snippets/code/enable-file-upload.config.ts.tpl +6 -0
  24. package/resources/snippets/code/enable-file-upload.controller.ts.tpl +16 -0
  25. package/resources/snippets/code/enable-linting.package.json.tpl +13 -0
  26. package/resources/snippets/code/generate-config.app-config.ts.tpl +7 -0
  27. package/resources/snippets/code/generate-config.application.yml.tpl +3 -0
  28. package/resources/snippets/code/generate-config.local.yml.tpl +2 -0
  29. package/resources/snippets/code/generate-test-suite.fixture.json.tpl +4 -0
  30. package/resources/snippets/code/generate-test-suite.unit.ts.tpl +11 -0
  31. package/resources/snippets/code/model-indexed.indexes.ts.tpl +14 -0
  32. package/resources/snippets/code/model-indexed.model.ts.tpl +8 -0
  33. package/resources/snippets/code/model-indexed.service.ts.tpl +15 -0
  34. package/resources/snippets/code/model-query.service.ts.tpl +18 -0
  35. package/resources/snippets/code/openapi-client-generation.readme.tpl +13 -0
  36. package/resources/snippets/code/openapi-client-generation.yml.tpl +20 -0
  37. package/resources/snippets/code/openapi-spec-pipeline.yml.tpl +21 -0
  38. package/resources/snippets/code/pack-docker-release.yml.tpl +21 -0
  39. package/resources/snippets/code/project-bootstrap.application.yml.tpl +2 -0
  40. package/resources/snippets/code/project-bootstrap.home-controller.ts.tpl +15 -0
  41. package/resources/snippets/code/project-bootstrap.home-service.ts.tpl +8 -0
  42. package/resources/snippets/code/project-bootstrap.monorepo.package.json.tpl +12 -0
  43. package/resources/snippets/code/project-bootstrap.package.json.tpl +18 -0
  44. package/resources/snippets/code/repo-version-release.yml.tpl +25 -0
  45. package/resources/snippets/code/rest-rpc-client.client.ts.tpl +8 -0
  46. package/resources/snippets/code/rest-rpc-client.index.ts.tpl +1 -0
  47. package/resources/snippets/code/workflow-cloudfront-deploy.yml.tpl +18 -0
  48. package/resources/snippets/code/workflow-gcp-deploy.yml.tpl +18 -0
  49. package/resources/snippets/core-aws-lambda-package-and-deploy.md +21 -0
  50. package/resources/snippets/core-email-compiler-pattern.md +21 -0
  51. package/resources/snippets/core-email-module-contract.md +21 -0
  52. package/resources/snippets/core-email-nodemailer-provider.md +21 -0
  53. package/resources/snippets/core-eslint-ruleset.md +21 -0
  54. package/resources/snippets/core-openapi-client-generation.md +21 -0
  55. package/resources/snippets/core-openapi-spec-pipeline.md +21 -0
  56. package/resources/snippets/core-pack-docker-release.md +21 -0
  57. package/resources/snippets/core-repo-version-release.md +21 -0
  58. package/resources/snippets/core-upload-pattern.md +21 -0
  59. package/resources/snippets/core-web-controller-pattern.md +23 -0
  60. package/resources/snippets/core-work-pool-pattern.md +23 -0
  61. package/resources/snippets/embracinglife-cloudfront-deploy.md +21 -0
  62. package/resources/snippets/embracinglife-gcp-deploy.md +21 -0
  63. package/resources/snippets/recipe-auth-google-oauth.md +21 -0
  64. package/resources/snippets/recipe-indexed-model-pattern.md +21 -0
  65. package/resources/snippets/recipe-upload-presigned.md +21 -0
  66. package/resources/snippets/todo-app-test-pattern.md +21 -0
  67. package/src/consumer-docs.ts +23 -0
  68. package/src/execute.ts +624 -0
  69. package/src/install-guidance.ts +187 -0
  70. package/src/mcp.ts +170 -0
  71. package/src/plan.ts +110 -0
  72. package/src/recommendation.ts +306 -0
  73. package/src/snippet-catalog.ts +80 -0
  74. package/src/snippet-shapes.ts +14 -0
  75. package/src/template-shapes.ts +13 -0
  76. package/src/tooling.ts +197 -0
  77. package/src/types.ts +215 -0
  78. package/src/workflow-guidance.ts +220 -0
  79. package/support/base-command.ts +57 -0
  80. package/support/cli.llm_support_execute.ts +80 -0
  81. package/support/cli.llm_support_mcp.ts +62 -0
  82. package/support/cli.llm_support_plan.ts +30 -0
  83. package/support/cli.llm_support_recommend.ts +34 -0
  84. package/support/cli.llm_support_status.ts +30 -0
@@ -0,0 +1,187 @@
1
+ import { type DependencyGraphNode, type InstallGuidance } from './types.ts';
2
+
3
+ export const INSTALL_BUNDLES: InstallGuidance[] = [
4
+ {
5
+ id: 'web-api-baseline',
6
+ title: 'Web API Baseline',
7
+ required: ['@travetto/runtime', '@travetto/config', '@travetto/schema', '@travetto/di', '@travetto/web'],
8
+ optional: ['@travetto/openapi', '@travetto/log', '@travetto/test'],
9
+ notes: [
10
+ 'Use this baseline for HTTP endpoint development with dependency injection and schema contracts.',
11
+ 'Add @travetto/openapi when API contract generation is required.'
12
+ ]
13
+ },
14
+ {
15
+ id: 'auth-enabled-web',
16
+ title: 'Auth Enabled Web',
17
+ required: ['@travetto/web', '@travetto/auth', '@travetto/auth-web'],
18
+ optional: ['@travetto/auth-session', '@travetto/auth-web-session', '@travetto/auth-web-passport'],
19
+ notes: [
20
+ 'Start with auth plus auth-web for core identity and permission checks in HTTP flows.',
21
+ 'Session and passport adapters are optional and depend on runtime identity needs.'
22
+ ]
23
+ },
24
+ {
25
+ id: 'auth-google-passport-web',
26
+ title: 'Google OAuth with Passport (Web)',
27
+ required: [
28
+ '@travetto/web',
29
+ '@travetto/auth',
30
+ '@travetto/auth-web',
31
+ '@travetto/auth-web-passport',
32
+ '@travetto/config',
33
+ 'passport',
34
+ 'passport-google-oauth20'
35
+ ],
36
+ optional: ['@travetto/model', '@travetto/model-indexed', '@travetto/model-firestore', '@travetto/auth-model'],
37
+ notes: [
38
+ 'Define google.auth config fields (clientID, clientSecret, callbackUrl) and bind with @Config.',
39
+ 'Register a PassportAuthenticator using OAuth2Strategy and map profile -> principal details.',
40
+ 'If persisting principals by external id, add one model adapter (for example @travetto/model-firestore) and an indexed lookup.'
41
+ ]
42
+ },
43
+ {
44
+ id: 'model-persistence-stack',
45
+ title: 'Model Persistence Stack',
46
+ required: ['@travetto/model'],
47
+ optional: [
48
+ '@travetto/model-query',
49
+ '@travetto/model-indexed',
50
+ '@travetto/model-sql',
51
+ '@travetto/model-postgres',
52
+ '@travetto/model-mysql',
53
+ '@travetto/model-sqlite',
54
+ '@travetto/model-memory',
55
+ '@travetto/model-mongo',
56
+ '@travetto/model-dynamodb',
57
+ '@travetto/model-file',
58
+ '@travetto/model-firestore',
59
+ '@travetto/model-redis',
60
+ '@travetto/model-s3',
61
+ '@travetto/model-elasticsearch',
62
+ '@travetto/model-query-language'
63
+ ],
64
+ notes: [
65
+ 'Pick one adapter family first (SQL or non-SQL), then select one primary adapter package for your datastore target.',
66
+ 'Use needs-driven adapter selection (blob/query/indexed/expiry) to narrow non-SQL options before finalizing a package.',
67
+ 'Add @travetto/model-query-language when exposing user-facing query parsing.'
68
+ ]
69
+ },
70
+ {
71
+ id: 'worker-baseline',
72
+ title: 'Worker Baseline',
73
+ required: ['@travetto/runtime', '@travetto/config', '@travetto/worker'],
74
+ optional: ['@travetto/model', '@travetto/log', '@travetto/context'],
75
+ notes: [
76
+ 'Use worker for scheduled or background job execution.',
77
+ 'Add model when jobs persist state between runs.'
78
+ ]
79
+ },
80
+ {
81
+ id: 'quality-lint-and-test',
82
+ title: 'Quality Setup (Lint + Test)',
83
+ required: ['@travetto/test', '@travetto/eslint'],
84
+ optional: ['@travetto/log'],
85
+ notes: [
86
+ 'Use this bundle for project quality guardrails and lint-fix workflows.',
87
+ 'Pair with generated operation plans so every new feature ships with test and lint coverage.'
88
+ ]
89
+ },
90
+ {
91
+ id: 'web-auth-session-stack',
92
+ title: 'Web Auth + Session Stack',
93
+ required: [
94
+ '@travetto/web',
95
+ '@travetto/auth',
96
+ '@travetto/auth-web',
97
+ '@travetto/auth-session',
98
+ '@travetto/auth-web-session',
99
+ '@travetto/model-memory'
100
+ ],
101
+ optional: ['@travetto/model', '@travetto/model-indexed'],
102
+ notes: [
103
+ 'Use this bundle for login/self/logout flows with session-backed identity.',
104
+ 'Use model-memory for local session storage unless a persistent session store is required.'
105
+ ]
106
+ },
107
+ {
108
+ id: 'web-model-crud',
109
+ title: 'Web + Model CRUD',
110
+ required: ['@travetto/web', '@travetto/model', '@travetto/model-query', '@travetto/schema', '@travetto/di'],
111
+ optional: ['@travetto/auth', '@travetto/auth-web', '@travetto/model-indexed'],
112
+ notes: [
113
+ 'Use this bundle when creating route/controller/service flows backed by model-query.',
114
+ 'Add auth/auth-web when CRUD endpoints should be principal-scoped.'
115
+ ]
116
+ },
117
+ {
118
+ id: 'model-backend-selection',
119
+ title: 'Model Backend Selection',
120
+ required: ['@travetto/model'],
121
+ optional: [
122
+ '@travetto/model-elasticsearch',
123
+ '@travetto/model-mongo',
124
+ '@travetto/model-sql',
125
+ '@travetto/model-mysql',
126
+ '@travetto/model-postgres',
127
+ '@travetto/model-sqlite'
128
+ ],
129
+ notes: [
130
+ 'Use this bundle to drive backend selection prompts for datastore adapters.',
131
+ 'Choose exactly one backend adapter for active datastore target.'
132
+ ]
133
+ },
134
+ {
135
+ id: 'email-generation-stack',
136
+ title: 'Email Generation + Delivery',
137
+ required: ['@travetto/email'],
138
+ optional: ['@travetto/email-compiler', '@travetto/email-inky', '@travetto/email-nodemailer', '@travetto/worker'],
139
+ notes: [
140
+ 'Use this bundle when generating templates, compiler pipelines, and transport wiring.',
141
+ 'Add worker when routing send operations through async background execution.'
142
+ ]
143
+ }
144
+ ];
145
+
146
+ export const DEPENDENCY_GRAPH: DependencyGraphNode[] = [
147
+ {
148
+ package: '@travetto/auth',
149
+ requires: ['@travetto/runtime', '@travetto/schema', '@travetto/di'],
150
+ optionalAdapters: ['@travetto/auth-model', '@travetto/auth-session']
151
+ },
152
+ {
153
+ package: '@travetto/web',
154
+ requires: ['@travetto/runtime', '@travetto/config', '@travetto/schema', '@travetto/di'],
155
+ optionalAdapters: ['@travetto/web-express', '@travetto/web-fastify', '@travetto/web-koa']
156
+ },
157
+ {
158
+ package: '@travetto/auth-web',
159
+ requires: ['@travetto/auth', '@travetto/web'],
160
+ optionalAdapters: ['@travetto/auth-web-session', '@travetto/auth-web-passport']
161
+ },
162
+ {
163
+ package: '@travetto/model',
164
+ requires: ['@travetto/schema', '@travetto/di', '@travetto/config'],
165
+ optionalAdapters: [
166
+ '@travetto/model-memory',
167
+ '@travetto/model-sql',
168
+ '@travetto/model-mongo',
169
+ '@travetto/model-dynamodb',
170
+ '@travetto/model-file',
171
+ '@travetto/model-firestore',
172
+ '@travetto/model-redis',
173
+ '@travetto/model-s3',
174
+ '@travetto/model-elasticsearch'
175
+ ]
176
+ },
177
+ {
178
+ package: '@travetto/model-query',
179
+ requires: ['@travetto/model'],
180
+ optionalAdapters: ['@travetto/model-query-language']
181
+ },
182
+ {
183
+ package: '@travetto/worker',
184
+ requires: ['@travetto/runtime', '@travetto/config'],
185
+ optionalAdapters: ['@travetto/model', '@travetto/log', '@travetto/context']
186
+ }
187
+ ];
package/src/mcp.ts ADDED
@@ -0,0 +1,170 @@
1
+ import { Schema } from '@travetto/schema';
2
+ import { JSONUtil } from '@travetto/runtime';
3
+
4
+ import { getLlmSupportToolDefinitions, runLlmSupportTool, type LlmSupportToolName } from './tooling.ts';
5
+
6
+ @Schema()
7
+ export class JsonRpcRequestSchema {
8
+ jsonrpc?: '2.0';
9
+
10
+ id?: string | number | null;
11
+
12
+ method: string;
13
+
14
+ params?: unknown;
15
+ }
16
+
17
+ @Schema()
18
+ export class JsonRpcErrorSchema {
19
+ code = 0;
20
+ message = '';
21
+
22
+ data?: unknown;
23
+ }
24
+
25
+ @Schema()
26
+ export class JsonRpcResponseSchema {
27
+ jsonrpc: '2.0';
28
+ id: string | number | null;
29
+
30
+ result?: unknown;
31
+
32
+ error?: JsonRpcErrorSchema;
33
+ }
34
+
35
+ @Schema()
36
+ export class McpInitializeCapabilitiesSchema {
37
+ tools?: object;
38
+ }
39
+
40
+ @Schema()
41
+ export class McpInitializeServerInfoSchema {
42
+ name?: string;
43
+ version?: string;
44
+ }
45
+
46
+ @Schema()
47
+ export class McpInitializeResultSchema {
48
+ protocolVersion?: string;
49
+ capabilities?: McpInitializeCapabilitiesSchema;
50
+ serverInfo?: McpInitializeServerInfoSchema;
51
+ }
52
+
53
+ @Schema()
54
+ export class McpToolDefinitionSchema {
55
+ name = '';
56
+ description = '';
57
+ inputSchema?: object;
58
+ }
59
+
60
+ @Schema()
61
+ export class McpToolsListResultSchema {
62
+ tools: McpToolDefinitionSchema[] = [];
63
+ }
64
+
65
+ @Schema()
66
+ export class McpToolCallContentSchema {
67
+ type = '';
68
+ text = '';
69
+ }
70
+
71
+ @Schema()
72
+ export class McpToolCallResultSchema {
73
+ content: McpToolCallContentSchema[] = [];
74
+ structuredContent?: unknown;
75
+ }
76
+
77
+ export type JsonRpcRequest = InstanceType<typeof JsonRpcRequestSchema>;
78
+ export type JsonRpcResponse = InstanceType<typeof JsonRpcResponseSchema>;
79
+
80
+ const PROTOCOL_VERSION = '2024-11-05';
81
+
82
+ function toError(id: string | number | null, code: number, message: string, data?: unknown): JsonRpcResponse {
83
+ return {
84
+ jsonrpc: '2.0',
85
+ id,
86
+ error: {
87
+ code,
88
+ message,
89
+ data
90
+ }
91
+ };
92
+ }
93
+
94
+ function toResult(id: string | number | null, result: unknown): JsonRpcResponse {
95
+ return {
96
+ jsonrpc: '2.0',
97
+ id,
98
+ result
99
+ };
100
+ }
101
+
102
+ function asObject(value: unknown): Record<string, unknown> {
103
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
104
+ return {};
105
+ }
106
+ return Object.fromEntries(Object.entries(value));
107
+ }
108
+
109
+ function toToolName(value: unknown): LlmSupportToolName | undefined {
110
+ if (typeof value !== 'string') {
111
+ return undefined;
112
+ }
113
+ if (value === 'llm_support_recommend' || value === 'llm_support_plan' || value === 'llm_support_execute') {
114
+ return value;
115
+ }
116
+ return undefined;
117
+ }
118
+
119
+ export async function handleMcpRequest(input: JsonRpcRequest): Promise<JsonRpcResponse | undefined> {
120
+ const id = input.id ?? null;
121
+
122
+ switch (input.method) {
123
+ case 'initialize':
124
+ return toResult(id, {
125
+ protocolVersion: PROTOCOL_VERSION,
126
+ capabilities: {
127
+ tools: {}
128
+ },
129
+ serverInfo: {
130
+ name: '@travetto/llm-support',
131
+ version: '1.0.0'
132
+ }
133
+ });
134
+
135
+ case 'notifications/initialized':
136
+ return undefined;
137
+
138
+ case 'tools/list':
139
+ return toResult(id, {
140
+ tools: getLlmSupportToolDefinitions()
141
+ });
142
+
143
+ case 'tools/call': {
144
+ const params = asObject(input.params);
145
+ const name = toToolName(params.name);
146
+ if (!name) {
147
+ return toError(id, -32602, 'Invalid tool name', { name: params.name });
148
+ }
149
+ try {
150
+ const args = asObject(params.arguments);
151
+ const output = await runLlmSupportTool(name, args);
152
+ return toResult(id, {
153
+ content: [
154
+ {
155
+ type: 'text',
156
+ text: JSONUtil.toUTF8(output, { indent: 2 })
157
+ }
158
+ ],
159
+ structuredContent: output
160
+ });
161
+ } catch (err) {
162
+ const message = err instanceof Error ? err.message : 'Tool execution failed';
163
+ return toError(id, -32000, message);
164
+ }
165
+ }
166
+
167
+ default:
168
+ return toError(id, -32601, `Method not found: ${input.method}`);
169
+ }
170
+ }
package/src/plan.ts ADDED
@@ -0,0 +1,110 @@
1
+ import { recommend, recommendOperations } from './recommendation.ts';
2
+ import type {
3
+ LlmOperation,
4
+ OperationPlan,
5
+ PlanResponse,
6
+ PlannedChange,
7
+ RecommendationQuery
8
+ } from './types.ts';
9
+
10
+ function filesFor(op: LlmOperation): string[] {
11
+ switch (op.id) {
12
+ case 'project-bootstrap':
13
+ return ['package.json', 'resources/application.yml', 'src/', 'packages/app/'];
14
+ case 'create-web-route':
15
+ return ['src/web/', 'src/service/'];
16
+ case 'enable-file-upload':
17
+ return ['src/web/', 'src/config/'];
18
+ case 'enable-auth-session':
19
+ return ['src/web/auth.ts', 'src/web/auth.config.ts'];
20
+ case 'rest-rpc-client':
21
+ return ['src/client/', '__index__.ts'];
22
+ case 'model-indexed-assistant':
23
+ return ['src/model/', 'src/service/'];
24
+ case 'model-query-assistant':
25
+ return ['src/model/', 'src/service/'];
26
+ case 'workflow-gcp-deploy':
27
+ return ['.github/workflows/deploy-api.yml'];
28
+ case 'workflow-cloudfront-deploy':
29
+ return ['.github/workflows/deploy-ui.yml'];
30
+ case 'enable-linting':
31
+ return ['package.json'];
32
+ case 'generate-config':
33
+ return ['src/config/', 'resources/'];
34
+ case 'generate-test-suite':
35
+ return ['test/'];
36
+ case 'create-web-interceptor':
37
+ return ['src/interceptor/'];
38
+ case 'email-create-template':
39
+ return ['src/email/templates/'];
40
+ case 'email-context-schema':
41
+ return ['src/email/schema.ts'];
42
+ case 'email-render-pipeline':
43
+ return ['src/email/service.ts'];
44
+ case 'email-transport-provider':
45
+ return ['src/email/provider.ts', 'src/config/'];
46
+ case 'email-preview-snapshot':
47
+ return ['test/email/'];
48
+ case 'email-send-flow':
49
+ return ['src/web/', 'src/worker/'];
50
+ case 'email-test-fixtures':
51
+ return ['test/email/fixtures/'];
52
+ case 'cache-enhancements':
53
+ return ['src/service/', 'src/config/'];
54
+ default:
55
+ return ['src/'];
56
+ }
57
+ }
58
+
59
+ function changesFor(op: LlmOperation): PlannedChange[] {
60
+ return [
61
+ {
62
+ stepId: 'validate-assumptions',
63
+ step: 'Validate command and module assumptions',
64
+ files: [],
65
+ rationale: 'Use cli schema and module metadata to avoid stale command signatures.'
66
+ },
67
+ {
68
+ stepId: 'generate-artifacts',
69
+ step: 'Generate core implementation artifacts',
70
+ files: filesFor(op),
71
+ rationale: op.summary
72
+ },
73
+ {
74
+ stepId: 'verify-output',
75
+ step: 'Run verification checks',
76
+ files: [],
77
+ rationale: 'Compile, lint, and test generated code paths before apply confirmation.'
78
+ }
79
+ ];
80
+ }
81
+
82
+ function toPlan(op: LlmOperation): OperationPlan {
83
+ return {
84
+ operationId: op.id,
85
+ title: op.title,
86
+ requiredModules: op.requiredModules,
87
+ optionalModules: op.optionalModules,
88
+ changes: changesFor(op)
89
+ };
90
+ }
91
+
92
+ export async function buildPlans(query: RecommendationQuery = {}): Promise<PlanResponse> {
93
+ const operations = query.operations && query.operations.length > 0 ?
94
+ recommendOperations({
95
+ categories: query.categories,
96
+ includeExcluded: query.includeExcluded
97
+ }).filter(item => query.operations?.includes(item.id)) :
98
+ recommendOperations({
99
+ categories: query.categories,
100
+ includeExcluded: query.includeExcluded
101
+ });
102
+
103
+ const plans = operations.map(toPlan);
104
+ const snippets = (await recommend({
105
+ ...query,
106
+ operations: plans.map(item => item.operationId)
107
+ })).snippets;
108
+
109
+ return { plans, snippets };
110
+ }