@keystrokehq/cli 0.0.132 → 0.0.134
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/index.mjs +179 -107
- package/dist/index.mjs.map +1 -1
- package/dist/skills-bundle/skills/keystroke-actions/SKILL.md +3 -4
- package/dist/skills-bundle/skills/keystroke-actions/references/catalog-and-imports.md +1 -1
- package/dist/skills-bundle/skills/keystroke-agents/SKILL.md +12 -16
- package/dist/skills-bundle/skills/keystroke-credentials/SKILL.md +1 -1
- package/dist/skills-bundle/skills/keystroke-files/SKILL.md +5 -7
- package/dist/skills-bundle/skills/keystroke-skills/SKILL.md +4 -1
- package/dist/skills-bundle/skills/keystroke-workflows/SKILL.md +1 -1
- package/dist/templates/hello-world/src/actions/greet.ts +1 -1
- package/dist/templates/hello-world/src/agents/hello.ts +5 -7
- package/dist/templates/hello-world/src/workflows/greeting.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1852,6 +1852,8 @@ const OrganizationSlugSchema = string().trim().toLowerCase().min(2, "Slug must b
|
|
|
1852
1852
|
* fail to load.
|
|
1853
1853
|
*/
|
|
1854
1854
|
const ClaimableOrganizationSlugSchema = OrganizationSlugSchema.refine((slug) => !RESERVED_ORGANIZATION_SLUGS.has(slug), "This slug is reserved");
|
|
1855
|
+
/** Same format as organization slugs — org-scoped, no global reserved list. */
|
|
1856
|
+
const ProjectSlugSchema = OrganizationSlugSchema;
|
|
1855
1857
|
/** Browser→platform request budget (ping + small platform overhead). */
|
|
1856
1858
|
const PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS = 17e3;
|
|
1857
1859
|
/** Normalize a public origin URL (no trailing slash). */
|
|
@@ -1891,6 +1893,7 @@ const serializedRouteManifestEntrySchema = discriminatedUnion("kind", [
|
|
|
1891
1893
|
kind: literal("agent"),
|
|
1892
1894
|
method: literal("POST"),
|
|
1893
1895
|
path: string(),
|
|
1896
|
+
agentSlug: string(),
|
|
1894
1897
|
moduleFile: string(),
|
|
1895
1898
|
requestSchema: record(string(), unknown()),
|
|
1896
1899
|
responseSchema: record(string(), unknown())
|
|
@@ -1899,21 +1902,21 @@ const serializedRouteManifestEntrySchema = discriminatedUnion("kind", [
|
|
|
1899
1902
|
kind: literal("agent-sessions-list"),
|
|
1900
1903
|
method: literal("GET"),
|
|
1901
1904
|
path: string(),
|
|
1902
|
-
|
|
1905
|
+
agentSlug: string(),
|
|
1903
1906
|
moduleFile: string()
|
|
1904
1907
|
}),
|
|
1905
1908
|
object({
|
|
1906
1909
|
kind: literal("agent-session-detail"),
|
|
1907
1910
|
method: literal("GET"),
|
|
1908
1911
|
path: string(),
|
|
1909
|
-
|
|
1912
|
+
agentSlug: string(),
|
|
1910
1913
|
moduleFile: string()
|
|
1911
1914
|
}),
|
|
1912
1915
|
object({
|
|
1913
1916
|
kind: literal("workflow"),
|
|
1914
1917
|
method: literal("POST"),
|
|
1915
1918
|
path: string(),
|
|
1916
|
-
|
|
1919
|
+
workflowSlug: string(),
|
|
1917
1920
|
workflowName: string().optional(),
|
|
1918
1921
|
moduleFile: string(),
|
|
1919
1922
|
requestSchema: record(string(), unknown()),
|
|
@@ -1923,7 +1926,7 @@ const serializedRouteManifestEntrySchema = discriminatedUnion("kind", [
|
|
|
1923
1926
|
kind: literal("workflow-runs-list"),
|
|
1924
1927
|
method: literal("GET"),
|
|
1925
1928
|
path: string(),
|
|
1926
|
-
|
|
1929
|
+
workflowSlug: string(),
|
|
1927
1930
|
workflowName: string().optional(),
|
|
1928
1931
|
moduleFile: string()
|
|
1929
1932
|
}),
|
|
@@ -1931,7 +1934,7 @@ const serializedRouteManifestEntrySchema = discriminatedUnion("kind", [
|
|
|
1931
1934
|
kind: literal("workflow-run-detail"),
|
|
1932
1935
|
method: literal("GET"),
|
|
1933
1936
|
path: string(),
|
|
1934
|
-
|
|
1937
|
+
workflowSlug: string(),
|
|
1935
1938
|
workflowName: string().optional(),
|
|
1936
1939
|
moduleFile: string()
|
|
1937
1940
|
}),
|
|
@@ -2053,6 +2056,17 @@ object({
|
|
|
2053
2056
|
slug: string().trim().min(1),
|
|
2054
2057
|
excludeOrganizationId: string().min(1).optional()
|
|
2055
2058
|
});
|
|
2059
|
+
const ProjectSlugAvailabilityReasonSchema = _enum(["taken", "invalid"]);
|
|
2060
|
+
const ProjectSlugAvailabilityResponseSchema = object({
|
|
2061
|
+
slug: string(),
|
|
2062
|
+
available: boolean(),
|
|
2063
|
+
reason: ProjectSlugAvailabilityReasonSchema.optional(),
|
|
2064
|
+
suggestion: ProjectSlugSchema.optional()
|
|
2065
|
+
});
|
|
2066
|
+
object({
|
|
2067
|
+
slug: string().trim().min(1),
|
|
2068
|
+
excludeProjectId: string().min(1).optional()
|
|
2069
|
+
});
|
|
2056
2070
|
const ProjectStatusSchema = _enum([
|
|
2057
2071
|
"inactive",
|
|
2058
2072
|
"starting",
|
|
@@ -2076,6 +2090,7 @@ const ProjectSchema = object({
|
|
|
2076
2090
|
id: string(),
|
|
2077
2091
|
organizationId: string(),
|
|
2078
2092
|
name: string(),
|
|
2093
|
+
slug: ProjectSlugSchema,
|
|
2079
2094
|
description: string().nullable(),
|
|
2080
2095
|
status: ProjectStatusSchema,
|
|
2081
2096
|
baseUrl: string().nullable(),
|
|
@@ -2116,8 +2131,9 @@ const CreateProjectRequestSchema = object({
|
|
|
2116
2131
|
});
|
|
2117
2132
|
const UpdateProjectRequestSchema = object({
|
|
2118
2133
|
name: string().trim().min(1).optional(),
|
|
2119
|
-
description: string().trim().optional()
|
|
2120
|
-
|
|
2134
|
+
description: string().trim().optional(),
|
|
2135
|
+
slug: ProjectSlugSchema.optional()
|
|
2136
|
+
}).refine((data) => data.name !== void 0 || data.description !== void 0 || data.slug !== void 0, { message: "At least one field is required" });
|
|
2121
2137
|
const CreateProjectResponseSchema = object({ project: ProjectSchema });
|
|
2122
2138
|
const ProjectResponseSchema = object({ project: ProjectSchema });
|
|
2123
2139
|
const ProjectReachabilityResponseSchema = object({ reachable: boolean() });
|
|
@@ -2255,7 +2271,7 @@ const WorkflowRunSummarySchema = object({
|
|
|
2255
2271
|
});
|
|
2256
2272
|
const WorkflowRunRecordSchema = object({
|
|
2257
2273
|
id: string(),
|
|
2258
|
-
|
|
2274
|
+
workflowSlug: string(),
|
|
2259
2275
|
status: WorkflowRunStatusSchema,
|
|
2260
2276
|
trigger: WorkflowRunTriggerSchema,
|
|
2261
2277
|
triggeredAt: string(),
|
|
@@ -2290,7 +2306,7 @@ object({ include: string().optional() });
|
|
|
2290
2306
|
const TriggerRunDetailSchema = object({
|
|
2291
2307
|
id: string(),
|
|
2292
2308
|
attachmentId: string(),
|
|
2293
|
-
|
|
2309
|
+
attachmentSlug: string().nullable(),
|
|
2294
2310
|
triggerType: _enum([
|
|
2295
2311
|
"cron",
|
|
2296
2312
|
"webhook",
|
|
@@ -2309,10 +2325,10 @@ const WorkflowStepRunSchema = object({
|
|
|
2309
2325
|
const TraceTriggerSummarySchema = object({
|
|
2310
2326
|
triggerType: string(),
|
|
2311
2327
|
triggerRunId: string(),
|
|
2312
|
-
|
|
2313
|
-
|
|
2328
|
+
workflowSlug: string().optional(),
|
|
2329
|
+
agentSlug: string().optional(),
|
|
2314
2330
|
attachmentId: string().nullable().optional(),
|
|
2315
|
-
|
|
2331
|
+
attachmentSlug: string().nullable().optional(),
|
|
2316
2332
|
route: string().optional(),
|
|
2317
2333
|
sourcePath: string().nullable().optional()
|
|
2318
2334
|
}).nullable();
|
|
@@ -2376,7 +2392,7 @@ const AgentSessionSummarySchema = object({
|
|
|
2376
2392
|
});
|
|
2377
2393
|
const AgentSessionRecordSchema = object({
|
|
2378
2394
|
id: string(),
|
|
2379
|
-
|
|
2395
|
+
agentSlug: string(),
|
|
2380
2396
|
status: AgentSessionStatusSchema,
|
|
2381
2397
|
source: RunSourceKindSchema,
|
|
2382
2398
|
sourceId: string().nullable(),
|
|
@@ -2406,7 +2422,7 @@ object({ include: string().optional() });
|
|
|
2406
2422
|
const GatewaySessionDetailSchema = object({
|
|
2407
2423
|
threadId: string(),
|
|
2408
2424
|
attachmentId: string(),
|
|
2409
|
-
|
|
2425
|
+
attachmentSlug: string().nullable()
|
|
2410
2426
|
});
|
|
2411
2427
|
const AgentEventSchema = object({
|
|
2412
2428
|
id: string(),
|
|
@@ -2501,11 +2517,11 @@ const TriggerRunTypeSchema = _enum([
|
|
|
2501
2517
|
const TriggerRunWorkflowSummarySchema = object({
|
|
2502
2518
|
id: string(),
|
|
2503
2519
|
status: WorkflowRunStatusSchema,
|
|
2504
|
-
|
|
2520
|
+
workflowSlug: string()
|
|
2505
2521
|
});
|
|
2506
2522
|
const TriggerRunAgentSessionSummarySchema = object({
|
|
2507
2523
|
id: string(),
|
|
2508
|
-
|
|
2524
|
+
agentSlug: string()
|
|
2509
2525
|
});
|
|
2510
2526
|
const TriggerRunSummarySchema = object({
|
|
2511
2527
|
id: string(),
|
|
@@ -2518,7 +2534,7 @@ const TriggerRunSummarySchema = object({
|
|
|
2518
2534
|
const TriggerRunRecordSchema = object({
|
|
2519
2535
|
id: string(),
|
|
2520
2536
|
attachmentId: string(),
|
|
2521
|
-
|
|
2537
|
+
attachmentSlug: string(),
|
|
2522
2538
|
triggerType: TriggerRunTypeSchema,
|
|
2523
2539
|
sourcePath: string().nullable(),
|
|
2524
2540
|
payload: unknown().nullable(),
|
|
@@ -2541,7 +2557,7 @@ _enum([
|
|
|
2541
2557
|
object({ include: string().optional() });
|
|
2542
2558
|
const TriggerRunAgentSessionDetailSchema = object({
|
|
2543
2559
|
id: string(),
|
|
2544
|
-
|
|
2560
|
+
agentSlug: string()
|
|
2545
2561
|
});
|
|
2546
2562
|
const TriggerRunDetailResponseSchema = object({
|
|
2547
2563
|
run: TriggerRunRecordSchema,
|
|
@@ -2684,6 +2700,7 @@ const optionalCount = number$1().int().nonnegative().nullable().optional();
|
|
|
2684
2700
|
const optionalTimestamp = string().nullable().optional();
|
|
2685
2701
|
const AgentSummarySchema = object({
|
|
2686
2702
|
id: string().min(1),
|
|
2703
|
+
slug: string().min(1),
|
|
2687
2704
|
name: string().min(1),
|
|
2688
2705
|
projectId: string().min(1),
|
|
2689
2706
|
updatedAt: string().min(1),
|
|
@@ -2696,16 +2713,17 @@ const AgentSummarySchema = object({
|
|
|
2696
2713
|
});
|
|
2697
2714
|
const WorkflowSummarySchema = object({
|
|
2698
2715
|
id: string().min(1),
|
|
2716
|
+
slug: string().min(1),
|
|
2699
2717
|
name: string().min(1),
|
|
2700
2718
|
projectId: string().min(1),
|
|
2701
2719
|
updatedAt: string().min(1),
|
|
2702
2720
|
description: string().optional(),
|
|
2703
2721
|
sourcePath: string().min(1).optional(),
|
|
2704
|
-
stepCount: optionalCount,
|
|
2705
2722
|
lastRunAt: optionalTimestamp
|
|
2706
2723
|
});
|
|
2707
2724
|
const SkillSummarySchema = object({
|
|
2708
2725
|
id: string().min(1),
|
|
2726
|
+
slug: string().min(1),
|
|
2709
2727
|
name: string().min(1),
|
|
2710
2728
|
projectId: string().min(1),
|
|
2711
2729
|
updatedAt: string().min(1),
|
|
@@ -2750,9 +2768,9 @@ const ProjectFileSummarySchema = object({
|
|
|
2750
2768
|
path: string().min(1),
|
|
2751
2769
|
hash: sha256Hex
|
|
2752
2770
|
});
|
|
2753
|
-
/** Maps a runtime resource
|
|
2771
|
+
/** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
|
|
2754
2772
|
const ProjectSourceResourceRefSchema = object({
|
|
2755
|
-
|
|
2773
|
+
slug: string().min(1),
|
|
2756
2774
|
path: string().min(1)
|
|
2757
2775
|
});
|
|
2758
2776
|
const ProjectSourceResourcesSchema = object({
|
|
@@ -5174,6 +5192,16 @@ function createProjectsResource(http) {
|
|
|
5174
5192
|
} catch (error) {
|
|
5175
5193
|
throw await toPlatformError(error);
|
|
5176
5194
|
}
|
|
5195
|
+
},
|
|
5196
|
+
async checkSlug(slug, options = {}) {
|
|
5197
|
+
const searchParams = new URLSearchParams({ slug });
|
|
5198
|
+
if (options.excludeProjectId) searchParams.set("excludeProjectId", options.excludeProjectId);
|
|
5199
|
+
try {
|
|
5200
|
+
const data = await http.get(`/api/projects/slug-available?${searchParams}`).json();
|
|
5201
|
+
return ProjectSlugAvailabilityResponseSchema.parse(data);
|
|
5202
|
+
} catch (error) {
|
|
5203
|
+
throw await toPlatformError(error);
|
|
5204
|
+
}
|
|
5177
5205
|
}
|
|
5178
5206
|
};
|
|
5179
5207
|
}
|
|
@@ -5187,11 +5215,15 @@ function createProjectMetricsResource(http) {
|
|
|
5187
5215
|
}
|
|
5188
5216
|
} };
|
|
5189
5217
|
}
|
|
5218
|
+
function listSearchParams$2(options) {
|
|
5219
|
+
const projectId = options?.projectId?.trim();
|
|
5220
|
+
return projectId ? { projectId } : void 0;
|
|
5221
|
+
}
|
|
5190
5222
|
function createAgentsResource(http) {
|
|
5191
5223
|
return {
|
|
5192
|
-
async list() {
|
|
5224
|
+
async list(options) {
|
|
5193
5225
|
try {
|
|
5194
|
-
const data = await http.get("/api/agents").json();
|
|
5226
|
+
const data = await http.get("/api/agents", { searchParams: listSearchParams$2(options) }).json();
|
|
5195
5227
|
return AgentSummaryListResponseSchema.parse(data);
|
|
5196
5228
|
} catch (error) {
|
|
5197
5229
|
throw await toPlatformError(error);
|
|
@@ -5207,11 +5239,15 @@ function createAgentsResource(http) {
|
|
|
5207
5239
|
}
|
|
5208
5240
|
};
|
|
5209
5241
|
}
|
|
5242
|
+
function listSearchParams$1(options) {
|
|
5243
|
+
const projectId = options?.projectId?.trim();
|
|
5244
|
+
return projectId ? { projectId } : void 0;
|
|
5245
|
+
}
|
|
5210
5246
|
function createWorkflowsResource(http) {
|
|
5211
5247
|
return {
|
|
5212
|
-
async list() {
|
|
5248
|
+
async list(options) {
|
|
5213
5249
|
try {
|
|
5214
|
-
const data = await http.get("/api/workflows").json();
|
|
5250
|
+
const data = await http.get("/api/workflows", { searchParams: listSearchParams$1(options) }).json();
|
|
5215
5251
|
return WorkflowSummaryListResponseSchema.parse(data);
|
|
5216
5252
|
} catch (error) {
|
|
5217
5253
|
throw await toPlatformError(error);
|
|
@@ -5227,11 +5263,15 @@ function createWorkflowsResource(http) {
|
|
|
5227
5263
|
}
|
|
5228
5264
|
};
|
|
5229
5265
|
}
|
|
5266
|
+
function listSearchParams(options) {
|
|
5267
|
+
const projectId = options?.projectId?.trim();
|
|
5268
|
+
return projectId ? { projectId } : void 0;
|
|
5269
|
+
}
|
|
5230
5270
|
function createSkillsResource(http) {
|
|
5231
5271
|
return {
|
|
5232
|
-
async list() {
|
|
5272
|
+
async list(options) {
|
|
5233
5273
|
try {
|
|
5234
|
-
const data = await http.get("/api/skills").json();
|
|
5274
|
+
const data = await http.get("/api/skills", { searchParams: listSearchParams(options) }).json();
|
|
5235
5275
|
return SkillSummaryListResponseSchema.parse(data);
|
|
5236
5276
|
} catch (error) {
|
|
5237
5277
|
throw await toPlatformError(error);
|
|
@@ -6754,6 +6794,7 @@ const credentialSeed = [
|
|
|
6754
6794
|
];
|
|
6755
6795
|
const agentSeed = [{
|
|
6756
6796
|
id: "agent-support",
|
|
6797
|
+
slug: "support-agent",
|
|
6757
6798
|
name: "Support Agent",
|
|
6758
6799
|
projectId: "project_personal_repo",
|
|
6759
6800
|
updatedAt: "2026-06-02T14:20:00Z",
|
|
@@ -6765,6 +6806,7 @@ const agentSeed = [{
|
|
|
6765
6806
|
lastRunAt: "2026-06-02T14:20:00Z"
|
|
6766
6807
|
}, {
|
|
6767
6808
|
id: "agent-research",
|
|
6809
|
+
slug: "research-agent",
|
|
6768
6810
|
name: "Research Agent",
|
|
6769
6811
|
projectId: "project_personal_repo",
|
|
6770
6812
|
updatedAt: "2026-06-01T09:15:00Z",
|
|
@@ -6777,21 +6819,21 @@ const agentSeed = [{
|
|
|
6777
6819
|
}];
|
|
6778
6820
|
const workflowSeed = [{
|
|
6779
6821
|
id: "workflow-daily-digest",
|
|
6822
|
+
slug: "daily-digest",
|
|
6780
6823
|
name: "Daily Digest",
|
|
6781
6824
|
projectId: "project_personal_repo",
|
|
6782
6825
|
updatedAt: "2026-06-02T11:05:00Z",
|
|
6783
6826
|
description: "Collect project updates and send a daily summary.",
|
|
6784
6827
|
sourcePath: "src/workflows/daily-digest.ts",
|
|
6785
|
-
stepCount: 2,
|
|
6786
6828
|
lastRunAt: "2026-06-02T11:05:00Z"
|
|
6787
6829
|
}, {
|
|
6788
6830
|
id: "workflow-email-triage",
|
|
6831
|
+
slug: "email-triage",
|
|
6789
6832
|
name: "Email Triage",
|
|
6790
6833
|
projectId: "project_personal_repo",
|
|
6791
6834
|
updatedAt: "2026-05-31T16:40:00Z",
|
|
6792
6835
|
description: "Label, prioritize, and draft replies for inbound email.",
|
|
6793
6836
|
sourcePath: "src/workflows/email-triage.ts",
|
|
6794
|
-
stepCount: 4,
|
|
6795
6837
|
lastRunAt: "2026-05-31T16:40:00Z"
|
|
6796
6838
|
}];
|
|
6797
6839
|
/** Review personas for mocked project members and API key authors (not org membership). */
|
|
@@ -7124,15 +7166,11 @@ function buildFailedUsage(durationMs) {
|
|
|
7124
7166
|
totalExcludingDurationUsd: .021
|
|
7125
7167
|
};
|
|
7126
7168
|
}
|
|
7127
|
-
function
|
|
7128
|
-
|
|
7129
|
-
if (!row?.sourcePath) return workflowId;
|
|
7130
|
-
return row.sourcePath.match(/\/([^/]+)\.ts$/)?.[1] ?? workflowId;
|
|
7169
|
+
function workflowSlugFromId(workflowId) {
|
|
7170
|
+
return workflowSeed.find((workflow) => workflow.id === workflowId)?.slug ?? workflowId;
|
|
7131
7171
|
}
|
|
7132
|
-
function
|
|
7133
|
-
|
|
7134
|
-
if (!row?.sourcePath) return agentId;
|
|
7135
|
-
return row.sourcePath.match(/\/([^/]+)\.ts$/)?.[1] ?? agentId;
|
|
7172
|
+
function agentSlugFromId(agentId) {
|
|
7173
|
+
return agentSeed.find((agent) => agent.id === agentId)?.slug ?? agentId;
|
|
7136
7174
|
}
|
|
7137
7175
|
const historyRunSeed = [
|
|
7138
7176
|
{
|
|
@@ -7141,7 +7179,7 @@ const historyRunSeed = [
|
|
|
7141
7179
|
traceId: "run-support-agent-001",
|
|
7142
7180
|
projectId: "project_personal_repo",
|
|
7143
7181
|
projectName: historyProjectNameById.project_personal_repo ?? "Project",
|
|
7144
|
-
resourceKey:
|
|
7182
|
+
resourceKey: agentSlugFromId("agent-support"),
|
|
7145
7183
|
resourceId: "agent-support",
|
|
7146
7184
|
resourceName: "Support Agent",
|
|
7147
7185
|
status: "completed",
|
|
@@ -7164,7 +7202,7 @@ const historyRunSeed = [
|
|
|
7164
7202
|
traceId: "run-daily-digest-001",
|
|
7165
7203
|
projectId: "project_personal_repo",
|
|
7166
7204
|
projectName: historyProjectNameById.project_personal_repo ?? "Project",
|
|
7167
|
-
resourceKey:
|
|
7205
|
+
resourceKey: workflowSlugFromId("workflow-daily-digest"),
|
|
7168
7206
|
resourceId: "workflow-daily-digest",
|
|
7169
7207
|
resourceName: "Daily Digest",
|
|
7170
7208
|
status: "running",
|
|
@@ -7187,7 +7225,7 @@ const historyRunSeed = [
|
|
|
7187
7225
|
traceId: "run-support-agent-000",
|
|
7188
7226
|
projectId: "project_personal_repo",
|
|
7189
7227
|
projectName: historyProjectNameById.project_personal_repo ?? "Project",
|
|
7190
|
-
resourceKey:
|
|
7228
|
+
resourceKey: agentSlugFromId("agent-support"),
|
|
7191
7229
|
resourceId: "agent-support",
|
|
7192
7230
|
resourceName: "Support Agent",
|
|
7193
7231
|
status: "failed",
|
|
@@ -7210,7 +7248,7 @@ const historyRunSeed = [
|
|
|
7210
7248
|
traceId: "run-email-triage-002",
|
|
7211
7249
|
projectId: "project_personal_repo",
|
|
7212
7250
|
projectName: historyProjectNameById.project_personal_repo ?? "Project",
|
|
7213
|
-
resourceKey:
|
|
7251
|
+
resourceKey: workflowSlugFromId("workflow-email-triage"),
|
|
7214
7252
|
resourceId: "workflow-email-triage",
|
|
7215
7253
|
resourceName: "Email Triage",
|
|
7216
7254
|
status: "failed",
|
|
@@ -7233,7 +7271,7 @@ const historyRunSeed = [
|
|
|
7233
7271
|
traceId: "run-research-agent-003",
|
|
7234
7272
|
projectId: "project_personal_repo",
|
|
7235
7273
|
projectName: historyProjectNameById.project_personal_repo ?? "Project",
|
|
7236
|
-
resourceKey:
|
|
7274
|
+
resourceKey: agentSlugFromId("agent-research"),
|
|
7237
7275
|
resourceId: "agent-research",
|
|
7238
7276
|
resourceName: "Research Agent",
|
|
7239
7277
|
status: "completed",
|
|
@@ -8587,6 +8625,33 @@ function createCliPlatformClient(config) {
|
|
|
8587
8625
|
});
|
|
8588
8626
|
}
|
|
8589
8627
|
//#endregion
|
|
8628
|
+
//#region src/resolve-resource-ref.ts
|
|
8629
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8630
|
+
function looksLikeUuid(value) {
|
|
8631
|
+
return UUID_PATTERN.test(value);
|
|
8632
|
+
}
|
|
8633
|
+
function formatProjectLabel(project) {
|
|
8634
|
+
return project.slug;
|
|
8635
|
+
}
|
|
8636
|
+
async function resolveProjectRef(platform, ref) {
|
|
8637
|
+
if (looksLikeUuid(ref)) try {
|
|
8638
|
+
return await platform.projects.get(ref);
|
|
8639
|
+
} catch (error) {
|
|
8640
|
+
if (error instanceof PlatformError && error.status === 404) throw new Error(`Project ${ref} not found in the active organization. Run \`keystroke project list\`, then \`keystroke config use project <slug>\`.`);
|
|
8641
|
+
throw error;
|
|
8642
|
+
}
|
|
8643
|
+
const match = (await platform.projects.list()).find((project) => project.slug === ref);
|
|
8644
|
+
if (!match) throw new Error(`Project "${ref}" not found in the active organization. Run \`keystroke project list\`.`);
|
|
8645
|
+
return match;
|
|
8646
|
+
}
|
|
8647
|
+
function resolveOrganizationRef(organizations, ref) {
|
|
8648
|
+
const byId = organizations.find((entry) => entry.organization.id === ref);
|
|
8649
|
+
if (byId) return byId;
|
|
8650
|
+
const bySlug = organizations.find((entry) => entry.organization.slug === ref);
|
|
8651
|
+
if (bySlug) return bySlug;
|
|
8652
|
+
throw new Error(`Organization "${ref}" was not found or you do not have access`);
|
|
8653
|
+
}
|
|
8654
|
+
//#endregion
|
|
8590
8655
|
//#region src/organization/active-organization.ts
|
|
8591
8656
|
function formatOrganization(membership) {
|
|
8592
8657
|
return `${membership.organization.name} (${membership.role})`;
|
|
@@ -8600,15 +8665,11 @@ async function activateOrganization(config, organizationId) {
|
|
|
8600
8665
|
platform.setActiveOrganizationId(membership.organization.id);
|
|
8601
8666
|
return membership;
|
|
8602
8667
|
}
|
|
8603
|
-
async function pickOrganization(config, organizations,
|
|
8604
|
-
if (
|
|
8605
|
-
const membership = organizations.find((entry) => entry.organization.id === organizationId);
|
|
8606
|
-
if (!membership) throw new Error(`Organization ${organizationId} was not found or you do not have access`);
|
|
8607
|
-
return activateOrganization(config, membership.organization.id);
|
|
8608
|
-
}
|
|
8668
|
+
async function pickOrganization(config, organizations, organizationRef) {
|
|
8669
|
+
if (organizationRef) return activateOrganization(config, resolveOrganizationRef(organizations, organizationRef).organization.id);
|
|
8609
8670
|
if (!process.stdin.isTTY) {
|
|
8610
|
-
const names = organizations.map((entry) => entry.organization.
|
|
8611
|
-
throw new Error(`Multiple organizations found. Run \`keystroke config use org <
|
|
8671
|
+
const names = organizations.map((entry) => entry.organization.slug).join(", ");
|
|
8672
|
+
throw new Error(`Multiple organizations found. Run \`keystroke config use org <slug>\`. Options: ${names}`);
|
|
8612
8673
|
}
|
|
8613
8674
|
return activateOrganization(config, await select({
|
|
8614
8675
|
message: "Select an organization",
|
|
@@ -8622,7 +8683,7 @@ async function selectActiveOrganization(config, options = {}) {
|
|
|
8622
8683
|
const organizations = await listOrganizations(config);
|
|
8623
8684
|
if (organizations.length === 0) throw new Error(`No organization found — create one at ${getWebUrl(config)}`);
|
|
8624
8685
|
if (organizations.length === 1) return activateOrganization(config, organizations[0].organization.id);
|
|
8625
|
-
return pickOrganization(config, organizations, options.organizationId);
|
|
8686
|
+
return pickOrganization(config, organizations, options.organizationRef ?? options.organizationId);
|
|
8626
8687
|
}
|
|
8627
8688
|
async function syncActiveOrganizationAfterLogin(config, options = {}) {
|
|
8628
8689
|
const organizations = await listOrganizations(config);
|
|
@@ -8638,8 +8699,8 @@ async function syncActiveOrganizationAfterLogin(config, options = {}) {
|
|
|
8638
8699
|
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
8639
8700
|
return membership;
|
|
8640
8701
|
}
|
|
8641
|
-
if (options.organizationId) {
|
|
8642
|
-
const membership = await pickOrganization(config, organizations, options.organizationId);
|
|
8702
|
+
if (options.organizationRef ?? options.organizationId) {
|
|
8703
|
+
const membership = await pickOrganization(config, organizations, options.organizationRef ?? options.organizationId);
|
|
8643
8704
|
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
8644
8705
|
return membership;
|
|
8645
8706
|
}
|
|
@@ -8712,19 +8773,19 @@ function resolveOrgPlatformTarget(config) {
|
|
|
8712
8773
|
mode: "platform"
|
|
8713
8774
|
};
|
|
8714
8775
|
}
|
|
8715
|
-
async function resolvePlatformTarget(config,
|
|
8776
|
+
async function resolvePlatformTarget(config, projectRef) {
|
|
8716
8777
|
const platform = createCliPlatformClient(config);
|
|
8717
8778
|
let project;
|
|
8718
8779
|
try {
|
|
8719
|
-
project = await platform
|
|
8780
|
+
project = await resolveProjectRef(platform, projectRef);
|
|
8720
8781
|
} catch (error) {
|
|
8721
|
-
if (error instanceof
|
|
8782
|
+
if (error instanceof Error) throw error;
|
|
8722
8783
|
throw error;
|
|
8723
8784
|
}
|
|
8724
|
-
if (project.status !== "active") throw new Error(`Project ${
|
|
8785
|
+
if (project.status !== "active") throw new Error(`Project ${formatProjectLabel(project)} is not active (${project.status})`);
|
|
8725
8786
|
return {
|
|
8726
|
-
baseUrl: `${getPlatformUrl(config).replace(/\/+$/, "")}/api/projects/${encodeURIComponent(
|
|
8727
|
-
projectId,
|
|
8787
|
+
baseUrl: `${getPlatformUrl(config).replace(/\/+$/, "")}/api/projects/${encodeURIComponent(project.id)}`,
|
|
8788
|
+
projectId: project.id,
|
|
8728
8789
|
mode: "platform"
|
|
8729
8790
|
};
|
|
8730
8791
|
}
|
|
@@ -8742,9 +8803,9 @@ async function resolveApiTarget(config, options = {}) {
|
|
|
8742
8803
|
if (options.projectId) return resolvePlatformTarget(config, options.projectId);
|
|
8743
8804
|
if (getEffectiveApiTarget(config) === "local") return resolveLocalTarget(config);
|
|
8744
8805
|
if (!options.projectScoped) return resolveOrgPlatformTarget(config);
|
|
8745
|
-
const
|
|
8746
|
-
if (!
|
|
8747
|
-
return resolvePlatformTarget(config,
|
|
8806
|
+
const projectRef = options.projectId ?? config.get("activeProjectId");
|
|
8807
|
+
if (!projectRef) throw new Error("No project selected. Pass `--project <slug>` or run `keystroke config use project <slug>`.");
|
|
8808
|
+
return resolvePlatformTarget(config, projectRef);
|
|
8748
8809
|
}
|
|
8749
8810
|
//#endregion
|
|
8750
8811
|
//#region src/target-options.ts
|
|
@@ -8755,9 +8816,6 @@ function setCliTargetOptions(options) {
|
|
|
8755
8816
|
function getCliTargetOptions() {
|
|
8756
8817
|
return targetOptions;
|
|
8757
8818
|
}
|
|
8758
|
-
function resolveActiveProjectId(config) {
|
|
8759
|
-
return getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
8760
|
-
}
|
|
8761
8819
|
//#endregion
|
|
8762
8820
|
//#region src/errors/example-input.ts
|
|
8763
8821
|
function exampleValueFromValidationMessage(message) {
|
|
@@ -9232,7 +9290,7 @@ function resolveAuthLoginTargets(options, config) {
|
|
|
9232
9290
|
//#endregion
|
|
9233
9291
|
//#region src/commands/auth/login.ts
|
|
9234
9292
|
function registerAuthLoginCommand(auth) {
|
|
9235
|
-
auth.command("login").description("Authenticate via browser device flow").option("--web-url <url>", "Web dashboard origin (omit to use production defaults; local dev: http://localhost:3000)").option("--platform-url <url>", "Platform API origin (derived from web URL when omitted)").option("--org <
|
|
9293
|
+
auth.command("login").description("Authenticate via browser device flow").option("--web-url <url>", "Web dashboard origin (omit to use production defaults; local dev: http://localhost:3000)").option("--platform-url <url>", "Platform API origin (derived from web URL when omitted)").option("--org <slug>", "Active organization slug (skips prompt when you belong to several)").action(async (options) => {
|
|
9236
9294
|
const config = createCliConfig();
|
|
9237
9295
|
const { webUrl, platformUrl } = resolveAuthLoginTargets(options, config);
|
|
9238
9296
|
config.set("webUrl", webUrl);
|
|
@@ -9247,7 +9305,7 @@ function registerAuthLoginCommand(auth) {
|
|
|
9247
9305
|
const user = await getSessionWithBearer(platformUrl, result.accessToken);
|
|
9248
9306
|
if (user) process.stdout.write(`Logged in as ${user.name} (${user.email})\n`);
|
|
9249
9307
|
else process.stdout.write(`Logged in to ${webUrl}\n`);
|
|
9250
|
-
await syncActiveOrganizationAfterLogin(config, {
|
|
9308
|
+
await syncActiveOrganizationAfterLogin(config, { organizationRef: options.org });
|
|
9251
9309
|
} catch (error) {
|
|
9252
9310
|
process.stderr.write(`${formatCliError(error, "Login failed", {
|
|
9253
9311
|
webUrl,
|
|
@@ -9425,9 +9483,9 @@ function collectModuleRefs(srcRoot, root, files, subdir, nestedEntry) {
|
|
|
9425
9483
|
const refs = [];
|
|
9426
9484
|
for (const file of files) {
|
|
9427
9485
|
if (!file.path.startsWith(prefix) || !/\.(ts|mts)$/.test(file.path)) continue;
|
|
9428
|
-
const
|
|
9429
|
-
if (
|
|
9430
|
-
|
|
9486
|
+
const slug = entryIdFromFile(dir, join(root, file.path), { nestedEntry });
|
|
9487
|
+
if (slug) refs.push({
|
|
9488
|
+
slug,
|
|
9431
9489
|
path: file.path
|
|
9432
9490
|
});
|
|
9433
9491
|
}
|
|
@@ -9439,9 +9497,9 @@ function collectSkillRefs(srcRoot, root, files) {
|
|
|
9439
9497
|
const refs = [];
|
|
9440
9498
|
for (const file of files) {
|
|
9441
9499
|
if (!file.path.startsWith(prefix) || !file.path.endsWith("SKILL.md")) continue;
|
|
9442
|
-
const
|
|
9443
|
-
if (
|
|
9444
|
-
|
|
9500
|
+
const slug = toPosix(relative(dir, join(root, file.path)).replace(/\/?SKILL\.md$/, ""));
|
|
9501
|
+
if (slug) refs.push({
|
|
9502
|
+
slug,
|
|
9445
9503
|
path: file.path
|
|
9446
9504
|
});
|
|
9447
9505
|
}
|
|
@@ -9467,6 +9525,18 @@ function collectProjectSource(root) {
|
|
|
9467
9525
|
};
|
|
9468
9526
|
}
|
|
9469
9527
|
//#endregion
|
|
9528
|
+
//#region src/resolve-project-target.ts
|
|
9529
|
+
async function resolveActiveProject(config, platform) {
|
|
9530
|
+
const ref = getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
9531
|
+
if (!ref) return;
|
|
9532
|
+
const client = platform ?? createCliPlatformClient(config);
|
|
9533
|
+
if (!getCliTargetOptions().projectId && looksLikeUuid(ref)) return resolveProjectRef(client, ref);
|
|
9534
|
+
return resolveProjectRef(client, ref);
|
|
9535
|
+
}
|
|
9536
|
+
async function resolveActiveProjectId(config) {
|
|
9537
|
+
return (await resolveActiveProject(config))?.id;
|
|
9538
|
+
}
|
|
9539
|
+
//#endregion
|
|
9470
9540
|
//#region src/commands/deploy.ts
|
|
9471
9541
|
const POLL_INTERVAL_MS = 2e3;
|
|
9472
9542
|
const DEPLOY_TIMEOUT_MS = 12e4;
|
|
@@ -9557,8 +9627,8 @@ async function runDeploy(options) {
|
|
|
9557
9627
|
function registerDeployCommand(program) {
|
|
9558
9628
|
program.command("deploy").description("Build, upload, and deploy the project to the platform").option("--dir <path>", "Project directory", process.cwd()).option("--skip-build", "Upload the existing dist/ without rebuilding").action(async (options) => {
|
|
9559
9629
|
try {
|
|
9560
|
-
const projectId = resolveActiveProjectId(createCliConfig());
|
|
9561
|
-
if (!projectId) throw new Error("Usage: keystroke deploy --project <
|
|
9630
|
+
const projectId = await resolveActiveProjectId(createCliConfig());
|
|
9631
|
+
if (!projectId) throw new Error("Usage: keystroke deploy --project <slug>");
|
|
9562
9632
|
await runDeploy({
|
|
9563
9633
|
dir: options.dir,
|
|
9564
9634
|
projectId,
|
|
@@ -10118,7 +10188,7 @@ function writeInactiveDeployHints(projects) {
|
|
|
10118
10188
|
const bin = cliBinaryName();
|
|
10119
10189
|
for (const project of projects) {
|
|
10120
10190
|
if (project.status !== "inactive") continue;
|
|
10121
|
-
process.stderr.write(`Project ${project
|
|
10191
|
+
process.stderr.write(`Project ${formatProjectLabel(project)} is inactive. Deploy with: ${bin} deploy --project ${formatProjectLabel(project)}\n`);
|
|
10122
10192
|
}
|
|
10123
10193
|
}
|
|
10124
10194
|
async function runProjectList(config) {
|
|
@@ -10136,13 +10206,19 @@ async function runProjectList(config) {
|
|
|
10136
10206
|
async function runProjectMetrics(config, options) {
|
|
10137
10207
|
await withActivePlatformClient(config, async (platform) => {
|
|
10138
10208
|
const metrics = await platform.projectMetrics.list();
|
|
10139
|
-
|
|
10209
|
+
if (options.projectRef === void 0) {
|
|
10210
|
+
process.stdout.write(`${JSON.stringify(metrics, null, 2)}\n`);
|
|
10211
|
+
return;
|
|
10212
|
+
}
|
|
10213
|
+
const project = await resolveProjectRef(platform, options.projectRef);
|
|
10214
|
+
const output = Object.fromEntries(Object.entries(metrics).filter(([projectId]) => projectId === project.id));
|
|
10140
10215
|
process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
|
|
10141
10216
|
});
|
|
10142
10217
|
}
|
|
10143
10218
|
async function runProjectDeploymentsList(config, options) {
|
|
10144
10219
|
await withActivePlatformClient(config, async (platform) => {
|
|
10145
|
-
const
|
|
10220
|
+
const project = await resolveProjectRef(platform, options.projectRef);
|
|
10221
|
+
const deployments = await platform.deployments.listForProject(project.id);
|
|
10146
10222
|
process.stdout.write(`${JSON.stringify({ deployments }, null, 2)}\n`);
|
|
10147
10223
|
});
|
|
10148
10224
|
}
|
|
@@ -10206,10 +10282,10 @@ function registerProjectCommand(program) {
|
|
|
10206
10282
|
process.exitCode = 1;
|
|
10207
10283
|
}
|
|
10208
10284
|
});
|
|
10209
|
-
project.command("metrics").description("List rollup metrics for projects in the active organization").option("--project <
|
|
10285
|
+
project.command("metrics").description("List rollup metrics for projects in the active organization").option("--project <slug>", "Return metrics for a single project").action(async (options) => {
|
|
10210
10286
|
const config = createCliConfig();
|
|
10211
10287
|
try {
|
|
10212
|
-
await runProjectMetrics(config, { ...options.project ? {
|
|
10288
|
+
await runProjectMetrics(config, { ...options.project ? { projectRef: options.project } : {} });
|
|
10213
10289
|
} catch (error) {
|
|
10214
10290
|
process.stderr.write(`${formatCliError(error, "List project metrics failed", {
|
|
10215
10291
|
serverUrl: getPlatformUrl(config),
|
|
@@ -10218,12 +10294,12 @@ function registerProjectCommand(program) {
|
|
|
10218
10294
|
process.exitCode = 1;
|
|
10219
10295
|
}
|
|
10220
10296
|
});
|
|
10221
|
-
project.command("deployments").description("View deployment history for platform projects").command("list").description("List deployment history for a project").option("--project <
|
|
10297
|
+
project.command("deployments").description("View deployment history for platform projects").command("list").description("List deployment history for a project").option("--project <slug>", "Project slug").action(async (options) => {
|
|
10222
10298
|
const config = createCliConfig();
|
|
10223
10299
|
try {
|
|
10224
|
-
const
|
|
10225
|
-
if (!
|
|
10226
|
-
await runProjectDeploymentsList(config, {
|
|
10300
|
+
const projectRef = options.project ?? getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
10301
|
+
if (!projectRef) throw new Error("Usage: keystroke project deployments list --project <slug>");
|
|
10302
|
+
await runProjectDeploymentsList(config, { projectRef });
|
|
10227
10303
|
} catch (error) {
|
|
10228
10304
|
process.stderr.write(`${formatCliError(error, "List deployments failed", {
|
|
10229
10305
|
serverUrl: getPlatformUrl(config),
|
|
@@ -10250,8 +10326,8 @@ function registerProjectCommand(program) {
|
|
|
10250
10326
|
project.command("update").description("Update a platform project's name and/or description").option("--name <name>", "Project name").option("--description <description>", "Project description").action(async (options) => {
|
|
10251
10327
|
const config = createCliConfig();
|
|
10252
10328
|
try {
|
|
10253
|
-
const projectId = resolveActiveProjectId(config);
|
|
10254
|
-
if (!projectId) throw new Error("Usage: keystroke --project <
|
|
10329
|
+
const projectId = await resolveActiveProjectId(config);
|
|
10330
|
+
if (!projectId) throw new Error("Usage: keystroke --project <slug> project update --name <name>");
|
|
10255
10331
|
if (!options.name && options.description === void 0) throw new Error("At least one of --name or --description is required");
|
|
10256
10332
|
await runProjectUpdate(config, {
|
|
10257
10333
|
projectId,
|
|
@@ -10269,8 +10345,8 @@ function registerProjectCommand(program) {
|
|
|
10269
10345
|
project.command("delete").description("Delete a platform project").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
10270
10346
|
const config = createCliConfig();
|
|
10271
10347
|
try {
|
|
10272
|
-
const projectId = resolveActiveProjectId(config);
|
|
10273
|
-
if (!projectId) throw new Error("Usage: keystroke --project <
|
|
10348
|
+
const projectId = await resolveActiveProjectId(config);
|
|
10349
|
+
if (!projectId) throw new Error("Usage: keystroke --project <slug> project delete");
|
|
10274
10350
|
if (!options.yes) throw new Error("Pass --yes to confirm project deletion");
|
|
10275
10351
|
await runProjectDelete(config, projectId);
|
|
10276
10352
|
} catch (error) {
|
|
@@ -10431,27 +10507,23 @@ function registerWorkflowCommand(program) {
|
|
|
10431
10507
|
}
|
|
10432
10508
|
//#endregion
|
|
10433
10509
|
//#region src/commands/config/use-project.ts
|
|
10434
|
-
async function fetchProjectInOrg(config,
|
|
10435
|
-
|
|
10436
|
-
try {
|
|
10437
|
-
return await platform.projects.get(projectId);
|
|
10438
|
-
} catch (error) {
|
|
10439
|
-
if (error instanceof PlatformError && error.status === 404) throw new Error(`Project ${projectId} not found in the active organization. Run \`keystroke project list\`, then \`keystroke config use project <id>\`.`);
|
|
10440
|
-
throw error;
|
|
10441
|
-
}
|
|
10510
|
+
async function fetchProjectInOrg(config, projectRef) {
|
|
10511
|
+
return resolveProjectRef(createCliPlatformClient(config), projectRef);
|
|
10442
10512
|
}
|
|
10443
10513
|
function assertProjectReadyForConfig(project) {
|
|
10444
|
-
|
|
10445
|
-
if (project.status === "
|
|
10514
|
+
const label = formatProjectLabel(project);
|
|
10515
|
+
if (project.status === "failed") throw new Error(project.lastError ? `Project ${label} deploy failed: ${project.lastError}` : `Project ${label} deploy failed`);
|
|
10516
|
+
if (project.status === "starting") throw new Error(`Project ${label} is still starting. Wait for deploy to finish, then run \`keystroke config use project ${label}\`.`);
|
|
10446
10517
|
}
|
|
10447
|
-
async function runConfigUseProject(config,
|
|
10448
|
-
const project = await fetchProjectInOrg(config,
|
|
10518
|
+
async function runConfigUseProject(config, projectRef) {
|
|
10519
|
+
const project = await fetchProjectInOrg(config, projectRef);
|
|
10449
10520
|
assertProjectReadyForConfig(project);
|
|
10450
|
-
config.set("activeProjectId",
|
|
10521
|
+
config.set("activeProjectId", project.id);
|
|
10451
10522
|
config.set("apiTarget", "platform");
|
|
10523
|
+
const label = formatProjectLabel(project);
|
|
10452
10524
|
return {
|
|
10453
|
-
stdout: project.status === "active" ? `Using platform project ${
|
|
10454
|
-
stderr: project.status === "inactive" ? `Project is not active yet. Deploy with: ${cliBinaryName()} deploy --project ${
|
|
10525
|
+
stdout: project.status === "active" ? `Using platform project ${label}\n` : `Using platform project ${label} (${project.status})\n`,
|
|
10526
|
+
stderr: project.status === "inactive" ? `Project is not active yet. Deploy with: ${cliBinaryName()} deploy --project ${label}\n` : void 0
|
|
10455
10527
|
};
|
|
10456
10528
|
}
|
|
10457
10529
|
//#endregion
|
|
@@ -10480,7 +10552,7 @@ function registerConfigCommand(program) {
|
|
|
10480
10552
|
return;
|
|
10481
10553
|
}
|
|
10482
10554
|
if (mode === "org") {
|
|
10483
|
-
const membership = await selectActiveOrganization(cliConfig, {
|
|
10555
|
+
const membership = await selectActiveOrganization(cliConfig, { organizationRef: id });
|
|
10484
10556
|
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
10485
10557
|
return;
|
|
10486
10558
|
}
|
|
@@ -10490,9 +10562,9 @@ function registerConfigCommand(program) {
|
|
|
10490
10562
|
process.stdout.write(activeProjectId ? `Using platform API (default project ${activeProjectId} for project-scoped commands)\n` : "Using platform API\n");
|
|
10491
10563
|
return;
|
|
10492
10564
|
}
|
|
10493
|
-
if (mode !== "project") throw new Error("Usage: keystroke config use [local|cloud|project [
|
|
10565
|
+
if (mode !== "project") throw new Error("Usage: keystroke config use [local|cloud|project [slug]|org [slug]]");
|
|
10494
10566
|
const targetProjectId = id ?? cliConfig.get("activeProjectId");
|
|
10495
|
-
if (!targetProjectId) throw new Error("Usage: keystroke config use project <
|
|
10567
|
+
if (!targetProjectId) throw new Error("Usage: keystroke config use project <slug>");
|
|
10496
10568
|
const result = await runConfigUseProject(cliConfig, targetProjectId);
|
|
10497
10569
|
process.stdout.write(result.stdout);
|
|
10498
10570
|
if (result.stderr) process.stderr.write(result.stderr);
|
|
@@ -10566,7 +10638,7 @@ async function syncSkills(command) {
|
|
|
10566
10638
|
//#endregion
|
|
10567
10639
|
//#region src/program.ts
|
|
10568
10640
|
function createProgram() {
|
|
10569
|
-
const program = new Command().name("keystroke").description("Build, run, and manage keystroke projects").version(readCliVersion()).option("--project <
|
|
10641
|
+
const program = new Command().name("keystroke").description("Build, run, and manage keystroke projects").version(readCliVersion()).option("--project <slug>", "Platform project slug (deploy target or one-off API target)").option("--local", "Force local keystroke server URL").hook("preAction", async (thisCommand, actionCommand) => {
|
|
10570
10642
|
const opts = thisCommand.opts();
|
|
10571
10643
|
setCliTargetOptions({
|
|
10572
10644
|
projectId: opts.project,
|