@keystrokehq/cli 0.0.1
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/AGENTS-blurb.md +123 -0
- package/LICENSE +42 -0
- package/README.md +177 -0
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/bin/keystroke.mjs +107 -0
- package/dist/_manifest-JSRE3H8k.mjs +385 -0
- package/dist/agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs +2344 -0
- package/dist/agent-manifest-CDnbkR2f.mjs +245 -0
- package/dist/agents-CZJGxVqV.mjs +228 -0
- package/dist/api-keys-D2lgguuY.mjs +40 -0
- package/dist/auth-DN2VusyU.mjs +59 -0
- package/dist/auth.handler-CT1BQUvu.mjs +340 -0
- package/dist/browser-qwFrUH82.mjs +24 -0
- package/dist/build-agents-BmM_AsSd-BGi9wtzt.mjs +514 -0
- package/dist/build-metadata-BWS7uhd_-DR8gJjTX.mjs +1422 -0
- package/dist/build-progress-DgYKb4hB.mjs +183 -0
- package/dist/build-tasks-CdihpudT-D5r5HUHe.mjs +91 -0
- package/dist/build-workflows-CfxBnIWh-CdYPv8w2.mjs +370 -0
- package/dist/build.handler-4799CjWH.mjs +36 -0
- package/dist/chunk-CH6r78ws.mjs +37 -0
- package/dist/clear-cache.handler-B9tqSoSM.mjs +11 -0
- package/dist/clear.handler-BTIXXPTJ.mjs +42 -0
- package/dist/clear.handler-BydlX-zE.mjs +11 -0
- package/dist/commander-DfTVqQ-3.mjs +133 -0
- package/dist/concurrency-gXn9Rw8x-DNl2YtrS.mjs +20 -0
- package/dist/connect-BUXkeH0F.mjs +43 -0
- package/dist/connect.handler-CYel9cy6.mjs +430 -0
- package/dist/constants-CPpPdSNg.mjs +8 -0
- package/dist/context-T7HZuB97.mjs +138 -0
- package/dist/credential-env-map-CI8yWHVy.mjs +28 -0
- package/dist/credential-schema-mismatch-BKo5PjcQ.mjs +76 -0
- package/dist/credentials-CvmjU0lK.mjs +171 -0
- package/dist/credentials-OfVHOtG3.mjs +151216 -0
- package/dist/current-deployment-workflow-poHt27i3.mjs +94 -0
- package/dist/current.handler-B8zKzfPp.mjs +21 -0
- package/dist/delete.handler-bAu1iXVQ.mjs +17 -0
- package/dist/deploy-7Jjls436.mjs +26 -0
- package/dist/deploy-BOPIpRWm.mjs +74 -0
- package/dist/deploy-progress-BmGUNFKg.mjs +70 -0
- package/dist/deploy.handler-BAzgiNhd.mjs +370 -0
- package/dist/detect-env-access-CwkOYeYM-D_BCZqV6.mjs +209 -0
- package/dist/diff-utils-NEfcjqxt.mjs +185 -0
- package/dist/diff.handler-Du7SY8K4.mjs +47 -0
- package/dist/dist-BkJUoBiG.mjs +1116 -0
- package/dist/dist-CUK7yBM0.mjs +308 -0
- package/dist/env-91KwMKov.mjs +140 -0
- package/dist/env.handler-BAzBuMzQ.mjs +277 -0
- package/dist/error-boundary-VL-JLfIa.mjs +34 -0
- package/dist/file-metadata-D1vm-XY2.mjs +191 -0
- package/dist/get-intrinsic-zLxwtrLK.mjs +658 -0
- package/dist/import-module-CV84H5fZ-B_CBCmb4.mjs +1747 -0
- package/dist/init-DpMCotSK.mjs +45 -0
- package/dist/init.handler-CPRnif52.mjs +585 -0
- package/dist/inspect.handler-DT_cD036.mjs +146 -0
- package/dist/integration-catalog-Bt-L3GjF.mjs +104 -0
- package/dist/integrations-DlatPK4W.mjs +79 -0
- package/dist/keystroke.d.mts +3 -0
- package/dist/keystroke.mjs +707 -0
- package/dist/layout-CbMtQ2tm.mjs +67 -0
- package/dist/list-enrichment-y-cwizLr.mjs +189 -0
- package/dist/list.handler-BTWvCyjA.mjs +52 -0
- package/dist/list.handler-CWF_Dj15.mjs +24 -0
- package/dist/list.handler-CZ6G2x_G.mjs +75 -0
- package/dist/list.handler-DWaQkJaR.mjs +51 -0
- package/dist/list.handler-DqbFcBW7.mjs +180 -0
- package/dist/list.handler-lq3ZGAn4.mjs +104 -0
- package/dist/logs-BEg9L5l8.mjs +28 -0
- package/dist/logs.handler-6hoMBzqw.mjs +35 -0
- package/dist/logs.handler-BD_dXiL1.mjs +231 -0
- package/dist/metadata-layout-GUYIUo0i-_aG2zjue.mjs +5877 -0
- package/dist/normalize-path-CojS-CgQ-DLCOvnD1.mjs +20 -0
- package/dist/options-CeaTcFxP.mjs +43 -0
- package/dist/org-xLzBtt2_.mjs +41 -0
- package/dist/output-DM4b7KgY.mjs +72 -0
- package/dist/oxc-B3KI3rf_-n9d1hKNq.mjs +119 -0
- package/dist/paused.handler-BMFm9Cff.mjs +94 -0
- package/dist/project-config-D1qsQlO7.mjs +107 -0
- package/dist/projects-CHkRE9rS.mjs +1574 -0
- package/dist/projects-Cjb7sovS.mjs +30 -0
- package/dist/read-credential-keys-77a91T8M-KA0Iw0Z1.mjs +9 -0
- package/dist/register.handler-BPCdor1_.mjs +86 -0
- package/dist/requirements.handler-DPXdSks3.mjs +201 -0
- package/dist/resolve-project-DDJ29sCF.mjs +35 -0
- package/dist/rolldown-runtime-twds-ZHy-BWWzu8VG.mjs +15 -0
- package/dist/run-polling-CAgFRdK3.mjs +20 -0
- package/dist/runs-D9hNLb9A.mjs +259 -0
- package/dist/schedule-BXx3uXwr.mjs +1142 -0
- package/dist/schema-17qMfNyI.mjs +18 -0
- package/dist/schema-display-CgmeKigW.mjs +130 -0
- package/dist/schemas-CDib1RhE.mjs +125 -0
- package/dist/skills-sync.handler-DIy8GR16.mjs +34 -0
- package/dist/skills.command-CrjI2dN9.mjs +35 -0
- package/dist/skills.handler-Bz8bJKql.mjs +9 -0
- package/dist/source-analysis-Cj-ADyu--BJQcFPCG.mjs +144 -0
- package/dist/spinner-progress-DMVwgqO9.mjs +173 -0
- package/dist/src-C0X6u_Mw.mjs +1340 -0
- package/dist/src-eHwu-Gfw.mjs +369 -0
- package/dist/status.handler-BO4nwvWn.mjs +101 -0
- package/dist/switch.handler-D_9213Vf.mjs +51 -0
- package/dist/sync-BL_Mo5st.mjs +39 -0
- package/dist/sync-keystroke-agent-skills-Kx_H7UTd.mjs +70 -0
- package/dist/sync.handler-BUFPdzWz.mjs +82 -0
- package/dist/task-B2sZMaZu.mjs +8 -0
- package/dist/task-target-build-CBeCKbu2.mjs +432 -0
- package/dist/task-target-deploy-C5X-USeR.mjs +4 -0
- package/dist/task-target-deploy-CA6elFpF-BEr4gkol.mjs +271 -0
- package/dist/task-target-deploy-runner.d.mts +3 -0
- package/dist/task-target-deploy-runner.mjs +202 -0
- package/dist/test-BHTgR3UA.mjs +698 -0
- package/dist/test.handler-BcPQ8b74.mjs +13 -0
- package/dist/trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs +239 -0
- package/dist/trigger-manifest-CY7brZeg.mjs +30 -0
- package/dist/try-deploy.handler-DqybNhXx.mjs +490 -0
- package/dist/upload-CkU--iDC.mjs +207 -0
- package/dist/upload.handler-DCtiznQp.mjs +441 -0
- package/dist/utils-CywxCDM7.mjs +14 -0
- package/dist/validate.handler-DOcTaJL0.mjs +280 -0
- package/dist/workflow-build-DBQaBfnn.mjs +1819 -0
- package/dist/workflow-bundler-BPiqVscj-X1PFFAuP.mjs +167 -0
- package/dist/workflows-g9z87AJJ.mjs +799 -0
- package/dist/writer-BG8poUm3-BbXlU2kI.mjs +426 -0
- package/package.json +87 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region ../../packages/shared-types/src/credentials/models/schema.ts
|
|
5
|
+
const CredentialScopeValues = [
|
|
6
|
+
"organization",
|
|
7
|
+
"user",
|
|
8
|
+
"project"
|
|
9
|
+
];
|
|
10
|
+
const CredentialScopeSchema = z.enum(CredentialScopeValues);
|
|
11
|
+
const ConnectionStatusSchema = z.enum([
|
|
12
|
+
"connected",
|
|
13
|
+
"broken",
|
|
14
|
+
"needs_reconnect",
|
|
15
|
+
"disconnected"
|
|
16
|
+
]);
|
|
17
|
+
//#endregion
|
|
18
|
+
export { CredentialScopeSchema as n, CredentialScopeValues as r, ConnectionStatusSchema as t };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
//#region src/lib/schema-display.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns true when the schema is the fallback "unknown" sentinel emitted
|
|
6
|
+
* by zodSchemaToJsonSchema when a schema cannot be converted.
|
|
7
|
+
*/
|
|
8
|
+
function isUnknownSchema(schema) {
|
|
9
|
+
return schema != null && schema.type === "unknown";
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generates a minimal placeholder JSON object for a given JSON Schema.
|
|
13
|
+
* Walks `properties` recursively to produce sensible default values so the
|
|
14
|
+
* user has a copy-pasteable `--input` example.
|
|
15
|
+
*
|
|
16
|
+
* Examples:
|
|
17
|
+
* { type: "number" } => 0
|
|
18
|
+
* { type: "string" } => ""
|
|
19
|
+
* { type: "boolean" } => false
|
|
20
|
+
* { type: "array" } => []
|
|
21
|
+
* { type: "object", properties: { x: { type: "number" } } } => { x: 0 }
|
|
22
|
+
* { enum: ["a", "b"] } => "a"
|
|
23
|
+
*/
|
|
24
|
+
function generateExampleJson(schema) {
|
|
25
|
+
if (schema == null || typeof schema !== "object") return null;
|
|
26
|
+
return generateValue(schema);
|
|
27
|
+
}
|
|
28
|
+
function generateValue(schema) {
|
|
29
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
|
|
30
|
+
switch (Array.isArray(schema.type) ? schema.type[0] : schema.type) {
|
|
31
|
+
case "object": {
|
|
32
|
+
if (!schema.properties) return {};
|
|
33
|
+
const result = {};
|
|
34
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) result[key] = generateValue(propSchema);
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
case "array": return [];
|
|
38
|
+
case "string": return "";
|
|
39
|
+
case "number":
|
|
40
|
+
case "integer": return 0;
|
|
41
|
+
case "boolean": return false;
|
|
42
|
+
case "null": return null;
|
|
43
|
+
default: return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validates input against a JSON Schema by checking required fields.
|
|
48
|
+
* This is a lightweight structural check that works without `z.fromJSONSchema`.
|
|
49
|
+
* Only checks top-level required fields — sufficient for the "did you forget
|
|
50
|
+
* to provide input?" use case.
|
|
51
|
+
*/
|
|
52
|
+
function validateRequiredFields(input, schema) {
|
|
53
|
+
if (schema == null || typeof schema !== "object") return {
|
|
54
|
+
valid: true,
|
|
55
|
+
missingRequired: []
|
|
56
|
+
};
|
|
57
|
+
const missingRequired = (Array.isArray(schema.required) ? schema.required : []).filter((field) => !(field in input));
|
|
58
|
+
return {
|
|
59
|
+
valid: missingRequired.length === 0,
|
|
60
|
+
missingRequired
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns a short human-readable type hint from a JSON Schema field definition.
|
|
65
|
+
* e.g. { type: "number" } → "number"
|
|
66
|
+
* { type: "string", enum: ["a","b"] } → "string: a | b"
|
|
67
|
+
* { type: ["string", "null"] } → "string | null"
|
|
68
|
+
* { $ref: "..." } → "object"
|
|
69
|
+
*/
|
|
70
|
+
function resolveTypeHint(fieldSchema) {
|
|
71
|
+
if (!fieldSchema) return "any";
|
|
72
|
+
if (Array.isArray(fieldSchema.enum) && fieldSchema.enum.length > 0) return `${typeof fieldSchema.type === "string" ? `${fieldSchema.type}: ` : ""}${fieldSchema.enum.map(String).join(" | ")}`;
|
|
73
|
+
if (Array.isArray(fieldSchema.type)) return fieldSchema.type.join(" | ");
|
|
74
|
+
if (typeof fieldSchema.type === "string" && fieldSchema.type !== "unknown") return fieldSchema.type;
|
|
75
|
+
if (fieldSchema.$ref) return "object";
|
|
76
|
+
return "any";
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Formats a missing-required-fields error into a descriptive CLI message.
|
|
80
|
+
*/
|
|
81
|
+
function formatMissingInputError(workflowName, missingFields, inputSchema) {
|
|
82
|
+
const lines = [];
|
|
83
|
+
lines.push(`Missing required input for workflow "${workflowName}"\n`);
|
|
84
|
+
if (inputSchema == null || typeof inputSchema !== "object") {
|
|
85
|
+
lines.push(" (input schema unavailable)\n");
|
|
86
|
+
lines.push(` $ keystroke workflows try-deploy "${workflowName}" --input '{}'`);
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
}
|
|
89
|
+
const properties = inputSchema.properties && typeof inputSchema.properties === "object" ? inputSchema.properties : {};
|
|
90
|
+
for (const field of missingFields) {
|
|
91
|
+
const fieldSchema = properties[field];
|
|
92
|
+
const typeHint = resolveTypeHint(fieldSchema);
|
|
93
|
+
lines.push(` ${field} (${typeHint}): Required`);
|
|
94
|
+
}
|
|
95
|
+
lines.push("");
|
|
96
|
+
const exampleValue = generateExampleJson(inputSchema);
|
|
97
|
+
const exampleJson = JSON.stringify(exampleValue);
|
|
98
|
+
lines.push("Expected input:");
|
|
99
|
+
lines.push(` $ keystroke workflows try-deploy "${workflowName}" --input '${exampleJson}'`);
|
|
100
|
+
return lines.join("\n");
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Formats validation issues into a descriptive CLI message.
|
|
104
|
+
*
|
|
105
|
+
* Example output:
|
|
106
|
+
*
|
|
107
|
+
* Invalid input for workflow "Addition"
|
|
108
|
+
*
|
|
109
|
+
* num: Required
|
|
110
|
+
* num2: Required
|
|
111
|
+
*
|
|
112
|
+
* Expected input:
|
|
113
|
+
* $ keystroke workflows try-deploy "Addition" --input '{"num":0,"num2":0}'
|
|
114
|
+
*/
|
|
115
|
+
function formatValidationError(workflowName, issues, inputSchema) {
|
|
116
|
+
const lines = [];
|
|
117
|
+
lines.push(`Invalid input for workflow "${workflowName}"\n`);
|
|
118
|
+
for (const issue of issues) {
|
|
119
|
+
const fieldPath = issue.path.length === 0 || issue.path.length === 1 && issue.path[0] === "" ? "(root)" : issue.path.join(".");
|
|
120
|
+
lines.push(` ${fieldPath}: ${issue.message}`);
|
|
121
|
+
}
|
|
122
|
+
lines.push("");
|
|
123
|
+
const exampleValue = inputSchema != null && typeof inputSchema === "object" ? generateExampleJson(inputSchema) : null;
|
|
124
|
+
const exampleJson = JSON.stringify(exampleValue);
|
|
125
|
+
lines.push(`Expected input:`);
|
|
126
|
+
lines.push(` $ keystroke workflows try-deploy "${workflowName}" --input '${exampleJson}'`);
|
|
127
|
+
return lines.join("\n");
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
export { validateRequiredFields as a, resolveTypeHint as i, formatValidationError as n, isUnknownSchema as r, formatMissingInputError as t };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { A as idNoSpacesString, C as CredentialSetManifestSchema, I as trimmedNonEmptyString, L as trimmedNonEmptyStringUnbounded, N as optionalDescriptionString, O as createStructuralSchema, V as SHA256HashSchema, f as TriggerTypeSchema, j as jsonSchemaObject, k as descriptionString, s as ExecutionIdentityPolicySchema, t as DurationSchema } from "./schedule-BXx3uXwr.mjs";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region ../../packages/workflow-core/src/trigger/schemas.ts
|
|
6
|
+
const credentialSetInstanceSchema = createStructuralSchema([
|
|
7
|
+
"id",
|
|
8
|
+
"auth",
|
|
9
|
+
"needsResolve"
|
|
10
|
+
], "a CredentialSet instance");
|
|
11
|
+
const TriggerModeDefaultSchema = z.enum(["managed", "subscribable"]);
|
|
12
|
+
const TriggerCallbackPresenceSchema = z.object({
|
|
13
|
+
filter: z.boolean(),
|
|
14
|
+
idempotencyKey: z.boolean(),
|
|
15
|
+
poll: z.boolean().optional(),
|
|
16
|
+
transformAllowed: z.boolean(),
|
|
17
|
+
verify: z.boolean().optional()
|
|
18
|
+
});
|
|
19
|
+
const TriggerRuntimeDescriptorSchema = z.object({ callbacks: TriggerCallbackPresenceSchema });
|
|
20
|
+
const TriggerManifestSchema = z.object({
|
|
21
|
+
manifestVersion: z.literal(1),
|
|
22
|
+
type: z.literal("trigger"),
|
|
23
|
+
triggerType: TriggerTypeSchema,
|
|
24
|
+
name: trimmedNonEmptyString("Trigger name"),
|
|
25
|
+
description: descriptionString("Trigger description"),
|
|
26
|
+
enabled: z.boolean(),
|
|
27
|
+
modeDefault: TriggerModeDefaultSchema,
|
|
28
|
+
executionIdentityPolicy: ExecutionIdentityPolicySchema.optional(),
|
|
29
|
+
credentialSets: z.array(CredentialSetManifestSchema).optional(),
|
|
30
|
+
runtime: TriggerRuntimeDescriptorSchema
|
|
31
|
+
});
|
|
32
|
+
const triggerBaseConfigSchema = z.object({
|
|
33
|
+
credentialSets: z.array(credentialSetInstanceSchema).optional(),
|
|
34
|
+
description: descriptionString("Trigger description"),
|
|
35
|
+
enabled: z.boolean().default(true),
|
|
36
|
+
executionIdentityPolicy: ExecutionIdentityPolicySchema.optional(),
|
|
37
|
+
modeDefault: TriggerModeDefaultSchema.default("managed"),
|
|
38
|
+
name: trimmedNonEmptyString("Trigger name")
|
|
39
|
+
});
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region ../../packages/workflow-core/src/task/schemas.ts
|
|
42
|
+
const agentInstanceSchema = createStructuralSchema([
|
|
43
|
+
"id",
|
|
44
|
+
"name",
|
|
45
|
+
"systemPrompt",
|
|
46
|
+
"model",
|
|
47
|
+
"input",
|
|
48
|
+
"output",
|
|
49
|
+
"workflowSafeReference"
|
|
50
|
+
], "an Agent instance");
|
|
51
|
+
const triggerInstanceSchema = createStructuralSchema([
|
|
52
|
+
"isTrigger",
|
|
53
|
+
"name",
|
|
54
|
+
"description",
|
|
55
|
+
"enabled"
|
|
56
|
+
], "a trigger instance (use cronTrigger(), pollingTrigger(), or webhookTrigger())");
|
|
57
|
+
const taskLifecycleSchema = z.object({
|
|
58
|
+
maxExecutions: z.number().int().positive().optional(),
|
|
59
|
+
expiresAt: z.union([z.date(), z.string().datetime()]).optional(),
|
|
60
|
+
expiresAfter: DurationSchema.optional()
|
|
61
|
+
}).strict();
|
|
62
|
+
z.object({
|
|
63
|
+
id: idNoSpacesString("Task ID"),
|
|
64
|
+
name: trimmedNonEmptyString("Task name"),
|
|
65
|
+
description: optionalDescriptionString("Task description"),
|
|
66
|
+
agent: agentInstanceSchema,
|
|
67
|
+
prompt: trimmedNonEmptyStringUnbounded("Task prompt"),
|
|
68
|
+
triggers: z.array(triggerInstanceSchema).min(1, { message: "At least one trigger is required" }),
|
|
69
|
+
lifecycle: taskLifecycleSchema.optional(),
|
|
70
|
+
tags: z.array(z.string()).optional()
|
|
71
|
+
}).strict();
|
|
72
|
+
const WorkflowSafeAgentReferenceSchema = z.object({
|
|
73
|
+
kind: z.literal("agent"),
|
|
74
|
+
authoredAgentId: z.string(),
|
|
75
|
+
displayName: z.string(),
|
|
76
|
+
runtimeKind: z.enum(["declarative", "runnable"]),
|
|
77
|
+
inputSchema: jsonSchemaObject.optional(),
|
|
78
|
+
outputSchema: jsonSchemaObject.optional(),
|
|
79
|
+
authoredExport: z.object({
|
|
80
|
+
exportName: z.string().optional(),
|
|
81
|
+
filePath: z.string().optional()
|
|
82
|
+
}).optional(),
|
|
83
|
+
metadata: jsonSchemaObject.optional()
|
|
84
|
+
}).strict();
|
|
85
|
+
const TaskBuildInfoStubSchema = z.object({
|
|
86
|
+
hash: SHA256HashSchema.optional(),
|
|
87
|
+
size: z.number().optional(),
|
|
88
|
+
metadata: jsonSchemaObject.optional()
|
|
89
|
+
}).strict();
|
|
90
|
+
/**
|
|
91
|
+
* Extended trigger manifest schema for tasks.
|
|
92
|
+
* Preserves runtime fields (schedule, timezone, path, method) that the base
|
|
93
|
+
* TriggerManifestSchema strips. Tasks need these for trigger evaluation at runtime.
|
|
94
|
+
*/
|
|
95
|
+
const TaskTriggerManifestSchema = TriggerManifestSchema.extend({
|
|
96
|
+
runtime: TriggerRuntimeDescriptorSchema.extend({
|
|
97
|
+
schedule: z.string().optional(),
|
|
98
|
+
timezone: z.string().optional(),
|
|
99
|
+
path: z.string().optional(),
|
|
100
|
+
method: z.string().optional(),
|
|
101
|
+
input: z.unknown().optional(),
|
|
102
|
+
payloadMode: z.string().optional()
|
|
103
|
+
}),
|
|
104
|
+
/** Static payload for cron triggers */
|
|
105
|
+
payload: z.unknown().optional()
|
|
106
|
+
});
|
|
107
|
+
const TaskBuildManifestSchema = z.object({
|
|
108
|
+
manifestVersion: z.literal(1),
|
|
109
|
+
type: z.literal("task"),
|
|
110
|
+
id: z.string().min(1),
|
|
111
|
+
name: z.string().min(1),
|
|
112
|
+
description: z.string().optional(),
|
|
113
|
+
agentRef: WorkflowSafeAgentReferenceSchema,
|
|
114
|
+
prompt: z.string().min(1),
|
|
115
|
+
triggers: z.array(TaskTriggerManifestSchema),
|
|
116
|
+
lifecycle: z.object({
|
|
117
|
+
maxExecutions: z.number().int().positive().optional(),
|
|
118
|
+
expiresAt: z.string().optional(),
|
|
119
|
+
expiresAfter: z.string().optional()
|
|
120
|
+
}).strict().optional(),
|
|
121
|
+
tags: z.array(z.string()).optional(),
|
|
122
|
+
buildInfo: TaskBuildInfoStubSchema
|
|
123
|
+
}).strict();
|
|
124
|
+
//#endregion
|
|
125
|
+
export { TriggerRuntimeDescriptorSchema as n, triggerBaseConfigSchema as r, TaskBuildManifestSchema as t };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { C as CliExitError, t as ui } from "./keystroke.mjs";
|
|
4
|
+
import { i as writeJson, r as isJsonMode } from "./output-DM4b7KgY.mjs";
|
|
5
|
+
import { t as syncKeystrokeAgentSkills } from "./sync-keystroke-agent-skills-Kx_H7UTd.mjs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
//#region src/commands/skills/skills-sync.handler.ts
|
|
8
|
+
async function handleSkillsSync(options, _ctx) {
|
|
9
|
+
const result = await syncKeystrokeAgentSkills(path.resolve(options.path ?? process.cwd()));
|
|
10
|
+
if (isJsonMode(options)) {
|
|
11
|
+
if (result.ok) writeJson({
|
|
12
|
+
ok: true,
|
|
13
|
+
copied: result.copied
|
|
14
|
+
});
|
|
15
|
+
else if (result.reason === "not_installed") writeJson({
|
|
16
|
+
ok: false,
|
|
17
|
+
reason: "not_installed"
|
|
18
|
+
});
|
|
19
|
+
else writeJson({
|
|
20
|
+
ok: false,
|
|
21
|
+
reason: "no_skills_found",
|
|
22
|
+
packageRoot: result.packageRoot
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (result.ok) {
|
|
27
|
+
ui.success(`Synced ${result.copied.length} skill(s) to .cursor/skills and .claude/skills: ${result.copied.join(", ")}`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (result.reason === "not_installed") throw new CliExitError("Could not resolve @keystroke/skills. Add it to devDependencies, run install, then run `keystroke skills sync`.", { exitCode: 1 });
|
|
31
|
+
ui.warn(`@keystroke/skills is installed at ${result.packageRoot} but no skill directories with SKILL.md were found.`);
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { handleSkillsSync };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-DM4b7KgY.mjs";
|
|
4
|
+
import { t as createTypedCommand } from "./commander-DfTVqQ-3.mjs";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
//#region src/commands/skills/skills.command.ts
|
|
7
|
+
const SkillsCommandOptionsSchema = JsonOptionSchema.extend({ path: z.string().optional().describe("Project root (default: current directory)") });
|
|
8
|
+
const SKILLS_OPTIONS_CONFIG = {
|
|
9
|
+
...JSON_OPTION_CONFIG,
|
|
10
|
+
path: {
|
|
11
|
+
flag: "--path <dir>",
|
|
12
|
+
description: "Project root (directory containing package.json; default: cwd)"
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
function createSkillsCommand() {
|
|
16
|
+
const cmd = createTypedCommand({
|
|
17
|
+
name: "skills",
|
|
18
|
+
description: "Sync Keystroke agent skills (SKILL.md) from @keystroke/skills",
|
|
19
|
+
schema: SkillsCommandOptionsSchema,
|
|
20
|
+
optionsConfig: SKILLS_OPTIONS_CONFIG,
|
|
21
|
+
loadHandler: async () => (await import("./skills.handler-Bz8bJKql.mjs")).handleSkillsParent,
|
|
22
|
+
subcommands: [createTypedCommand({
|
|
23
|
+
name: "sync",
|
|
24
|
+
description: "Copy installed @keystroke/skills into .cursor/skills and .claude/skills",
|
|
25
|
+
schema: SkillsCommandOptionsSchema,
|
|
26
|
+
optionsConfig: SKILLS_OPTIONS_CONFIG,
|
|
27
|
+
loadHandler: async () => (await import("./skills-sync.handler-DIy8GR16.mjs")).handleSkillsSync
|
|
28
|
+
})]
|
|
29
|
+
});
|
|
30
|
+
cmd.enablePositionalOptions();
|
|
31
|
+
cmd.passThroughOptions();
|
|
32
|
+
return cmd;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createSkillsCommand };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { t as ui } from "./keystroke.mjs";
|
|
4
|
+
//#region src/commands/skills/skills.handler.ts
|
|
5
|
+
async function handleSkillsParent(_options, _ctx) {
|
|
6
|
+
ui.hint("Run `keystroke skills sync` to copy @keystroke/skills into .cursor/skills and .claude/skills.");
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { handleSkillsParent };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { d as getMetadataRoot } from "./layout-CbMtQ2tm.mjs";
|
|
4
|
+
import { t as BASE_IGNORE_PATTERNS } from "./metadata-layout-GUYIUo0i-_aG2zjue.mjs";
|
|
5
|
+
import { a as literalString, l as unwrapExpression, n as identifierName, r as isNode } from "./oxc-B3KI3rf_-n9d1hKNq.mjs";
|
|
6
|
+
import { readFile, readdir, rm } from "node:fs/promises";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
//#region ../../packages/workflow-builder/dist/source-analysis-Cj-ADyu-.mjs
|
|
9
|
+
async function removeAllMetadataArtifacts(outputDir) {
|
|
10
|
+
await rm(getMetadataRoot(outputDir), {
|
|
11
|
+
recursive: true,
|
|
12
|
+
force: true
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
async function removeMetadataArtifacts(outputDir, outputFiles) {
|
|
16
|
+
for (const outputFile of new Set(outputFiles)) await rm(path.join(outputDir, outputFile), { force: true });
|
|
17
|
+
await removeEmptyMetadataDirectories(getMetadataRoot(outputDir));
|
|
18
|
+
}
|
|
19
|
+
async function removeEmptyMetadataDirectories(directoryPath) {
|
|
20
|
+
try {
|
|
21
|
+
const entries = await readdir(directoryPath, { withFileTypes: true });
|
|
22
|
+
for (const entry of entries) {
|
|
23
|
+
if (!entry.isDirectory()) continue;
|
|
24
|
+
await removeEmptyMetadataDirectories(path.join(directoryPath, entry.name));
|
|
25
|
+
}
|
|
26
|
+
if ((await readdir(directoryPath, { withFileTypes: true })).length === 0) {
|
|
27
|
+
await rm(directoryPath, {
|
|
28
|
+
recursive: true,
|
|
29
|
+
force: true
|
|
30
|
+
});
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const DISCOVERY_GLOB = [
|
|
39
|
+
"**/*.ts",
|
|
40
|
+
"**/*.tsx",
|
|
41
|
+
"**/*.mts"
|
|
42
|
+
];
|
|
43
|
+
const DISCOVERY_IGNORE = [...BASE_IGNORE_PATTERNS, "**/dist/**"];
|
|
44
|
+
const WORKFLOW_IMPORT_SOURCES = ["@keystroke/workflow-core"];
|
|
45
|
+
const AGENT_FACTORY_IMPORT_SOURCES = ["@keystroke/integration-ai"];
|
|
46
|
+
const AGENT_FACTORY_NAMES = ["agent"];
|
|
47
|
+
function getLocalModuleSpecifier(moduleSpecifier) {
|
|
48
|
+
if (!moduleSpecifier) return null;
|
|
49
|
+
return moduleSpecifier.startsWith(".") ? moduleSpecifier : null;
|
|
50
|
+
}
|
|
51
|
+
async function resolveLocalModulePath(fromFilePath, specifier) {
|
|
52
|
+
const basePath = path.resolve(path.dirname(fromFilePath), specifier);
|
|
53
|
+
const candidates = [
|
|
54
|
+
basePath,
|
|
55
|
+
`${basePath}.ts`,
|
|
56
|
+
`${basePath}.tsx`,
|
|
57
|
+
`${basePath}.mts`,
|
|
58
|
+
path.join(basePath, "index.ts"),
|
|
59
|
+
path.join(basePath, "index.tsx"),
|
|
60
|
+
path.join(basePath, "index.mts")
|
|
61
|
+
];
|
|
62
|
+
for (const candidate of candidates) try {
|
|
63
|
+
await readFile(candidate, "utf-8");
|
|
64
|
+
return candidate;
|
|
65
|
+
} catch {}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
function collectWorkflowImportNames(sourceFile) {
|
|
69
|
+
const names = new Map([
|
|
70
|
+
["Workflow", "workflow"],
|
|
71
|
+
["Agent", "agent"],
|
|
72
|
+
["Task", "task"]
|
|
73
|
+
]);
|
|
74
|
+
for (const statement of sourceFile.statements) {
|
|
75
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
76
|
+
const moduleSpecifier = literalString(statement.source);
|
|
77
|
+
if (!moduleSpecifier || !Array.isArray(statement.specifiers)) continue;
|
|
78
|
+
if (WORKFLOW_IMPORT_SOURCES.includes(moduleSpecifier)) for (const specifier of statement.specifiers) {
|
|
79
|
+
if (!isNode(specifier) || specifier.type !== "ImportSpecifier") continue;
|
|
80
|
+
const importedName = identifierName(specifier.imported);
|
|
81
|
+
const localName = identifierName(specifier.local);
|
|
82
|
+
if (!importedName || !localName) continue;
|
|
83
|
+
if (importedName === "Workflow") names.set(localName, "workflow");
|
|
84
|
+
else if (importedName === "Agent") names.set(localName, "agent");
|
|
85
|
+
else if (importedName === "Task") names.set(localName, "task");
|
|
86
|
+
}
|
|
87
|
+
if (AGENT_FACTORY_IMPORT_SOURCES.includes(moduleSpecifier)) for (const specifier of statement.specifiers) {
|
|
88
|
+
if (!isNode(specifier) || specifier.type !== "ImportSpecifier") continue;
|
|
89
|
+
const importedName = identifierName(specifier.imported);
|
|
90
|
+
const localName = identifierName(specifier.local);
|
|
91
|
+
if (!importedName || !localName) continue;
|
|
92
|
+
if (AGENT_FACTORY_NAMES.includes(importedName)) names.set(localName, "agent");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return names;
|
|
96
|
+
}
|
|
97
|
+
function collectLocalWorkflowBindings(sourceFile, workflowImportNames) {
|
|
98
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
99
|
+
for (const statement of sourceFile.statements) for (const declaration of getVariableDeclarators(statement)) {
|
|
100
|
+
const bindingName = identifierName(declaration.id);
|
|
101
|
+
if (!bindingName || !isNode(declaration.init)) continue;
|
|
102
|
+
const exportKind = classifyDiscoverableExpression(declaration.init, workflowImportNames);
|
|
103
|
+
if (exportKind) bindings.set(bindingName, exportKind);
|
|
104
|
+
}
|
|
105
|
+
return bindings;
|
|
106
|
+
}
|
|
107
|
+
function resolveDefaultExportAssignment(expression, filePath, localWorkflowBindings, workflowImportNames) {
|
|
108
|
+
const exportKind = classifyDiscoverableExpression(expression, workflowImportNames);
|
|
109
|
+
if (exportKind) return {
|
|
110
|
+
resolvedFilePath: filePath,
|
|
111
|
+
localExportName: "default",
|
|
112
|
+
exportKind
|
|
113
|
+
};
|
|
114
|
+
const bindingName = identifierName(expression);
|
|
115
|
+
const bindingKind = bindingName ? localWorkflowBindings.get(bindingName) : void 0;
|
|
116
|
+
if (bindingKind) return {
|
|
117
|
+
resolvedFilePath: filePath,
|
|
118
|
+
localExportName: "default",
|
|
119
|
+
exportKind: bindingKind
|
|
120
|
+
};
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
function isExportedVariableStatement(statement) {
|
|
124
|
+
return statement.type === "ExportNamedDeclaration" && isNode(statement.declaration) && statement.declaration.type === "VariableDeclaration";
|
|
125
|
+
}
|
|
126
|
+
function classifyDiscoverableExpression(expression, workflowImportNames) {
|
|
127
|
+
const unwrapped = unwrapExpression(expression);
|
|
128
|
+
if (unwrapped.type === "NewExpression") {
|
|
129
|
+
const callee = identifierName(unwrapped.callee);
|
|
130
|
+
return callee ? workflowImportNames.get(callee) ?? null : null;
|
|
131
|
+
}
|
|
132
|
+
if (unwrapped.type === "CallExpression") {
|
|
133
|
+
const callee = identifierName(unwrapped.callee);
|
|
134
|
+
return callee ? workflowImportNames.get(callee) ?? null : null;
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
function getVariableDeclarators(statement) {
|
|
139
|
+
const declaration = statement.type === "VariableDeclaration" ? statement : statement.type === "ExportNamedDeclaration" && isNode(statement.declaration) ? statement.declaration : null;
|
|
140
|
+
if (!declaration || declaration.type !== "VariableDeclaration") return [];
|
|
141
|
+
return Array.isArray(declaration.declarations) ? declaration.declarations.filter((node) => isNode(node)) : [];
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
export { getLocalModuleSpecifier as a, removeAllMetadataArtifacts as c, resolveDefaultExportAssignment as d, resolveLocalModulePath as f, collectWorkflowImportNames as i, removeEmptyMetadataDirectories as l, DISCOVERY_IGNORE as n, getVariableDeclarators as o, collectLocalWorkflowBindings as r, isExportedVariableStatement as s, DISCOVERY_GLOB as t, removeMetadataArtifacts as u };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { a as originalConsole, c as isTTY, i as logger, o as ANSI, s as style } from "./keystroke.mjs";
|
|
4
|
+
import { writeSync } from "node:fs";
|
|
5
|
+
import { Worker } from "node:worker_threads";
|
|
6
|
+
//#region src/lib/spinner-progress.ts
|
|
7
|
+
/** Match `spinner-worker` (stdout) so `stopAll` clears the same stream as the worker. */
|
|
8
|
+
const SPINNER_OUTPUT_FD = 1;
|
|
9
|
+
const DEFAULT_PHASE_ID = "__default__";
|
|
10
|
+
function formatProgressDuration(ms) {
|
|
11
|
+
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
12
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
13
|
+
}
|
|
14
|
+
function printCompletedLine(label, elapsed) {
|
|
15
|
+
const check = style("✓", `${ANSI.bold}${ANSI.green}`);
|
|
16
|
+
if (elapsed) {
|
|
17
|
+
const timeStr = style(elapsed, ANSI.dim);
|
|
18
|
+
originalConsole.info(` ${check} ${label} ${timeStr}`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
originalConsole.info(` ${check} ${label}`);
|
|
22
|
+
}
|
|
23
|
+
function printFailedLine(label, elapsed) {
|
|
24
|
+
const cross = style("✗", `${ANSI.bold}${ANSI.red}`);
|
|
25
|
+
if (elapsed) {
|
|
26
|
+
const timeStr = style(elapsed, ANSI.dim);
|
|
27
|
+
originalConsole.info(` ${cross} ${label} ${timeStr}`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
originalConsole.info(` ${cross} ${label}`);
|
|
31
|
+
}
|
|
32
|
+
function printSkippedLine(label) {
|
|
33
|
+
const dash = style("-", ANSI.dim);
|
|
34
|
+
originalConsole.info(` ${dash} ${label}`);
|
|
35
|
+
}
|
|
36
|
+
function createWorker() {
|
|
37
|
+
if (!isTTY()) return null;
|
|
38
|
+
try {
|
|
39
|
+
return new Worker(new URL("./spinner-worker.ts", import.meta.url));
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function createSpinnerProgress(logPrefix, options = {}) {
|
|
45
|
+
const worker = createWorker();
|
|
46
|
+
const phaseStartTimes = /* @__PURE__ */ new Map();
|
|
47
|
+
const visiblePhaseIds = /* @__PURE__ */ new Set();
|
|
48
|
+
const showElapsed = options.showElapsed ?? true;
|
|
49
|
+
let defaultLabel = "";
|
|
50
|
+
function addPendingPhase(id, label) {
|
|
51
|
+
visiblePhaseIds.add(id);
|
|
52
|
+
worker?.postMessage({
|
|
53
|
+
type: "addPendingPhase",
|
|
54
|
+
id,
|
|
55
|
+
label,
|
|
56
|
+
showElapsed
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function startPhase(id, label) {
|
|
60
|
+
visiblePhaseIds.add(id);
|
|
61
|
+
phaseStartTimes.set(id, Date.now());
|
|
62
|
+
logger.info(`${logPrefix} → [${id}] ${label}`);
|
|
63
|
+
worker?.postMessage({
|
|
64
|
+
type: "addPhase",
|
|
65
|
+
id,
|
|
66
|
+
label,
|
|
67
|
+
showElapsed
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function updatePhase(id, label) {
|
|
71
|
+
worker?.postMessage({
|
|
72
|
+
type: "updateLabel",
|
|
73
|
+
id,
|
|
74
|
+
label
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function completePhase(id, label, elapsedMs) {
|
|
78
|
+
const phaseStart = phaseStartTimes.get(id);
|
|
79
|
+
const elapsed = formatProgressDuration(elapsedMs ?? (phaseStart ? Date.now() - phaseStart : 0));
|
|
80
|
+
phaseStartTimes.delete(id);
|
|
81
|
+
visiblePhaseIds.delete(id);
|
|
82
|
+
logger.info(`${logPrefix} ✓ [${id}] ${label} ${elapsed}`);
|
|
83
|
+
if (worker) worker.postMessage({
|
|
84
|
+
type: "completePhase",
|
|
85
|
+
id,
|
|
86
|
+
label,
|
|
87
|
+
elapsed,
|
|
88
|
+
showElapsed
|
|
89
|
+
});
|
|
90
|
+
else printCompletedLine(label, showElapsed ? elapsed : void 0);
|
|
91
|
+
}
|
|
92
|
+
function failPhase(id, label, elapsedMs, error) {
|
|
93
|
+
const phaseStart = phaseStartTimes.get(id);
|
|
94
|
+
const elapsed = formatProgressDuration(elapsedMs ?? (phaseStart ? Date.now() - phaseStart : 0));
|
|
95
|
+
phaseStartTimes.delete(id);
|
|
96
|
+
visiblePhaseIds.delete(id);
|
|
97
|
+
const msg = error ? `${label}: ${error}` : label;
|
|
98
|
+
logger.info(`${logPrefix} ✗ [${id}] ${msg} ${elapsed}`);
|
|
99
|
+
if (worker) worker.postMessage({
|
|
100
|
+
type: "failPhase",
|
|
101
|
+
id,
|
|
102
|
+
label: msg,
|
|
103
|
+
elapsed,
|
|
104
|
+
showElapsed
|
|
105
|
+
});
|
|
106
|
+
else printFailedLine(msg, showElapsed ? elapsed : void 0);
|
|
107
|
+
}
|
|
108
|
+
function skipPhase(id, label) {
|
|
109
|
+
phaseStartTimes.delete(id);
|
|
110
|
+
visiblePhaseIds.delete(id);
|
|
111
|
+
logger.info(`${logPrefix} - [${id}] ${label}`);
|
|
112
|
+
if (worker) worker.postMessage({
|
|
113
|
+
type: "skipPhase",
|
|
114
|
+
id,
|
|
115
|
+
label
|
|
116
|
+
});
|
|
117
|
+
else printSkippedLine(label);
|
|
118
|
+
}
|
|
119
|
+
function stopAll() {
|
|
120
|
+
const lineCount = visiblePhaseIds.size;
|
|
121
|
+
phaseStartTimes.clear();
|
|
122
|
+
visiblePhaseIds.clear();
|
|
123
|
+
worker?.postMessage({ type: "stopAll" });
|
|
124
|
+
if (isTTY() && lineCount > 0) {
|
|
125
|
+
let clearOutput = "";
|
|
126
|
+
if (lineCount > 1) clearOutput += "\x1B[A".repeat(lineCount - 1);
|
|
127
|
+
for (let i = 0; i < lineCount; i++) {
|
|
128
|
+
clearOutput += "\r\x1B[2K";
|
|
129
|
+
if (i < lineCount - 1) clearOutput += "\n";
|
|
130
|
+
}
|
|
131
|
+
if (lineCount > 1) clearOutput += "\x1B[A".repeat(lineCount - 1);
|
|
132
|
+
writeSync(SPINNER_OUTPUT_FD, clearOutput);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function start(label) {
|
|
136
|
+
defaultLabel = label;
|
|
137
|
+
startPhase(DEFAULT_PHASE_ID, label);
|
|
138
|
+
}
|
|
139
|
+
function setLabel(label) {
|
|
140
|
+
defaultLabel = label;
|
|
141
|
+
updatePhase(DEFAULT_PHASE_ID, label);
|
|
142
|
+
}
|
|
143
|
+
function complete(label, elapsedMs) {
|
|
144
|
+
completePhase(DEFAULT_PHASE_ID, label, elapsedMs);
|
|
145
|
+
}
|
|
146
|
+
function fail(label, elapsedMs, error) {
|
|
147
|
+
failPhase(DEFAULT_PHASE_ID, label, elapsedMs, error);
|
|
148
|
+
}
|
|
149
|
+
function skip(label) {
|
|
150
|
+
skipPhase(DEFAULT_PHASE_ID, label);
|
|
151
|
+
}
|
|
152
|
+
function stop() {
|
|
153
|
+
stopAll();
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
start,
|
|
157
|
+
setLabel,
|
|
158
|
+
complete,
|
|
159
|
+
fail,
|
|
160
|
+
skip,
|
|
161
|
+
stop,
|
|
162
|
+
isRunning: () => visiblePhaseIds.size > 0,
|
|
163
|
+
currentLabel: () => defaultLabel,
|
|
164
|
+
addPendingPhase,
|
|
165
|
+
startPhase,
|
|
166
|
+
updatePhase,
|
|
167
|
+
completePhase,
|
|
168
|
+
failPhase,
|
|
169
|
+
skipPhase
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
173
|
+
export { formatProgressDuration as n, createSpinnerProgress as t };
|