superlab 0.1.48 → 0.1.49

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/bin/superlab.cjs CHANGED
@@ -39,7 +39,8 @@ Usage:
39
39
  superlab init [--target <dir>] [--platform codex|claude|both|all] [--lang en|zh] [--force]
40
40
  superlab install [--target <dir>] [--platform codex|claude|both|all] [--lang en|zh] [--force]
41
41
  superlab paper attach-template --path <dir> [--target <dir>]
42
- superlab auto start [--target <dir>] [--objective <text>] [--campaign-kind <kind>] [--allowed-stages <csv>] [--autonomy-level <L1|L2|L3>]
42
+ superlab auto start [--target <dir>] [--campaign-kind <kind>] [--allowed-stages <csv>] [--autonomy-level <L1|L2|L3>|--l1|--l2|--l3] [--objective <text>|<objective>]
43
+ superlab auto experiment [--target <dir>] [--l1|--l2|--l3] <objective>
43
44
  superlab auto status [--target <dir>]
44
45
  superlab auto stop [--target <dir>]
45
46
  superlab update [--target <dir>]
@@ -219,7 +220,7 @@ function parsePaperArgs(argv) {
219
220
 
220
221
  function parseAutoArgs(argv) {
221
222
  const [action, ...rest] = argv;
222
- if (!["start", "status", "stop"].includes(action || "")) {
223
+ if (!["start", "status", "stop", "experiment"].includes(action || "")) {
223
224
  throw new Error(`Unknown auto action: ${action || "(missing)"}`);
224
225
  }
225
226
  const options = {
@@ -230,13 +231,14 @@ function parseAutoArgs(argv) {
230
231
  requestedAllowedStages: "",
231
232
  requestedAutonomyLevel: "",
232
233
  };
234
+ const positionalObjectiveParts = [];
233
235
 
234
236
  for (let index = 0; index < rest.length; index += 1) {
235
237
  const value = rest[index];
236
238
  if (value === "--target") {
237
239
  options.targetDir = path.resolve(rest[index + 1]);
238
240
  index += 1;
239
- } else if (action === "start" && value === "--objective") {
241
+ } else if ((action === "start" || action === "experiment") && value === "--objective") {
240
242
  options.requestedObjective = rest[index + 1] || "";
241
243
  index += 1;
242
244
  } else if (action === "start" && value === "--campaign-kind") {
@@ -245,14 +247,25 @@ function parseAutoArgs(argv) {
245
247
  } else if (action === "start" && value === "--allowed-stages") {
246
248
  options.requestedAllowedStages = rest[index + 1] || "";
247
249
  index += 1;
248
- } else if (action === "start" && value === "--autonomy-level") {
250
+ } else if ((action === "start" || action === "experiment") && value === "--autonomy-level") {
249
251
  options.requestedAutonomyLevel = (rest[index + 1] || "").trim();
250
252
  index += 1;
253
+ } else if ((action === "start" || action === "experiment") && ["--l1", "--l2", "--l3"].includes(value)) {
254
+ options.requestedAutonomyLevel = value.slice(2).toUpperCase();
255
+ } else if (action === "start" || action === "experiment") {
256
+ positionalObjectiveParts.push(value);
251
257
  } else {
252
258
  throw new Error(`Unknown option: ${value}`);
253
259
  }
254
260
  }
255
261
 
262
+ if (!options.requestedObjective && positionalObjectiveParts.length > 0) {
263
+ options.requestedObjective = positionalObjectiveParts.join(" ").trim();
264
+ }
265
+ if (action === "experiment" && !options.requestedCampaignKind) {
266
+ options.requestedCampaignKind = "experiment-loop";
267
+ }
268
+
256
269
  return options;
257
270
  }
258
271
 
@@ -990,7 +1003,7 @@ async function main() {
990
1003
  printAutoStatus(options);
991
1004
  return;
992
1005
  }
993
- if (options.action === "start") {
1006
+ if (options.action === "start" || options.action === "experiment") {
994
1007
  const result = await startAutoMode({
995
1008
  targetDir: options.targetDir,
996
1009
  requestedContract: {
@@ -23,6 +23,12 @@ const AUTO_LEVEL_STAGE_ENVELOPES = {
23
23
  };
24
24
  const VALID_APPROVAL_STATUSES = new Set(["draft", "approved"]);
25
25
  const VALID_TERMINAL_GOAL_TYPES = new Set(["rounds", "metric-threshold", "task-completion"]);
26
+ const CAMPAIGN_KIND_DEFAULT_STAGES = {
27
+ planning: ["idea", "data", "framing", "spec", "review", "report"],
28
+ spec: ["idea", "data", "framing", "spec", "review", "report"],
29
+ "experiment-loop": ["run", "iterate", "review", "report"],
30
+ "report-polish": ["review", "report", "write"],
31
+ };
26
32
  const FROZEN_CORE_ALIASES = {
27
33
  mission: [path.join(".lab", "context", "mission.md")],
28
34
  framing: [
@@ -82,19 +88,23 @@ function inferCampaignKind({ campaignKind = "", allowedStages = [] }) {
82
88
  }
83
89
 
84
90
  function normalizeRequestedAutoContract(requested = {}) {
85
- const allowedStages = Array.isArray(requested.allowedStages)
91
+ const rawAllowedStages = Array.isArray(requested.allowedStages)
86
92
  ? requested.allowedStages.map((stage) => String(stage).trim().toLowerCase()).filter(Boolean)
87
93
  : normalizeList(requested.allowedStages || "").map((stage) => stage.toLowerCase());
94
+ const normalizedCampaignKind =
95
+ isMeaningful(requested.campaignKind || "") || rawAllowedStages.length > 0
96
+ ? inferCampaignKind({
97
+ campaignKind: requested.campaignKind || "",
98
+ allowedStages: rawAllowedStages,
99
+ })
100
+ : "";
101
+ const allowedStages = rawAllowedStages.length > 0
102
+ ? rawAllowedStages
103
+ : [...(CAMPAIGN_KIND_DEFAULT_STAGES[normalizedCampaignKind] || [])];
88
104
  return {
89
105
  objective: (requested.objective || "").trim(),
90
106
  autonomyLevel: normalizeScalar(requested.autonomyLevel || ""),
91
- campaignKind:
92
- isMeaningful(requested.campaignKind || "") || allowedStages.length > 0
93
- ? inferCampaignKind({
94
- campaignKind: requested.campaignKind || "",
95
- allowedStages,
96
- })
97
- : "",
107
+ campaignKind: normalizedCampaignKind,
98
108
  allowedStages,
99
109
  };
100
110
  }
@@ -539,6 +549,7 @@ module.exports = {
539
549
  REVIEW_CONTEXT_FILES,
540
550
  VALID_APPROVAL_STATUSES,
541
551
  VALID_TERMINAL_GOAL_TYPES,
552
+ CAMPAIGN_KIND_DEFAULT_STAGES,
542
553
  classifyAutoContractFit,
543
554
  changedSnapshotPaths,
544
555
  detectFrozenCoreChanges,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlab",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "description": "Strict /lab research workflow installer for Codex and Claude",
5
5
  "keywords": [
6
6
  "codex",