@keystrokehq/cli 0.0.127 → 0.0.129
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 +102 -105
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2103,6 +2103,10 @@ const CreateProjectRequestSchema = object({
|
|
|
2103
2103
|
name: string().trim().min(1),
|
|
2104
2104
|
description: string().trim().min(1).optional()
|
|
2105
2105
|
});
|
|
2106
|
+
const UpdateProjectRequestSchema = object({
|
|
2107
|
+
name: string().trim().min(1).optional(),
|
|
2108
|
+
description: string().trim().optional()
|
|
2109
|
+
}).refine((data) => data.name !== void 0 || data.description !== void 0, { message: "At least one field is required" });
|
|
2106
2110
|
const CreateProjectResponseSchema = object({ project: ProjectSchema });
|
|
2107
2111
|
const ProjectResponseSchema = object({ project: ProjectSchema });
|
|
2108
2112
|
const ProjectReachabilityResponseSchema = object({ reachable: boolean() });
|
|
@@ -2670,6 +2674,25 @@ const WorkflowSummaryListResponseSchema = array(WorkflowSummarySchema);
|
|
|
2670
2674
|
const WorkflowSummaryDetailResponseSchema = WorkflowSummarySchema.nullable();
|
|
2671
2675
|
const SkillSummaryListResponseSchema = array(SkillSummarySchema);
|
|
2672
2676
|
const SkillSummaryDetailResponseSchema = SkillSummarySchema.nullable();
|
|
2677
|
+
const RecentResourceKindSchema = _enum([
|
|
2678
|
+
"agent",
|
|
2679
|
+
"workflow",
|
|
2680
|
+
"skill"
|
|
2681
|
+
]);
|
|
2682
|
+
const RecentResourceSourceSchema = _enum(["owned", "shared"]);
|
|
2683
|
+
const RecentResourceListResponseSchema = array(object({
|
|
2684
|
+
id: string().min(1),
|
|
2685
|
+
resourceKind: RecentResourceKindSchema,
|
|
2686
|
+
resourceId: string().min(1),
|
|
2687
|
+
name: string().min(1),
|
|
2688
|
+
description: string().optional(),
|
|
2689
|
+
projectId: string().min(1),
|
|
2690
|
+
projectName: string().min(1),
|
|
2691
|
+
sourcePath: string().min(1).optional(),
|
|
2692
|
+
source: RecentResourceSourceSchema,
|
|
2693
|
+
lastOpenedAt: string().min(1),
|
|
2694
|
+
lastModifiedAt: string().min(1)
|
|
2695
|
+
}));
|
|
2673
2696
|
const isoDateTime = string().datetime();
|
|
2674
2697
|
const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
|
|
2675
2698
|
/**
|
|
@@ -5096,16 +5119,22 @@ function createProjectsResource(http) {
|
|
|
5096
5119
|
throw await toPlatformError(error);
|
|
5097
5120
|
}
|
|
5098
5121
|
},
|
|
5099
|
-
update
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5122
|
+
async update(projectId, patch) {
|
|
5123
|
+
const body = UpdateProjectRequestSchema.parse(patch);
|
|
5124
|
+
try {
|
|
5125
|
+
const data = await http.patch(`/api/projects/${encodeURIComponent(projectId)}`, { json: body }).json();
|
|
5126
|
+
return ProjectResponseSchema.parse(data).project;
|
|
5127
|
+
} catch (error) {
|
|
5128
|
+
throw await toPlatformError(error);
|
|
5129
|
+
}
|
|
5130
|
+
},
|
|
5131
|
+
async delete(projectId) {
|
|
5132
|
+
try {
|
|
5133
|
+
await http.delete(`/api/projects/${encodeURIComponent(projectId)}`);
|
|
5134
|
+
} catch (error) {
|
|
5135
|
+
throw await toPlatformError(error);
|
|
5136
|
+
}
|
|
5137
|
+
},
|
|
5109
5138
|
async checkReachability(projectId) {
|
|
5110
5139
|
try {
|
|
5111
5140
|
const data = await http.get(`/api/projects/${encodeURIComponent(projectId)}/reachability`, { timeout: PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS }).json();
|
|
@@ -5176,6 +5205,16 @@ function createSkillsResource(http) {
|
|
|
5176
5205
|
}
|
|
5177
5206
|
};
|
|
5178
5207
|
}
|
|
5208
|
+
function createRecentsResource(http) {
|
|
5209
|
+
return { async list() {
|
|
5210
|
+
try {
|
|
5211
|
+
const data = await http.get("/api/recents").json();
|
|
5212
|
+
return RecentResourceListResponseSchema.parse(data);
|
|
5213
|
+
} catch (error) {
|
|
5214
|
+
throw await toPlatformError(error);
|
|
5215
|
+
}
|
|
5216
|
+
} };
|
|
5217
|
+
}
|
|
5179
5218
|
const DEFAULT_PROJECT_SETTINGS = {
|
|
5180
5219
|
description: "",
|
|
5181
5220
|
defaultRole: "editor",
|
|
@@ -6704,21 +6743,6 @@ const workflowSeed = [{
|
|
|
6704
6743
|
stepCount: 4,
|
|
6705
6744
|
lastRunAt: "2026-05-31T16:40:00Z"
|
|
6706
6745
|
}];
|
|
6707
|
-
const skillSeed = [{
|
|
6708
|
-
id: "skill-attio-sync",
|
|
6709
|
-
name: "Attio Sync",
|
|
6710
|
-
projectId: "project_personal_repo",
|
|
6711
|
-
updatedAt: "2026-06-01T18:05:00Z",
|
|
6712
|
-
description: "Enrich company and contact records from Attio.",
|
|
6713
|
-
sourcePath: ".agents/skills/attio-sync/SKILL.md"
|
|
6714
|
-
}, {
|
|
6715
|
-
id: "skill-doc-coauthor",
|
|
6716
|
-
name: "Doc Co-author",
|
|
6717
|
-
projectId: "project_personal_repo",
|
|
6718
|
-
updatedAt: "2026-05-30T10:24:00Z",
|
|
6719
|
-
description: "Collaborative writing, editing, and version tracking for docs.",
|
|
6720
|
-
sourcePath: ".agents/skills/doc-coauthor/SKILL.md"
|
|
6721
|
-
}];
|
|
6722
6746
|
const deploymentSeed = [{
|
|
6723
6747
|
id: "deployment-v002",
|
|
6724
6748
|
projectId: "project_personal_repo",
|
|
@@ -6814,75 +6838,6 @@ const apiKeySeed = [
|
|
|
6814
6838
|
}
|
|
6815
6839
|
];
|
|
6816
6840
|
let credentialRecords = [...credentialSeed];
|
|
6817
|
-
const recentProjectNameById = { project_personal_repo: "Blake's Project" };
|
|
6818
|
-
function laterIso(a, b) {
|
|
6819
|
-
return new Date(a).getTime() >= new Date(b).getTime() ? a : b;
|
|
6820
|
-
}
|
|
6821
|
-
function hoursBefore(iso, hours) {
|
|
6822
|
-
return (/* @__PURE__ */ new Date(new Date(iso).getTime() - hours * 36e5)).toISOString();
|
|
6823
|
-
}
|
|
6824
|
-
function buildRecentResourceSeed() {
|
|
6825
|
-
const agentRecents = agentSeed.map((agent, index) => {
|
|
6826
|
-
const lastModifiedAt = agent.updatedAt;
|
|
6827
|
-
const lastOpenedAt = hoursBefore(lastModifiedAt, index * 5 + 2);
|
|
6828
|
-
return {
|
|
6829
|
-
id: `recent-agent-${agent.id}`,
|
|
6830
|
-
resourceKind: "agent",
|
|
6831
|
-
resourceId: agent.id,
|
|
6832
|
-
name: agent.name,
|
|
6833
|
-
description: agent.description,
|
|
6834
|
-
projectId: agent.projectId,
|
|
6835
|
-
projectName: recentProjectNameById[agent.projectId] ?? agent.projectId,
|
|
6836
|
-
sourcePath: agent.sourcePath,
|
|
6837
|
-
source: "owned",
|
|
6838
|
-
lastOpenedAt,
|
|
6839
|
-
lastModifiedAt
|
|
6840
|
-
};
|
|
6841
|
-
});
|
|
6842
|
-
const workflowRecents = workflowSeed.map((workflow, index) => {
|
|
6843
|
-
const lastModifiedAt = workflow.updatedAt;
|
|
6844
|
-
const lastOpenedAt = hoursBefore(lastModifiedAt, index * 4 + 6);
|
|
6845
|
-
return {
|
|
6846
|
-
id: `recent-workflow-${workflow.id}`,
|
|
6847
|
-
resourceKind: "workflow",
|
|
6848
|
-
resourceId: workflow.id,
|
|
6849
|
-
name: workflow.name,
|
|
6850
|
-
description: workflow.description,
|
|
6851
|
-
projectId: workflow.projectId,
|
|
6852
|
-
projectName: recentProjectNameById[workflow.projectId] ?? workflow.projectId,
|
|
6853
|
-
sourcePath: workflow.sourcePath,
|
|
6854
|
-
source: "owned",
|
|
6855
|
-
lastOpenedAt,
|
|
6856
|
-
lastModifiedAt
|
|
6857
|
-
};
|
|
6858
|
-
});
|
|
6859
|
-
const skillRecents = skillSeed.map((skill, index) => {
|
|
6860
|
-
const lastModifiedAt = skill.updatedAt;
|
|
6861
|
-
const lastOpenedAt = hoursBefore(lastModifiedAt, index * 3 + 1);
|
|
6862
|
-
return {
|
|
6863
|
-
id: `recent-skill-${skill.id}`,
|
|
6864
|
-
resourceKind: "skill",
|
|
6865
|
-
resourceId: skill.id,
|
|
6866
|
-
name: skill.name,
|
|
6867
|
-
description: skill.description,
|
|
6868
|
-
projectId: skill.projectId,
|
|
6869
|
-
projectName: recentProjectNameById[skill.projectId] ?? skill.projectId,
|
|
6870
|
-
sourcePath: skill.sourcePath,
|
|
6871
|
-
source: "owned",
|
|
6872
|
-
lastOpenedAt,
|
|
6873
|
-
lastModifiedAt
|
|
6874
|
-
};
|
|
6875
|
-
});
|
|
6876
|
-
return [
|
|
6877
|
-
...agentRecents,
|
|
6878
|
-
...workflowRecents,
|
|
6879
|
-
...skillRecents
|
|
6880
|
-
].sort((left, right) => {
|
|
6881
|
-
const leftAt = laterIso(left.lastOpenedAt, left.lastModifiedAt);
|
|
6882
|
-
const rightAt = laterIso(right.lastOpenedAt, right.lastModifiedAt);
|
|
6883
|
-
return new Date(rightAt).getTime() - new Date(leftAt).getTime();
|
|
6884
|
-
});
|
|
6885
|
-
}
|
|
6886
6841
|
function createMockApiKeySecret() {
|
|
6887
6842
|
const secret = `sk_${`${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`}`;
|
|
6888
6843
|
return {
|
|
@@ -7106,13 +7061,6 @@ function createApiKeysResource() {
|
|
|
7106
7061
|
})
|
|
7107
7062
|
};
|
|
7108
7063
|
}
|
|
7109
|
-
function createRecentsResource() {
|
|
7110
|
-
return { list: mock({
|
|
7111
|
-
domain: "recents",
|
|
7112
|
-
method: "list",
|
|
7113
|
-
plannedEndpoint: "GET /api/recents"
|
|
7114
|
-
}, async () => buildRecentResourceSeed()) };
|
|
7115
|
-
}
|
|
7116
7064
|
const historyProjectNameById = { project_personal_repo: "Blake's Project" };
|
|
7117
7065
|
const MOCK_ACTOR = {
|
|
7118
7066
|
userId: "user_blake",
|
|
@@ -8633,7 +8581,7 @@ function createPlatformClient(options) {
|
|
|
8633
8581
|
members: createMembersResource(http),
|
|
8634
8582
|
invitations: createInvitationsResource(http),
|
|
8635
8583
|
apiKeys: createApiKeysResource(),
|
|
8636
|
-
recents: createRecentsResource(),
|
|
8584
|
+
recents: createRecentsResource(http),
|
|
8637
8585
|
userPreferences: createUserPreferencesResource({ getCurrentUserId: options.getCurrentUserId }),
|
|
8638
8586
|
userAvatar: createUserAvatarResource(http),
|
|
8639
8587
|
organizationSidebarBranding: createOrganizationSidebarBrandingResource({ getActiveOrganizationId: () => activeOrganizationId }),
|
|
@@ -8833,6 +8781,9 @@ function setCliTargetOptions(options) {
|
|
|
8833
8781
|
function getCliTargetOptions() {
|
|
8834
8782
|
return targetOptions;
|
|
8835
8783
|
}
|
|
8784
|
+
function resolveActiveProjectId(config) {
|
|
8785
|
+
return getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
8786
|
+
}
|
|
8836
8787
|
//#endregion
|
|
8837
8788
|
//#region src/errors/example-input.ts
|
|
8838
8789
|
function exampleValueFromValidationMessage(message) {
|
|
@@ -9632,8 +9583,7 @@ async function runDeploy(options) {
|
|
|
9632
9583
|
function registerDeployCommand(program) {
|
|
9633
9584
|
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) => {
|
|
9634
9585
|
try {
|
|
9635
|
-
const
|
|
9636
|
-
const projectId = getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
9586
|
+
const projectId = resolveActiveProjectId(createCliConfig());
|
|
9637
9587
|
if (!projectId) throw new Error("Usage: keystroke deploy --project <id>");
|
|
9638
9588
|
await runDeploy({
|
|
9639
9589
|
dir: options.dir,
|
|
@@ -10216,10 +10166,23 @@ async function runProjectCreate(config, input) {
|
|
|
10216
10166
|
writeInactiveDeployHints([project]);
|
|
10217
10167
|
});
|
|
10218
10168
|
}
|
|
10169
|
+
async function runProjectUpdate(config, input) {
|
|
10170
|
+
await withActivePlatformClient(config, async (platform) => {
|
|
10171
|
+
const { projectId, ...patch } = input;
|
|
10172
|
+
const project = await platform.projects.update(projectId, patch);
|
|
10173
|
+
process.stdout.write(`${JSON.stringify({ project }, null, 2)}\n`);
|
|
10174
|
+
});
|
|
10175
|
+
}
|
|
10176
|
+
async function runProjectDelete(config, projectId) {
|
|
10177
|
+
await withActivePlatformClient(config, async (platform) => {
|
|
10178
|
+
await platform.projects.delete(projectId);
|
|
10179
|
+
process.stdout.write(`${JSON.stringify({ deleted: projectId }, null, 2)}\n`);
|
|
10180
|
+
});
|
|
10181
|
+
}
|
|
10219
10182
|
//#endregion
|
|
10220
10183
|
//#region src/commands/project/index.ts
|
|
10221
10184
|
function registerProjectCommand(program) {
|
|
10222
|
-
const project = program.command("project").description("List and
|
|
10185
|
+
const project = program.command("project").description("List, create, update, and delete platform projects");
|
|
10223
10186
|
project.command("list").description("List projects in the active organization").action(async () => {
|
|
10224
10187
|
const config = createCliConfig();
|
|
10225
10188
|
try {
|
|
@@ -10247,6 +10210,40 @@ function registerProjectCommand(program) {
|
|
|
10247
10210
|
process.exitCode = 1;
|
|
10248
10211
|
}
|
|
10249
10212
|
});
|
|
10213
|
+
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) => {
|
|
10214
|
+
const config = createCliConfig();
|
|
10215
|
+
try {
|
|
10216
|
+
const projectId = resolveActiveProjectId(config);
|
|
10217
|
+
if (!projectId) throw new Error("Usage: keystroke --project <id> project update --name <name>");
|
|
10218
|
+
if (!options.name && options.description === void 0) throw new Error("At least one of --name or --description is required");
|
|
10219
|
+
await runProjectUpdate(config, {
|
|
10220
|
+
projectId,
|
|
10221
|
+
...options.name ? { name: options.name } : {},
|
|
10222
|
+
...options.description !== void 0 ? { description: options.description } : {}
|
|
10223
|
+
});
|
|
10224
|
+
} catch (error) {
|
|
10225
|
+
process.stderr.write(`${formatCliError(error, "Update project failed", {
|
|
10226
|
+
serverUrl: getPlatformUrl(config),
|
|
10227
|
+
webUrl: getWebUrl(config)
|
|
10228
|
+
})}\n`);
|
|
10229
|
+
process.exitCode = 1;
|
|
10230
|
+
}
|
|
10231
|
+
});
|
|
10232
|
+
project.command("delete").description("Delete a platform project").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
10233
|
+
const config = createCliConfig();
|
|
10234
|
+
try {
|
|
10235
|
+
const projectId = resolveActiveProjectId(config);
|
|
10236
|
+
if (!projectId) throw new Error("Usage: keystroke --project <id> project delete");
|
|
10237
|
+
if (!options.yes) throw new Error("Pass --yes to confirm project deletion");
|
|
10238
|
+
await runProjectDelete(config, projectId);
|
|
10239
|
+
} catch (error) {
|
|
10240
|
+
process.stderr.write(`${formatCliError(error, "Delete project failed", {
|
|
10241
|
+
serverUrl: getPlatformUrl(config),
|
|
10242
|
+
webUrl: getWebUrl(config)
|
|
10243
|
+
})}\n`);
|
|
10244
|
+
process.exitCode = 1;
|
|
10245
|
+
}
|
|
10246
|
+
});
|
|
10250
10247
|
}
|
|
10251
10248
|
//#endregion
|
|
10252
10249
|
//#region src/commands/start.ts
|