@fatagnus/dink-convex 2.0.2 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -262,6 +262,64 @@ Set these in your Convex dashboard:
262
262
  - `createSyncCrons({ internal })` - Creates cron job for outbox processing
263
263
  - `createSyncMutation(mutation, tables, options)` - Creates sync-enabled mutation wrapper
264
264
 
265
+ ### Introspection Functions
266
+
267
+ - `describeEdgeServices(ctx, serviceName)` - Describe an edge service by name, returning its ServiceDescriptor
268
+ - `getLLMContext(ctx, serviceNames?)` - Get LLM-friendly context (llm.txt format) for edge services
269
+
270
+ #### describeEdgeServices
271
+
272
+ Returns structured metadata about an edge service:
273
+
274
+ ```typescript
275
+ import { describeEdgeServices } from "@fatagnus/dink-convex";
276
+ import { action } from "./_generated/server";
277
+ import { v } from "convex/values";
278
+
279
+ export const getServiceInfo = action({
280
+ args: { serviceName: v.string() },
281
+ handler: async (ctx, args) => {
282
+ const descriptor = await describeEdgeServices(ctx, args.serviceName);
283
+ return {
284
+ name: descriptor.name,
285
+ version: descriptor.version,
286
+ description: descriptor.description,
287
+ methods: descriptor.methods?.map(m => ({
288
+ name: m.name,
289
+ description: m.description,
290
+ })),
291
+ };
292
+ },
293
+ });
294
+ ```
295
+
296
+ #### getLLMContext
297
+
298
+ Returns human/AI-readable documentation for services in llm.txt format:
299
+
300
+ ```typescript
301
+ import { getLLMContext } from "@fatagnus/dink-convex";
302
+ import { action } from "./_generated/server";
303
+ import { v } from "convex/values";
304
+
305
+ // Get context for all services
306
+ export const getAllServiceDocs = action({
307
+ handler: async (ctx) => {
308
+ return await getLLMContext(ctx);
309
+ },
310
+ });
311
+
312
+ // Get context for specific services
313
+ export const getServiceDocs = action({
314
+ args: { services: v.array(v.string()) },
315
+ handler: async (ctx, args) => {
316
+ return await getLLMContext(ctx, args.services);
317
+ },
318
+ });
319
+ ```
320
+
321
+ Both functions require `DINK_URL` and `DINK_APP_SYNC_KEY` environment variables to be configured.
322
+
265
323
  ## Troubleshooting
266
324
 
267
325
  ### "DINK_APP_SYNC_KEY environment variable is not configured"
package/dist/index.d.ts CHANGED
@@ -65,6 +65,7 @@ export { createSyncMutation, type SyncCronsConfig } from "./factories.js";
65
65
  export { syncTriggers, registerSyncedTable, isSyncedTable, getSyncConfig, createDeltaRecord, createOutboxRecord, createSyncTriggerHandler, createSyncTriggerHandlerAsync, createSyncTriggerHandlerWithScheduling, scheduleImmediateProcessing, getNextSeq, getNextSeqAsync, createSequenceCounter, checkSyncConfigEnabled, createSyncConfigChecker, createConfigAwareSyncTriggerHandler, createSyncTriggers, createSyncTriggersWithHandlers, customMutation, type SequenceCounter, } from "./triggers.js";
66
66
  export { callEdge, scatterCall, discoverEdges, getEdgeRpcConfig, buildCallEdgeUrl, buildScatterCallUrl, buildDiscoverEdgesUrl, buildCallEdgePayload, buildScatterCallPayload, parseCallEdgeResponse, parseScatterCallResponse, parseDiscoverEdgesResponse, EdgeRpcError, EDGE_RPC_ERROR_CODES, type CallEdgeOptions, type ScatterCallOptions, type DiscoverEdgesOptions, type CallEdgeResult, type ScatterCallResult, type ScatterCallResultItem, type EdgeInfo, type EdgeRpcConfig, } from "./edgeRpc.js";
67
67
  export { registerReplicateComponent, hasReplicateComponent, getReplicateComponent, clearReplicateComponent, forwardToReplicate, type ReplicateComponent, type DeltaData, type ForwardContext, } from "./replicateBridge.js";
68
- export declare const VERSION = "2.0.0";
68
+ export { describeEdgeServices, getLLMContext, getIntrospectConfig, buildDescribeUrl, buildLLMContextUrl, parseDescribeResponse, parseLLMContextResponse, IntrospectError, INTROSPECT_ERROR_CODES, type ServiceDescriptor, type MethodDescriptor, type ServiceAIContext, type MethodAIContext, type IntrospectConfig, } from "./introspect.js";
69
+ export declare const VERSION = "2.4.0";
69
70
  export type { SyncedTableConfig } from "./schema.js";
70
71
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAGH,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG1E,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mCAAmC,EACnC,kBAAkB,EAClB,8BAA8B,EAC9B,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,YAAY,EACZ,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAGH,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG1E,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mCAAmC,EACnC,kBAAkB,EAClB,8BAA8B,EAC9B,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,YAAY,EACZ,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AAGzB,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -72,6 +72,8 @@ export { syncTriggers, registerSyncedTable, isSyncedTable, getSyncConfig, create
72
72
  export { callEdge, scatterCall, discoverEdges, getEdgeRpcConfig, buildCallEdgeUrl, buildScatterCallUrl, buildDiscoverEdgesUrl, buildCallEdgePayload, buildScatterCallPayload, parseCallEdgeResponse, parseScatterCallResponse, parseDiscoverEdgesResponse, EdgeRpcError, EDGE_RPC_ERROR_CODES, } from "./edgeRpc.js";
73
73
  // Replicate bridge utility
74
74
  export { registerReplicateComponent, hasReplicateComponent, getReplicateComponent, clearReplicateComponent, forwardToReplicate, } from "./replicateBridge.js";
75
+ // Introspection helpers
76
+ export { describeEdgeServices, getLLMContext, getIntrospectConfig, buildDescribeUrl, buildLLMContextUrl, parseDescribeResponse, parseLLMContextResponse, IntrospectError, INTROSPECT_ERROR_CODES, } from "./introspect.js";
75
77
  // Component version
76
- export const VERSION = "2.0.0";
78
+ export const VERSION = "2.4.0";
77
79
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,iBAAiB;AACjB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,iBAAiB;AACjB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GAEpB,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAOhB,MAAM,oBAAoB,CAAC;AAE5B,sEAAsE;AACtE,OAAO,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAE1E,+CAA+C;AAC/C,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mCAAmC,EACnC,kBAAkB,EAClB,8BAA8B,EAC9B,cAAc,GAEf,MAAM,eAAe,CAAC;AAEvB,2BAA2B;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,YAAY,EACZ,oBAAoB,GASrB,MAAM,cAAc,CAAC;AAEtB,2BAA2B;AAC3B,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,GAInB,MAAM,sBAAsB,CAAC;AAE9B,oBAAoB;AACpB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,iBAAiB;AACjB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,iBAAiB;AACjB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GAEpB,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAOhB,MAAM,oBAAoB,CAAC;AAE5B,sEAAsE;AACtE,OAAO,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAE1E,+CAA+C;AAC/C,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mCAAmC,EACnC,kBAAkB,EAClB,8BAA8B,EAC9B,cAAc,GAEf,MAAM,eAAe,CAAC;AAEvB,2BAA2B;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,YAAY,EACZ,oBAAoB,GASrB,MAAM,cAAc,CAAC;AAEtB,2BAA2B;AAC3B,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,GAInB,MAAM,sBAAsB,CAAC;AAE9B,wBAAwB;AACxB,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,GAMvB,MAAM,iBAAiB,CAAC;AAEzB,oBAAoB;AACpB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Introspection Helpers for Convex
3
+ *
4
+ * These helpers allow Convex actions to introspect edge services and get
5
+ * LLM-friendly context via dinkd HTTP endpoints.
6
+ *
7
+ * @module introspect
8
+ */
9
+ /**
10
+ * Action context type (minimal interface for fetch operations).
11
+ * In generated code, this will be the full Convex ActionCtx.
12
+ */
13
+ interface ActionCtx {
14
+ }
15
+ /**
16
+ * MethodAIContext provides AI-specific guidance for understanding and using a method.
17
+ */
18
+ export interface MethodAIContext {
19
+ /** When this method should be called */
20
+ when_to_use?: string;
21
+ /** Why to use this method over alternatives */
22
+ why_to_use?: string;
23
+ /** Instructions on how to use this method correctly */
24
+ how_to_use?: string;
25
+ /** Conditions that must be true before calling this method */
26
+ preconditions?: string[];
27
+ /** Side effects that occur when calling this method */
28
+ side_effects?: string[];
29
+ /** Names of related methods that may be useful */
30
+ related_methods?: string[];
31
+ /** Scenarios describing when to use this method */
32
+ scenarios?: string[];
33
+ }
34
+ /**
35
+ * ServiceAIContext provides AI-specific guidance for understanding a service.
36
+ */
37
+ export interface ServiceAIContext {
38
+ /** High-level description of what this service does */
39
+ overview?: string;
40
+ /** List of capabilities this service provides */
41
+ capabilities?: string[];
42
+ /** Known limitations of this service */
43
+ limitations?: string[];
44
+ }
45
+ /**
46
+ * MethodDescriptor provides complete metadata about a service method.
47
+ */
48
+ export interface MethodDescriptor {
49
+ /** Method name */
50
+ name: string;
51
+ /** Human-readable description of what this method does */
52
+ description?: string;
53
+ /** JSON Schema describing the input parameters */
54
+ input_schema?: Record<string, unknown>;
55
+ /** JSON Schema describing the output */
56
+ output_schema?: Record<string, unknown>;
57
+ /** Tags for categorization and filtering */
58
+ tags?: string[];
59
+ /** AI-specific context for this method */
60
+ ai_context?: MethodAIContext;
61
+ }
62
+ /**
63
+ * ServiceDescriptor provides complete metadata about a service.
64
+ */
65
+ export interface ServiceDescriptor {
66
+ /** Service name */
67
+ name: string;
68
+ /** Service version (semver recommended) */
69
+ version: string;
70
+ /** Human-readable description of this service */
71
+ description?: string;
72
+ /** Methods provided by this service */
73
+ methods?: MethodDescriptor[];
74
+ /** AI-specific context for this service */
75
+ ai_context?: ServiceAIContext;
76
+ /** Names of related services */
77
+ related_services?: string[];
78
+ }
79
+ /**
80
+ * Configuration for introspection operations.
81
+ */
82
+ export interface IntrospectConfig {
83
+ /** dinkd URL (from DINK_URL env var) */
84
+ dinkUrl: string | undefined;
85
+ /** App sync key (from DINK_APP_SYNC_KEY env var) */
86
+ appSyncKey: string | undefined;
87
+ }
88
+ /**
89
+ * Error codes for introspection operations.
90
+ */
91
+ export declare const INTROSPECT_ERROR_CODES: {
92
+ /** DINK_URL or DINK_APP_SYNC_KEY not configured */
93
+ readonly MISSING_CONFIG: "MISSING_CONFIG";
94
+ /** Network error during HTTP request */
95
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
96
+ /** Service not found */
97
+ readonly NOT_FOUND: "NOT_FOUND";
98
+ /** Authentication failed */
99
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
100
+ /** Server returned an error */
101
+ readonly SERVER_ERROR: "SERVER_ERROR";
102
+ /** Invalid input */
103
+ readonly INVALID_INPUT: "INVALID_INPUT";
104
+ };
105
+ /**
106
+ * Error type for introspection operations.
107
+ */
108
+ export declare class IntrospectError extends Error {
109
+ /** Error code */
110
+ readonly code: string;
111
+ constructor(code: string, message: string);
112
+ }
113
+ /**
114
+ * Get introspection configuration from environment variables.
115
+ *
116
+ * @returns Configuration object with dinkUrl and appSyncKey
117
+ */
118
+ export declare function getIntrospectConfig(): IntrospectConfig;
119
+ /**
120
+ * Build URL for single service describe endpoint.
121
+ *
122
+ * @param baseUrl - Base dinkd URL
123
+ * @param serviceName - Name of the service to describe
124
+ * @returns Full URL for /api/services/:service/llm.txt
125
+ */
126
+ export declare function buildDescribeUrl(baseUrl: string, serviceName: string): string;
127
+ /**
128
+ * Build URL for LLM context endpoint.
129
+ *
130
+ * @param baseUrl - Base dinkd URL
131
+ * @param serviceNames - Optional array of service names to filter
132
+ * @returns Full URL for /api/llm.txt with optional services query param
133
+ */
134
+ export declare function buildLLMContextUrl(baseUrl: string, serviceNames?: string[]): string;
135
+ /**
136
+ * HTTP response from describe endpoint (JSON format).
137
+ */
138
+ interface DescribeHttpResponse {
139
+ success: boolean;
140
+ services?: ServiceDescriptor[];
141
+ error?: string;
142
+ }
143
+ /**
144
+ * Parse describe endpoint JSON response into ServiceDescriptor.
145
+ *
146
+ * @param response - Raw HTTP response
147
+ * @returns Parsed ServiceDescriptor
148
+ * @throws IntrospectError if response indicates failure
149
+ */
150
+ export declare function parseDescribeResponse(response: DescribeHttpResponse): ServiceDescriptor;
151
+ /**
152
+ * Parse LLM context response (plain text).
153
+ *
154
+ * @param content - Raw text content
155
+ * @returns The LLM context string
156
+ */
157
+ export declare function parseLLMContextResponse(content: string): string;
158
+ /**
159
+ * Describe an edge service by name, returning its ServiceDescriptor.
160
+ *
161
+ * Makes an authenticated HTTP GET to dinkd /api/services/:service/llm.txt
162
+ * with Accept: application/json header to get structured service metadata.
163
+ *
164
+ * @param _ctx - Convex action context (unused, for future expansion)
165
+ * @param serviceName - The name of the service to describe
166
+ * @returns Promise resolving to the ServiceDescriptor
167
+ * @throws IntrospectError if configuration is missing, service not found, or request fails
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * import { describeEdgeServices } from "@fatagnus/dink-convex";
172
+ *
173
+ * export const getServiceInfo = action({
174
+ * args: { serviceName: v.string() },
175
+ * handler: async (ctx, args) => {
176
+ * const descriptor = await describeEdgeServices(ctx, args.serviceName);
177
+ * return {
178
+ * name: descriptor.name,
179
+ * version: descriptor.version,
180
+ * methods: descriptor.methods?.map(m => m.name),
181
+ * };
182
+ * },
183
+ * });
184
+ * ```
185
+ */
186
+ export declare function describeEdgeServices(_ctx: ActionCtx, serviceName: string): Promise<ServiceDescriptor>;
187
+ /**
188
+ * Get LLM-friendly context (llm.txt format) for edge services.
189
+ *
190
+ * Makes an authenticated HTTP GET to dinkd /api/llm.txt to get
191
+ * human/AI-readable documentation for services.
192
+ *
193
+ * @param _ctx - Convex action context (unused, for future expansion)
194
+ * @param serviceNames - Optional service name(s) to filter. Can be a single string or array.
195
+ * If omitted, returns context for all services.
196
+ * @returns Promise resolving to llm.txt formatted string
197
+ * @throws IntrospectError if configuration is missing or request fails
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * import { getLLMContext } from "@fatagnus/dink-convex";
202
+ *
203
+ * // Get context for all services
204
+ * export const getAllContext = action({
205
+ * handler: async (ctx) => {
206
+ * return await getLLMContext(ctx);
207
+ * },
208
+ * });
209
+ *
210
+ * // Get context for specific services
211
+ * export const getSpecificContext = action({
212
+ * args: { services: v.array(v.string()) },
213
+ * handler: async (ctx, args) => {
214
+ * return await getLLMContext(ctx, args.services);
215
+ * },
216
+ * });
217
+ * ```
218
+ */
219
+ export declare function getLLMContext(_ctx: ActionCtx, serviceNames?: string | string[]): Promise<string>;
220
+ export {};
221
+ //# sourceMappingURL=introspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Introspection Helpers for Convex
3
+ *
4
+ * These helpers allow Convex actions to introspect edge services and get
5
+ * LLM-friendly context via dinkd HTTP endpoints.
6
+ *
7
+ * @module introspect
8
+ */
9
+ // ============================================================================
10
+ // Error handling
11
+ // ============================================================================
12
+ /**
13
+ * Error codes for introspection operations.
14
+ */
15
+ export const INTROSPECT_ERROR_CODES = {
16
+ /** DINK_URL or DINK_APP_SYNC_KEY not configured */
17
+ MISSING_CONFIG: "MISSING_CONFIG",
18
+ /** Network error during HTTP request */
19
+ NETWORK_ERROR: "NETWORK_ERROR",
20
+ /** Service not found */
21
+ NOT_FOUND: "NOT_FOUND",
22
+ /** Authentication failed */
23
+ UNAUTHORIZED: "UNAUTHORIZED",
24
+ /** Server returned an error */
25
+ SERVER_ERROR: "SERVER_ERROR",
26
+ /** Invalid input */
27
+ INVALID_INPUT: "INVALID_INPUT",
28
+ };
29
+ /**
30
+ * Error type for introspection operations.
31
+ */
32
+ export class IntrospectError extends Error {
33
+ /** Error code */
34
+ code;
35
+ constructor(code, message) {
36
+ super(message);
37
+ this.name = "IntrospectError";
38
+ this.code = code;
39
+ }
40
+ }
41
+ // ============================================================================
42
+ // Configuration
43
+ // ============================================================================
44
+ /**
45
+ * Get introspection configuration from environment variables.
46
+ *
47
+ * @returns Configuration object with dinkUrl and appSyncKey
48
+ */
49
+ export function getIntrospectConfig() {
50
+ return {
51
+ dinkUrl: process.env.DINK_URL,
52
+ appSyncKey: process.env.DINK_APP_SYNC_KEY,
53
+ };
54
+ }
55
+ /**
56
+ * Validate that required configuration is present.
57
+ *
58
+ * @throws IntrospectError if configuration is missing
59
+ */
60
+ function validateConfig() {
61
+ const config = getIntrospectConfig();
62
+ if (!config.dinkUrl) {
63
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.MISSING_CONFIG, "DINK_URL environment variable is not configured");
64
+ }
65
+ if (!config.appSyncKey) {
66
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.MISSING_CONFIG, "DINK_APP_SYNC_KEY environment variable is not configured");
67
+ }
68
+ return {
69
+ dinkUrl: config.dinkUrl,
70
+ appSyncKey: config.appSyncKey,
71
+ };
72
+ }
73
+ // ============================================================================
74
+ // URL builders
75
+ // ============================================================================
76
+ /**
77
+ * Build URL for single service describe endpoint.
78
+ *
79
+ * @param baseUrl - Base dinkd URL
80
+ * @param serviceName - Name of the service to describe
81
+ * @returns Full URL for /api/services/:service/llm.txt
82
+ */
83
+ export function buildDescribeUrl(baseUrl, serviceName) {
84
+ const url = new URL(`/api/services/${serviceName}/llm.txt`, baseUrl);
85
+ return url.toString();
86
+ }
87
+ /**
88
+ * Build URL for LLM context endpoint.
89
+ *
90
+ * @param baseUrl - Base dinkd URL
91
+ * @param serviceNames - Optional array of service names to filter
92
+ * @returns Full URL for /api/llm.txt with optional services query param
93
+ */
94
+ export function buildLLMContextUrl(baseUrl, serviceNames) {
95
+ const url = new URL("/api/llm.txt", baseUrl);
96
+ if (serviceNames && serviceNames.length > 0) {
97
+ url.searchParams.set("services", serviceNames.join(","));
98
+ }
99
+ return url.toString();
100
+ }
101
+ // ============================================================================
102
+ // Response parsers
103
+ // ============================================================================
104
+ /**
105
+ * Parse describe endpoint JSON response into ServiceDescriptor.
106
+ *
107
+ * @param response - Raw HTTP response
108
+ * @returns Parsed ServiceDescriptor
109
+ * @throws IntrospectError if response indicates failure
110
+ */
111
+ export function parseDescribeResponse(response) {
112
+ if (!response.success) {
113
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.SERVER_ERROR, response.error || "Unknown server error");
114
+ }
115
+ if (!response.services || response.services.length === 0) {
116
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.NOT_FOUND, "No service descriptor found");
117
+ }
118
+ return response.services[0];
119
+ }
120
+ /**
121
+ * Parse LLM context response (plain text).
122
+ *
123
+ * @param content - Raw text content
124
+ * @returns The LLM context string
125
+ */
126
+ export function parseLLMContextResponse(content) {
127
+ return content;
128
+ }
129
+ // ============================================================================
130
+ // Main helper functions
131
+ // ============================================================================
132
+ /**
133
+ * Describe an edge service by name, returning its ServiceDescriptor.
134
+ *
135
+ * Makes an authenticated HTTP GET to dinkd /api/services/:service/llm.txt
136
+ * with Accept: application/json header to get structured service metadata.
137
+ *
138
+ * @param _ctx - Convex action context (unused, for future expansion)
139
+ * @param serviceName - The name of the service to describe
140
+ * @returns Promise resolving to the ServiceDescriptor
141
+ * @throws IntrospectError if configuration is missing, service not found, or request fails
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * import { describeEdgeServices } from "@fatagnus/dink-convex";
146
+ *
147
+ * export const getServiceInfo = action({
148
+ * args: { serviceName: v.string() },
149
+ * handler: async (ctx, args) => {
150
+ * const descriptor = await describeEdgeServices(ctx, args.serviceName);
151
+ * return {
152
+ * name: descriptor.name,
153
+ * version: descriptor.version,
154
+ * methods: descriptor.methods?.map(m => m.name),
155
+ * };
156
+ * },
157
+ * });
158
+ * ```
159
+ */
160
+ export async function describeEdgeServices(_ctx, serviceName) {
161
+ const config = validateConfig();
162
+ if (!serviceName) {
163
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.INVALID_INPUT, "service name is required");
164
+ }
165
+ const url = buildDescribeUrl(config.dinkUrl, serviceName);
166
+ const response = await fetch(url, {
167
+ method: "GET",
168
+ headers: {
169
+ Accept: "application/json",
170
+ Authorization: `Bearer ${config.appSyncKey}`,
171
+ },
172
+ });
173
+ if (response.status === 401) {
174
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.UNAUTHORIZED, "Invalid authorization token");
175
+ }
176
+ if (response.status === 404) {
177
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.NOT_FOUND, `Service not found: ${serviceName}`);
178
+ }
179
+ if (!response.ok) {
180
+ const errorText = await response.text().catch(() => "");
181
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.SERVER_ERROR, `Server error: ${response.status} ${response.statusText} - ${errorText}`);
182
+ }
183
+ const json = (await response.json());
184
+ return parseDescribeResponse(json);
185
+ }
186
+ /**
187
+ * Get LLM-friendly context (llm.txt format) for edge services.
188
+ *
189
+ * Makes an authenticated HTTP GET to dinkd /api/llm.txt to get
190
+ * human/AI-readable documentation for services.
191
+ *
192
+ * @param _ctx - Convex action context (unused, for future expansion)
193
+ * @param serviceNames - Optional service name(s) to filter. Can be a single string or array.
194
+ * If omitted, returns context for all services.
195
+ * @returns Promise resolving to llm.txt formatted string
196
+ * @throws IntrospectError if configuration is missing or request fails
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * import { getLLMContext } from "@fatagnus/dink-convex";
201
+ *
202
+ * // Get context for all services
203
+ * export const getAllContext = action({
204
+ * handler: async (ctx) => {
205
+ * return await getLLMContext(ctx);
206
+ * },
207
+ * });
208
+ *
209
+ * // Get context for specific services
210
+ * export const getSpecificContext = action({
211
+ * args: { services: v.array(v.string()) },
212
+ * handler: async (ctx, args) => {
213
+ * return await getLLMContext(ctx, args.services);
214
+ * },
215
+ * });
216
+ * ```
217
+ */
218
+ export async function getLLMContext(_ctx, serviceNames) {
219
+ const config = validateConfig();
220
+ // Normalize serviceNames to array or undefined
221
+ const names = serviceNames
222
+ ? Array.isArray(serviceNames)
223
+ ? serviceNames
224
+ : [serviceNames]
225
+ : undefined;
226
+ const url = buildLLMContextUrl(config.dinkUrl, names);
227
+ const response = await fetch(url, {
228
+ method: "GET",
229
+ headers: {
230
+ Accept: "text/plain",
231
+ Authorization: `Bearer ${config.appSyncKey}`,
232
+ },
233
+ });
234
+ if (response.status === 401) {
235
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.UNAUTHORIZED, "Invalid authorization token");
236
+ }
237
+ if (!response.ok) {
238
+ const errorText = await response.text().catch(() => "");
239
+ throw new IntrospectError(INTROSPECT_ERROR_CODES.SERVER_ERROR, `Server error: ${response.status} ${response.statusText} - ${errorText}`);
240
+ }
241
+ const text = await response.text();
242
+ return parseLLMContextResponse(text);
243
+ }
244
+ //# sourceMappingURL=introspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.js","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fatagnus/dink-convex",
3
- "version": "2.0.2",
3
+ "version": "2.7.0",
4
4
  "description": "Dink Convex sync component - bidirectional sync between Convex and edge devices",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -90,11 +90,7 @@
90
90
  "convex": "^1.17.0",
91
91
  "convex-helpers": "^0.1.0"
92
92
  },
93
- "peerDependenciesMeta": {
94
- "convex-helpers": {
95
- "optional": true
96
- }
97
- },
93
+
98
94
  "engines": {
99
95
  "node": ">=18.0.0"
100
96
  },