@intentius/chant-lexicon-temporal 0.1.6 → 0.1.8
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/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/package.json +1 -1
- package/src/codegen/docs.ts +1 -0
- package/src/composites/composites.test.ts +103 -1
- package/src/composites/watch-op.ts +101 -0
- package/src/describe-resources.test.ts +328 -0
- package/src/describe-resources.ts +300 -0
- package/src/index.ts +2 -0
- package/src/op/activities/index.ts +2 -2
- package/src/op/activities/state.ts +66 -0
- package/src/op/op-serializer.test.ts +231 -0
- package/src/op/serializer.ts +71 -9
- package/src/plugin.test.ts +2 -2
- package/src/plugin.ts +7 -0
package/src/op/serializer.ts
CHANGED
|
@@ -75,7 +75,7 @@ function generateWorkflow(config: OpConfig): string {
|
|
|
75
75
|
const lines: string[] = [
|
|
76
76
|
"// Generated by chant — do not edit directly.",
|
|
77
77
|
`// Source: ${config.name}.op.ts`,
|
|
78
|
-
"import { proxyActivities, condition, defineSignal, setHandler } from '@temporalio/workflow';",
|
|
78
|
+
"import { proxyActivities, condition, defineSignal, setHandler, upsertSearchAttributes } from '@temporalio/workflow';",
|
|
79
79
|
"import { TEMPORAL_ACTIVITY_PROFILES } from '@intentius/chant-lexicon-temporal';",
|
|
80
80
|
"import type * as activities from './activities';",
|
|
81
81
|
"",
|
|
@@ -107,29 +107,91 @@ function generateWorkflow(config: OpConfig): string {
|
|
|
107
107
|
// Workflow function
|
|
108
108
|
lines.push(`export async function ${fnName}(): Promise<void> {`);
|
|
109
109
|
|
|
110
|
+
// Initial search attributes — OpName plus any user-provided attrs.
|
|
111
|
+
// Each value is wrapped in a single-element array (classic
|
|
112
|
+
// upsertSearchAttributes API takes arrays).
|
|
113
|
+
const initialAttrs: Record<string, string[]> = {
|
|
114
|
+
OpName: [config.name],
|
|
115
|
+
};
|
|
116
|
+
for (const [k, v] of Object.entries(config.searchAttributes ?? {})) {
|
|
117
|
+
initialAttrs[k] = [v];
|
|
118
|
+
}
|
|
119
|
+
lines.push(` upsertSearchAttributes(${JSON.stringify(initialAttrs)});`);
|
|
120
|
+
lines.push("");
|
|
121
|
+
|
|
122
|
+
// Counter for outcome-attribute capture variables (workflow-scoped).
|
|
123
|
+
let resultCounter = 0;
|
|
124
|
+
const nextResultVar = (): string => `__r${resultCounter++}`;
|
|
125
|
+
|
|
126
|
+
// Build a `String(<var>?.<from-path>)` fragment from a dot-path.
|
|
127
|
+
const stringifyFromPath = (varName: string, from?: string): string => {
|
|
128
|
+
if (!from) return `String(${varName})`;
|
|
129
|
+
const parts = from.split(".");
|
|
130
|
+
return `String(${varName}?.${parts.join("?.")})`;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Emit `upsertSearchAttributes({ <name>: [<expr>] })` for an outcome attr.
|
|
134
|
+
const emitOutcomeUpsert = (
|
|
135
|
+
step: ActivityStep,
|
|
136
|
+
varName: string,
|
|
137
|
+
indent = " ",
|
|
138
|
+
): string | null => {
|
|
139
|
+
if (!step.outcomeAttribute) return null;
|
|
140
|
+
const { name, from } = step.outcomeAttribute;
|
|
141
|
+
return `${indent}upsertSearchAttributes({ ${JSON.stringify(name)}: [${stringifyFromPath(varName, from)}] });`;
|
|
142
|
+
};
|
|
143
|
+
|
|
110
144
|
const renderPhases = (phases: PhaseDefinition[]) => {
|
|
111
145
|
for (const phase of phases) {
|
|
112
146
|
const phaseLines: string[] = [];
|
|
113
147
|
phaseLines.push(` // Phase: ${phase.name}`);
|
|
148
|
+
phaseLines.push(` upsertSearchAttributes({ Phase: ${JSON.stringify([phase.name])} });`);
|
|
114
149
|
|
|
115
150
|
const activitySteps = phase.steps.filter(isActivityStep);
|
|
116
151
|
const gateSteps = phase.steps.filter(isGateStep);
|
|
117
152
|
|
|
118
153
|
if (phase.parallel && activitySteps.length > 1) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
phaseLines.push(`
|
|
154
|
+
// Capture results into an array if any step has an outcome attribute,
|
|
155
|
+
// otherwise just await Promise.all without the destructure.
|
|
156
|
+
const anyOutcome = activitySteps.some((s) => s.outcomeAttribute);
|
|
157
|
+
if (anyOutcome) {
|
|
158
|
+
const vars = activitySteps.map(() => nextResultVar());
|
|
159
|
+
phaseLines.push(` const [${vars.join(", ")}] = await Promise.all([`);
|
|
160
|
+
for (let i = 0; i < activitySteps.length; i++) {
|
|
161
|
+
const step = activitySteps[i];
|
|
162
|
+
const argsStr = step.args && Object.keys(step.args).length > 0
|
|
163
|
+
? JSON.stringify(step.args)
|
|
164
|
+
: "{}";
|
|
165
|
+
phaseLines.push(` ${step.fn}(${argsStr}),`);
|
|
166
|
+
}
|
|
167
|
+
phaseLines.push(" ]);");
|
|
168
|
+
for (let i = 0; i < activitySteps.length; i++) {
|
|
169
|
+
const upsert = emitOutcomeUpsert(activitySteps[i], vars[i]);
|
|
170
|
+
if (upsert) phaseLines.push(upsert);
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
phaseLines.push(" await Promise.all([");
|
|
174
|
+
for (const step of activitySteps) {
|
|
175
|
+
const argsStr = step.args && Object.keys(step.args).length > 0
|
|
176
|
+
? JSON.stringify(step.args)
|
|
177
|
+
: "{}";
|
|
178
|
+
phaseLines.push(` ${step.fn}(${argsStr}),`);
|
|
179
|
+
}
|
|
180
|
+
phaseLines.push(" ]);");
|
|
125
181
|
}
|
|
126
|
-
phaseLines.push(" ]);");
|
|
127
182
|
} else {
|
|
128
183
|
for (const step of activitySteps) {
|
|
129
184
|
const argsStr = step.args && Object.keys(step.args).length > 0
|
|
130
185
|
? JSON.stringify(step.args)
|
|
131
186
|
: "{}";
|
|
132
|
-
|
|
187
|
+
if (step.outcomeAttribute) {
|
|
188
|
+
const v = nextResultVar();
|
|
189
|
+
phaseLines.push(` const ${v} = await ${step.fn}(${argsStr});`);
|
|
190
|
+
const upsert = emitOutcomeUpsert(step, v);
|
|
191
|
+
if (upsert) phaseLines.push(upsert);
|
|
192
|
+
} else {
|
|
193
|
+
phaseLines.push(` await ${step.fn}(${argsStr});`);
|
|
194
|
+
}
|
|
133
195
|
}
|
|
134
196
|
}
|
|
135
197
|
|
package/src/plugin.test.ts
CHANGED
|
@@ -32,7 +32,7 @@ describe("temporal plugin", () => {
|
|
|
32
32
|
const tools = temporalPlugin.mcpTools?.();
|
|
33
33
|
expect(Array.isArray(tools)).toBe(true);
|
|
34
34
|
expect(tools?.length).toBe(1);
|
|
35
|
-
expect(tools?.[0].name).toBe("diff");
|
|
35
|
+
expect(tools?.[0].name).toBe("temporal:diff");
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
it("mcpResources() returns at least 2 resources including resource-catalog", () => {
|
|
@@ -40,7 +40,7 @@ describe("temporal plugin", () => {
|
|
|
40
40
|
expect(Array.isArray(resources)).toBe(true);
|
|
41
41
|
expect((resources?.length ?? 0)).toBeGreaterThanOrEqual(2);
|
|
42
42
|
const uris = resources?.map((r) => r.uri);
|
|
43
|
-
expect(uris).toContain("resource-catalog");
|
|
43
|
+
expect(uris).toContain("temporal:resource-catalog");
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it("skills() returns 2 skill entries", () => {
|
package/src/plugin.ts
CHANGED
|
@@ -103,6 +103,7 @@ export const temporalPlugin: LexiconPlugin = {
|
|
|
103
103
|
createDiffTool(
|
|
104
104
|
temporalSerializer,
|
|
105
105
|
"Compare current Temporal build output (docker-compose.yml, temporal-setup.sh, schedules/) against previous version",
|
|
106
|
+
"temporal",
|
|
106
107
|
),
|
|
107
108
|
];
|
|
108
109
|
},
|
|
@@ -114,6 +115,7 @@ export const temporalPlugin: LexiconPlugin = {
|
|
|
114
115
|
"Temporal Resource Types",
|
|
115
116
|
"All supported Temporal resource types: TemporalServer, TemporalNamespace, SearchAttribute, TemporalSchedule",
|
|
116
117
|
"lexicon-temporal.json",
|
|
118
|
+
"temporal",
|
|
117
119
|
),
|
|
118
120
|
{
|
|
119
121
|
uri: "examples/dev-server",
|
|
@@ -283,4 +285,9 @@ export const temporalPlugin: LexiconPlugin = {
|
|
|
283
285
|
const { generateDocs } = await import("./codegen/docs");
|
|
284
286
|
return generateDocs(options);
|
|
285
287
|
},
|
|
288
|
+
|
|
289
|
+
async describeResources(options) {
|
|
290
|
+
const { describeResources } = await import("./describe-resources");
|
|
291
|
+
return describeResources(options);
|
|
292
|
+
},
|
|
286
293
|
};
|