speqs 0.5.1 → 0.7.0

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.
Files changed (40) hide show
  1. package/dist/commands/config.js +13 -4
  2. package/dist/commands/iteration.js +64 -13
  3. package/dist/commands/simulation.d.ts +1 -1
  4. package/dist/commands/simulation.js +454 -121
  5. package/dist/commands/study.js +140 -27
  6. package/dist/commands/tester-profile.js +17 -4
  7. package/dist/commands/tester.js +12 -3
  8. package/dist/commands/workspace.js +51 -6
  9. package/dist/config.d.ts +2 -0
  10. package/dist/index.js +3 -1
  11. package/dist/lib/alias-store.d.ts +22 -3
  12. package/dist/lib/alias-store.js +60 -12
  13. package/dist/lib/api-client.d.ts +31 -0
  14. package/dist/lib/api-client.js +83 -27
  15. package/dist/lib/auth.js +4 -1
  16. package/dist/lib/command-helpers.d.ts +4 -0
  17. package/dist/lib/command-helpers.js +41 -4
  18. package/dist/lib/local-sim/actions.d.ts +22 -0
  19. package/dist/lib/local-sim/actions.js +379 -0
  20. package/dist/lib/local-sim/browser.d.ts +63 -0
  21. package/dist/lib/local-sim/browser.js +332 -0
  22. package/dist/lib/local-sim/debug-report.d.ts +21 -0
  23. package/dist/lib/local-sim/debug-report.js +186 -0
  24. package/dist/lib/local-sim/debug.d.ts +44 -0
  25. package/dist/lib/local-sim/debug.js +103 -0
  26. package/dist/lib/local-sim/install.d.ts +25 -0
  27. package/dist/lib/local-sim/install.js +72 -0
  28. package/dist/lib/local-sim/loop.d.ts +60 -0
  29. package/dist/lib/local-sim/loop.js +526 -0
  30. package/dist/lib/local-sim/types.d.ts +232 -0
  31. package/dist/lib/local-sim/types.js +8 -0
  32. package/dist/lib/local-sim/upload.d.ts +6 -0
  33. package/dist/lib/local-sim/upload.js +24 -0
  34. package/dist/lib/output.d.ts +16 -1
  35. package/dist/lib/output.js +250 -61
  36. package/dist/lib/types.d.ts +7 -30
  37. package/dist/lib/types.js +9 -1
  38. package/dist/lib/upload.d.ts +47 -0
  39. package/dist/lib/upload.js +178 -0
  40. package/package.json +3 -2
@@ -2,7 +2,7 @@
2
2
  * speqs config — Manage simulation configs.
3
3
  */
4
4
  import { withClient, readJsonFileOrStdin } from "../lib/command-helpers.js";
5
- import { resolveId } from "../lib/alias-store.js";
5
+ import { resolveId, tagAlias, ALIAS_PREFIX } from "../lib/alias-store.js";
6
6
  import { output, formatConfigList } from "../lib/output.js";
7
7
  export function registerConfigCommands(program) {
8
8
  const config = program
@@ -26,7 +26,10 @@ export function registerConfigCommands(program) {
26
26
  await withClient(cmd, async (client, globals) => {
27
27
  const body = await readJsonFileOrStdin(opts.file);
28
28
  const data = await client.post("/dev/simulation-configs", body);
29
- output(data, globals.json);
29
+ const result = data;
30
+ if (result.id)
31
+ result.alias = tagAlias(ALIAS_PREFIX.config, String(result.id));
32
+ output(result, globals.json);
30
33
  });
31
34
  });
32
35
  config
@@ -36,7 +39,10 @@ export function registerConfigCommands(program) {
36
39
  .action(async (id, _opts, cmd) => {
37
40
  await withClient(cmd, async (client, globals) => {
38
41
  const data = await client.get(`/dev/simulation-configs/${resolveId(id)}`);
39
- output(data, globals.json);
42
+ const result = data;
43
+ if (result.id)
44
+ result.alias = tagAlias(ALIAS_PREFIX.config, String(result.id));
45
+ output(result, globals.json);
40
46
  });
41
47
  });
42
48
  config
@@ -57,7 +63,10 @@ export function registerConfigCommands(program) {
57
63
  await withClient(cmd, async (client, globals) => {
58
64
  const body = await readJsonFileOrStdin(opts.file);
59
65
  const data = await client.put(`/dev/simulation-configs/${resolveId(id)}`, body);
60
- output(data, globals.json);
66
+ const result = data;
67
+ if (result.id)
68
+ result.alias = tagAlias(ALIAS_PREFIX.config, String(result.id));
69
+ output(result, globals.json);
61
70
  });
62
71
  });
63
72
  config
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * speqs iteration — Manage iterations (usually created via `simulation run`).
3
3
  */
4
- import { withClient } from "../lib/command-helpers.js";
5
- import { resolveId } from "../lib/alias-store.js";
4
+ import { withClient, resolveStudy } from "../lib/command-helpers.js";
5
+ import { resolveId, tagAlias, ALIAS_PREFIX } from "../lib/alias-store.js";
6
6
  import { output, formatIterationList } from "../lib/output.js";
7
7
  export function registerIterationCommands(program) {
8
8
  const iteration = program
@@ -11,40 +11,76 @@ export function registerIterationCommands(program) {
11
11
  iteration
12
12
  .command("list")
13
13
  .description("List iterations for a study")
14
- .requiredOption("--study <id>", "Study ID")
14
+ .option("--study <id>", "Study ID")
15
15
  .addHelpText("after", "\nExamples:\n $ speqs iteration list --study <id>\n $ speqs iteration list --study <id> --json")
16
16
  .action(async (opts, cmd) => {
17
17
  await withClient(cmd, async (client, globals) => {
18
- const data = await client.get(`/studies/${resolveId(opts.study)}/iterations`);
18
+ const data = await client.get(`/studies/${resolveStudy(opts.study)}/iterations`);
19
19
  formatIterationList(data, globals.json);
20
20
  });
21
21
  });
22
22
  iteration
23
23
  .command("create")
24
24
  .description("Create a new iteration (low-level)")
25
- .requiredOption("--study <id>", "Study ID")
25
+ .option("--study <id>", "Study ID")
26
26
  .requiredOption("--name <name>", "Iteration name")
27
27
  .option("--description <description>", "Iteration description")
28
28
  .option("--details-json <json>", "Iteration details as JSON string")
29
+ .addHelpText("after", `
30
+ Examples:
31
+ # Interactive:
32
+ $ speqs iteration create --study S --name "v1" \\
33
+ --details-json '{"type":"interactive","platform":"browser","url":"https://example.com","screen_format":"desktop"}'
34
+
35
+ # Text/email:
36
+ $ speqs iteration create --study S --name "v1" \\
37
+ --details-json '{"type":"text","content_text":"Your email content here","title":"Newsletter"}'
38
+
39
+ # Video:
40
+ $ speqs iteration create --study S --name "v1" \\
41
+ --details-json '{"type":"video","content_url":"https://cdn.example.com/video.mp4","mime_type":"video/mp4"}'
42
+
43
+ # Image:
44
+ $ speqs iteration create --study S --name "v1" \\
45
+ --details-json '{"type":"image","image_urls":["https://cdn.example.com/a.png","https://cdn.example.com/b.png"]}'
46
+
47
+ # Document (PDF):
48
+ $ speqs iteration create --study S --name "v1" \\
49
+ --details-json '{"type":"document","content_url":"https://cdn.example.com/report.pdf","mime_type":"application/pdf"}'
50
+
51
+ Note: For local file uploads, use \`speqs simulation run\` which automatically
52
+ uploads files and resolves URLs (e.g. --content-url ./video.mp4).`)
29
53
  .action(async (opts, cmd) => {
30
54
  await withClient(cmd, async (client, globals) => {
31
55
  const body = {
32
56
  name: opts.name,
33
- ...(opts.description && { description: opts.description }),
34
- ...(opts.detailsJson && { details: JSON.parse(opts.detailsJson) }),
57
+ ...(opts.description !== undefined && { description: opts.description }),
58
+ ...(opts.detailsJson && { details: (() => { try {
59
+ return JSON.parse(opts.detailsJson);
60
+ }
61
+ catch {
62
+ throw new Error("Invalid --details-json: expected valid JSON string");
63
+ } })() }),
35
64
  };
36
- const data = await client.post(`/studies/${resolveId(opts.study)}/iterations`, body);
37
- output(data, globals.json);
65
+ const data = await client.post(`/studies/${resolveStudy(opts.study)}/iterations`, body);
66
+ const result = data;
67
+ if (result.id)
68
+ result.alias = tagAlias(ALIAS_PREFIX.iteration, String(result.id));
69
+ output(result, globals.json);
38
70
  });
39
71
  });
40
72
  iteration
41
73
  .command("get")
42
74
  .description("Get iteration details")
43
75
  .argument("<id>", "Iteration ID")
76
+ .addHelpText("after", "\nExamples:\n $ speqs iteration get <id>\n $ speqs iteration get <id> --json")
44
77
  .action(async (id, _opts, cmd) => {
45
78
  await withClient(cmd, async (client, globals) => {
46
79
  const data = await client.get(`/iterations/${resolveId(id)}`);
47
- output(data, globals.json);
80
+ const result = data;
81
+ if (result.id)
82
+ result.alias = tagAlias(ALIAS_PREFIX.iteration, String(result.id));
83
+ output(result, globals.json);
48
84
  });
49
85
  });
50
86
  iteration
@@ -55,6 +91,7 @@ export function registerIterationCommands(program) {
55
91
  .option("--description <description>", "Iteration description")
56
92
  .option("--details-json <json>", "Iteration details as JSON string")
57
93
  .option("--label <label>", "Iteration label (uppercase letters)")
94
+ .addHelpText("after", "\nExamples:\n $ speqs iteration update <id> --name \"v2\"\n $ speqs iteration update <id> --label B --json")
58
95
  .action(async (id, opts, cmd) => {
59
96
  await withClient(cmd, async (client, globals) => {
60
97
  const body = {};
@@ -62,18 +99,32 @@ export function registerIterationCommands(program) {
62
99
  body.name = opts.name;
63
100
  if (opts.description !== undefined)
64
101
  body.description = opts.description;
65
- if (opts.detailsJson !== undefined)
66
- body.details = JSON.parse(opts.detailsJson);
102
+ if (opts.detailsJson !== undefined) {
103
+ try {
104
+ body.details = JSON.parse(opts.detailsJson);
105
+ }
106
+ catch {
107
+ throw new Error("Invalid --details-json: expected valid JSON string");
108
+ }
109
+ }
67
110
  if (opts.label !== undefined)
68
111
  body.label = opts.label;
112
+ if (Object.keys(body).length === 0) {
113
+ console.error("No update flags provided. Run `speqs iteration update --help` for options.");
114
+ return;
115
+ }
69
116
  const data = await client.put(`/iterations/${resolveId(id)}`, body);
70
- output(data, globals.json);
117
+ const result = data;
118
+ if (result.id)
119
+ result.alias = tagAlias(ALIAS_PREFIX.iteration, String(result.id));
120
+ output(result, globals.json);
71
121
  });
72
122
  });
73
123
  iteration
74
124
  .command("delete")
75
125
  .description("Delete an iteration")
76
126
  .argument("<id>", "Iteration ID")
127
+ .addHelpText("after", "\nExamples:\n $ speqs iteration delete <id>")
77
128
  .action(async (id, _opts, cmd) => {
78
129
  await withClient(cmd, async (client, globals) => {
79
130
  await client.del(`/iterations/${resolveId(id)}`);
@@ -4,7 +4,7 @@
4
4
  * Primary command: `speqs simulation run` — orchestrates the full flow:
5
5
  * 1. Creates iteration (if not provided)
6
6
  * 2. Creates testers from profiles
7
- * 3. Starts simulations
7
+ * 3. Starts simulations (interactive or media, based on study modality)
8
8
  */
9
9
  import type { Command } from "commander";
10
10
  export declare function registerSimulationCommands(program: Command): void;