@rigkit/engine 0.2.4 → 0.2.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigkit/engine",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -274,6 +274,37 @@ describe("DevMachineEngine workflow runtime", () => {
274
274
  expect(status).toEqual({ workspace: "created", vmId: "vm-2" });
275
275
  });
276
276
 
277
+ test("rejects workspace names that are not shell-safe", async () => {
278
+ const projectDir = mkdtempSync(join(tmpdir(), "rigkit-"));
279
+ writeFileSync(
280
+ join(projectDir, "rig.config.ts"),
281
+ `
282
+ import { defineConfig, sequence } from "${import.meta.dir}/index.ts";
283
+
284
+ const root = sequence("workspace-names")
285
+ .step("ready", async () => ({ ctx: { ready: true } }))
286
+ .workspace({
287
+ create: async ({ workspace }) => ({ name: workspace.name }),
288
+ remove: async () => {},
289
+ });
290
+
291
+ export default defineConfig({
292
+ providers: {},
293
+ workflows: { root },
294
+ });
295
+ `,
296
+ );
297
+
298
+ const engine = await createDevMachineEngine({ projectDir });
299
+ await engine.load();
300
+
301
+ await expect(engine.fork({ name: "" })).rejects.toThrow("create requires a workspace name");
302
+ for (const name of ["some workspace", "some/workspace", "-workspace"]) {
303
+ await expect(engine.fork({ name })).rejects.toThrow("Workspace name");
304
+ }
305
+ expect(engine.listWorkspaces()).toEqual([]);
306
+ });
307
+
277
308
  test("loads multiple workflows from defineConfig", async () => {
278
309
  const projectDir = mkdtempSync(join(tmpdir(), "rigkit-"));
279
310
  writeFileSync(
package/src/engine.ts CHANGED
@@ -727,7 +727,7 @@ export class DevMachineEngine {
727
727
  }
728
728
 
729
729
  async createWorkspace(input: { workflow?: string; machine?: string; name: string }): Promise<WorkspaceRecord> {
730
- if (!input.name) throw new Error(`create requires a workspace name`);
730
+ assertValidWorkspaceName(input.name);
731
731
  if (this.getStateService().getWorkspace(input.name)) {
732
732
  throw new Error(`Workspace ${input.name} already exists`);
733
733
  }
@@ -1544,6 +1544,17 @@ function parseWorkspaceOperationId(value: string): { workspace: string; operatio
1544
1544
  };
1545
1545
  }
1546
1546
 
1547
+ const workspaceNamePattern = /^(?!-)[A-Za-z0-9._-]+$/;
1548
+
1549
+ function assertValidWorkspaceName(value: string): void {
1550
+ if (!value) throw new Error(`create requires a workspace name`);
1551
+ if (!workspaceNamePattern.test(value)) {
1552
+ throw new Error(
1553
+ `Workspace name "${value}" is invalid. Use only letters, numbers, ".", "_", and "-", and do not start with "-".`,
1554
+ );
1555
+ }
1556
+ }
1557
+
1547
1558
  async function resolveProviderDefinition(
1548
1559
  definition: WorkflowDefinition<any, any>["providers"][string],
1549
1560
  ): Promise<LoadedProviderDefinition> {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const RIGKIT_ENGINE_VERSION = "0.2.4";
1
+ export const RIGKIT_ENGINE_VERSION = "0.2.5";