@forloop-cc/forloop-cli 0.2.11 → 0.2.13

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/ERRORS.md CHANGED
@@ -44,33 +44,33 @@ No error scenarios — silently clears the token.
44
44
 
45
45
  ## Sprint Commands
46
46
 
47
- ### `forloop sprint get`
47
+ ### `forloop space-sprint get`
48
48
 
49
49
  | Scenario | Error Message |
50
50
  |---|---|
51
51
  | No sprint ID resolved | `Error: No sprint ID resolved. Use --id, set FORLOOP_SPRINT_ID, or use a sprint-XXX branch.` |
52
52
  | Sprint not found (404) | `ForLoop API GET /api/opencode/sprints/<id> failed: 404 Not Found` |
53
53
 
54
- ### `forloop sprint list`
54
+ ### `forloop space-sprint list`
55
55
 
56
56
  | Scenario | Error Message |
57
57
  |---|---|
58
58
  | No sprints found | `No sprints found.` |
59
59
 
60
- ### `forloop sprint create`
60
+ ### `forloop space-sprint create`
61
61
 
62
62
  | Scenario | Error Message |
63
63
  |---|---|
64
64
  | Missing `--title`, `--start-date`, or `--end-date` | `Error: --title, --start-date, and --end-date are required` |
65
65
 
66
- ### `forloop sprint update`
66
+ ### `forloop space-sprint update`
67
67
 
68
68
  | Scenario | Error Message |
69
69
  |---|---|
70
70
  | `--id` not provided | `Error: --id is required` |
71
71
  | No fields to update | `Error: at least one field to update is required` |
72
72
 
73
- ### `forloop sprint delete`
73
+ ### `forloop space-sprint delete`
74
74
 
75
75
  | Scenario | Error Message |
76
76
  |---|---|
package/README.md CHANGED
@@ -83,10 +83,10 @@ In about 30 seconds, you'll be connected:
83
83
  forloop auth login --api-key floop_xxxxx
84
84
 
85
85
  # 3. See your sprints
86
- forloop sprint list
86
+ forloop space-sprint list
87
87
 
88
88
  # 4. Dive into a sprint
89
- forloop sprint get --id 66
89
+ forloop space-sprint get --id 66
90
90
 
91
91
  # 5. Check what your AI agents are doing
92
92
  forloop agent developer-status --sprint 66
@@ -138,19 +138,19 @@ Work with sprints — the containers that hold your stories and track developmen
138
138
 
139
139
  ```bash
140
140
  # List all sprints you have access to
141
- forloop sprint list
142
- forloop sprint list --org-id 1
143
- forloop sprint list --include-system-org # Include system organization sprints
144
- forloop sprint list --output json # Structured JSON output
141
+ forloop space-sprint list
142
+ forloop space-sprint list --org-id 1
143
+ forloop space-sprint list --include-system-org # Include system organization sprints
144
+ forloop space-sprint list --output json # Structured JSON output
145
145
 
146
146
  # Get sprint details, including all stories
147
- forloop sprint get --id 66
148
- forloop sprint get --id 66 --no-stories # Exclude stories
149
- forloop sprint get --id 66 --no-files # Exclude files
150
- forloop sprint get --id 66 --output json # Structured JSON output
147
+ forloop space-sprint get --id 66
148
+ forloop space-sprint get --id 66 --no-stories # Exclude stories
149
+ forloop space-sprint get --id 66 --no-files # Exclude files
150
+ forloop space-sprint get --id 66 --output json # Structured JSON output
151
151
 
152
152
  # Create a new sprint
153
- forloop sprint create \
153
+ forloop space-sprint create \
154
154
  --title "Sprint 15" \
155
155
  --start-date 2026-06-09 \
156
156
  --end-date 2026-06-23 \
@@ -158,11 +158,11 @@ forloop sprint create \
158
158
  --org-id 1
159
159
 
160
160
  # Update sprint details
161
- forloop sprint update --id 66 --title "Updated Title"
162
- forloop sprint update --id 66 --description "New goals for this sprint"
161
+ forloop space-sprint update --id 66 --title "Updated Title"
162
+ forloop space-sprint update --id 66 --description "New goals for this sprint"
163
163
 
164
164
  # Delete a sprint (destructive — requires --confirm)
165
- forloop sprint delete --id 66 --confirm
165
+ forloop space-sprint delete --id 66 --confirm
166
166
  ```
167
167
 
168
168
  > **Tip:** The CLI auto-detects your sprint from `FORLOOP_SPRINT_ID` env var or a git branch named `sprint-66`. You can often omit `--id` and the right sprint will be chosen.
@@ -381,10 +381,10 @@ A typical session start — load context, check progress, and understand what's
381
381
  forloop auth status
382
382
 
383
383
  # 2. Find your sprint
384
- forloop sprint list
384
+ forloop space-sprint list
385
385
 
386
386
  # 3. Load the full picture — stories, status, AI agents
387
- forloop sprint get --id 66
387
+ forloop space-sprint get --id 66
388
388
 
389
389
  # 4. Is the developer agent already running?
390
390
  forloop agent developer-status --sprint 66
@@ -402,7 +402,7 @@ Create a sprint, add stories, and let AI agents implement them.
402
402
 
403
403
  ```bash
404
404
  # 1. Create the sprint
405
- forloop sprint create \
405
+ forloop space-sprint create \
406
406
  --title "Feature X" \
407
407
  --start-date 2026-06-09 \
408
408
  --end-date 2026-06-23
@@ -429,7 +429,7 @@ forloop agent developer-sprint --sprint 67
429
429
 
430
430
  # 5. Monitor progress
431
431
  forloop agent developer-status --sprint 67
432
- forloop sprint get --id 67
432
+ forloop space-sprint get --id 67
433
433
  ```
434
434
 
435
435
  ### Sync Files Between Local and S3
@@ -545,7 +545,7 @@ Tokens must start with `floop_`. Double-check you copied the entire token from h
545
545
  ### "Forbidden" or "Not Found" on Specific Resources
546
546
 
547
547
  Some resources (organizations, stories, files) return 403/404 when you don't have access or they don't exist in your current environment. Try:
548
- - Verifying the resource ID exists with `forloop sprint get --id <id>`
548
+ - Verifying the resource ID exists with `forloop space-sprint get --id <id>`
549
549
  - Checking your token has the required scopes
550
550
 
551
551
  ### Verbose Debugging
@@ -553,7 +553,7 @@ Some resources (organizations, stories, files) return 403/404 when you don't hav
553
553
  When something isn't working, use `--verbose` to see the raw HTTP requests:
554
554
 
555
555
  ```bash
556
- forloop sprint get --id 66 --verbose
556
+ forloop space-sprint get --id 66 --verbose
557
557
  # Output:
558
558
  # > GET https://api.forloop.cc/api/opencode/sprints/66
559
559
  # < 200 OK
package/dist/forloop CHANGED
@@ -142,7 +142,7 @@ var GLOBAL_OPTIONS = [
142
142
  { flag: "--version", description: "Print version" }
143
143
  ];
144
144
 
145
- // node_modules/@forloop-cc/forloop-opencode-plugin-planner/plugins/capabilities/token-storage.ts
145
+ // ../forloop-opencode-plugin-planner/plugins/capabilities/token-storage.ts
146
146
  import { promises as fs } from "fs";
147
147
  import path from "path";
148
148
  var getTokenPath = () => {
@@ -216,7 +216,7 @@ async function clearToken(profile) {
216
216
  await saveTokens(tokens);
217
217
  }
218
218
 
219
- // node_modules/@forloop-cc/forloop-opencode-plugin-planner/plugins/capabilities/config.ts
219
+ // ../forloop-opencode-plugin-planner/plugins/capabilities/config.ts
220
220
  import fs2 from "fs";
221
221
  import path2 from "path";
222
222
  var PROD_API_URL = "https://api.forloop.cc";
@@ -339,7 +339,7 @@ var isLambdaExecution = () => {
339
339
  return !!(process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.AWS_EXECUTION_ENV || process.env.LAMBDA_TASK_ROOT);
340
340
  };
341
341
 
342
- // node_modules/@forloop-cc/forloop-opencode-plugin-planner/plugins/capabilities/auth.ts
342
+ // ../forloop-opencode-plugin-planner/plugins/capabilities/auth.ts
343
343
  function detectTokenType(token) {
344
344
  if (!token) return null;
345
345
  if (token.startsWith("floop_")) {
@@ -390,7 +390,7 @@ async function validateToken(providedToken) {
390
390
  };
391
391
  }
392
392
 
393
- // node_modules/@forloop-cc/forloop-opencode-plugin-planner/plugins/capabilities/api-client.ts
393
+ // ../forloop-opencode-plugin-planner/plugins/capabilities/api-client.ts
394
394
  var APIError = class extends Error {
395
395
  constructor(code, message, status) {
396
396
  super(message);
@@ -539,6 +539,9 @@ var ForLoopAPIClient = class {
539
539
  includeStories: options?.includeStories !== false ? "true" : "false",
540
540
  includeFiles: options?.includeFiles !== false ? "true" : "false"
541
541
  });
542
+ if (options?.allStories) query.set("allStories", "true");
543
+ if (options?.subSprintId) query.set("subSprintId", String(options.subSprintId));
544
+ if (options?.includeSubSprints) query.set("includeSubSprints", "true");
542
545
  return this.request(`/api/opencode/sprints/${id}?${query}`);
543
546
  }
544
547
  async createSprint(data) {
@@ -581,6 +584,39 @@ var ForLoopAPIClient = class {
581
584
  method: "DELETE"
582
585
  });
583
586
  }
587
+ async getSubSprints(sprintId) {
588
+ return this.request(`/api/opencode/sprints/${sprintId}/sub-sprints`);
589
+ }
590
+ async createSubSprint(sprintId, data) {
591
+ return this.request(`/api/opencode/sprints/${sprintId}/sub-sprints`, {
592
+ method: "POST",
593
+ body: JSON.stringify(data)
594
+ });
595
+ }
596
+ async updateSubSprint(subSprintId, data) {
597
+ return this.request(`/api/opencode/sub-sprints/${subSprintId}`, {
598
+ method: "PUT",
599
+ body: JSON.stringify(data)
600
+ });
601
+ }
602
+ async deleteSubSprint(subSprintId) {
603
+ await this.request(`/api/opencode/sub-sprints/${subSprintId}`, {
604
+ method: "DELETE"
605
+ });
606
+ }
607
+ async addStoryComment(storyId, body, authorAgentKey) {
608
+ const payload = { body };
609
+ if (authorAgentKey) payload.authorAgentKey = authorAgentKey;
610
+ return this.request(`/api/opencode/stories/${storyId}/comments`, {
611
+ method: "POST",
612
+ body: JSON.stringify(payload)
613
+ });
614
+ }
615
+ async summarizeConversation(sprintId) {
616
+ return this.request(`/api/opencode/sprints/${sprintId}/summarize`, {
617
+ method: "POST"
618
+ });
619
+ }
584
620
  async listTemplates() {
585
621
  return this.request("/api/opencode/templates");
586
622
  }
@@ -722,6 +758,10 @@ var ForLoopAPIClient = class {
722
758
  metadata: data
723
759
  });
724
760
  }
761
+ /**
762
+ * @deprecated Use writeConversationEvent() for new integrations.
763
+ * Kept for backward compatibility with existing plugin hooks.
764
+ */
725
765
  async recordMessage(data) {
726
766
  return this.request("/api/opencode/messages", {
727
767
  method: "POST",
@@ -734,6 +774,12 @@ var ForLoopAPIClient = class {
734
774
  body: JSON.stringify({ sprintId, sessionId })
735
775
  });
736
776
  }
777
+ async writeConversationEvent(data) {
778
+ return this.request("/api/opencode/conversations/events", {
779
+ method: "POST",
780
+ body: JSON.stringify(data)
781
+ });
782
+ }
737
783
  async sendStreamChunk(data) {
738
784
  return this.request("/api/opencode/agents/stream", {
739
785
  method: "POST",
@@ -742,7 +788,7 @@ var ForLoopAPIClient = class {
742
788
  }
743
789
  };
744
790
 
745
- // node_modules/@forloop-cc/forloop-opencode-plugin-planner/plugins/capabilities/context-resolver.ts
791
+ // ../forloop-opencode-plugin-planner/plugins/capabilities/context-resolver.ts
746
792
  import { exec } from "child_process";
747
793
  import { promisify } from "util";
748
794
  import * as fs3 from "fs";
@@ -1088,11 +1134,15 @@ function createStoryDeleteCommand() {
1088
1134
  // src/commands/sprint.ts
1089
1135
  function createSprintCommands() {
1090
1136
  return {
1091
- "sprint get": createSprintGetCommand(),
1092
- "sprint list": createSprintListCommand(),
1093
- "sprint create": createSprintCreateCommand(),
1094
- "sprint update": createSprintUpdateCommand(),
1095
- "sprint delete": createSprintDeleteCommand()
1137
+ "space-sprint get": createSprintGetCommand(),
1138
+ "space-sprint list": createSprintListCommand(),
1139
+ "space-sprint create": createSprintCreateCommand(),
1140
+ "space-sprint update": createSprintUpdateCommand(),
1141
+ "space-sprint delete": createSprintDeleteCommand(),
1142
+ "space-sprint sub-sprint list": createSubSprintListCommand(),
1143
+ "space-sprint sub-sprint create": createSubSprintCreateCommand(),
1144
+ "space-sprint sub-sprint update": createSubSprintUpdateCommand(),
1145
+ "space-sprint sub-sprint delete": createSubSprintDeleteCommand()
1096
1146
  };
1097
1147
  }
1098
1148
  async function getClient2() {
@@ -1107,15 +1157,18 @@ async function getClient2() {
1107
1157
  }
1108
1158
  function createSprintGetCommand() {
1109
1159
  return defineCommand({
1110
- name: "sprint get",
1160
+ name: "space-sprint get",
1111
1161
  description: "Get sprint details including stories and files",
1112
- usage: "forloop sprint get --id <number>",
1162
+ usage: "forloop space-sprint get --id <number>",
1113
1163
  options: [
1114
1164
  { flag: "--id <number>", description: "Sprint ID (auto-detected if not provided)", type: "number" },
1115
1165
  { flag: "--no-stories", description: "Exclude stories from response" },
1116
- { flag: "--no-files", description: "Exclude files from response" }
1166
+ { flag: "--no-files", description: "Exclude files from response" },
1167
+ { flag: "--all-stories", description: "Return all sprint stories (bypass sub-sprint filter)" },
1168
+ { flag: "--sub-sprint-id <number>", description: "Filter stories to a specific sub-sprint", type: "number" },
1169
+ { flag: "--include-sub-sprints", description: "Include sub-sprints array in response" }
1117
1170
  ],
1118
- examples: ["forloop sprint get --id 456", "forloop sprint get --id 456 --no-files"],
1171
+ examples: ["forloop space-sprint get --id 456", "forloop space-sprint get --id 456 --no-files", "forloop space-sprint get --id 456 --all-stories"],
1119
1172
  async run(config, flags) {
1120
1173
  const resolved = await getClient2();
1121
1174
  if (!resolved) return;
@@ -1127,7 +1180,10 @@ function createSprintGetCommand() {
1127
1180
  }
1128
1181
  const sprint = await client.getSprint(resolution.sprintId, {
1129
1182
  includeStories: !flags.noStories,
1130
- includeFiles: !flags.noFiles
1183
+ includeFiles: !flags.noFiles,
1184
+ allStories: flags.allStories,
1185
+ subSprintId: flags.subSprintId,
1186
+ includeSubSprints: flags.includeSubSprints
1131
1187
  });
1132
1188
  print(config, sprint);
1133
1189
  }
@@ -1135,14 +1191,14 @@ function createSprintGetCommand() {
1135
1191
  }
1136
1192
  function createSprintListCommand() {
1137
1193
  return defineCommand({
1138
- name: "sprint list",
1194
+ name: "space-sprint list",
1139
1195
  description: "List all accessible sprints",
1140
- usage: "forloop sprint list [--org-id <id>] [--include-system-org]",
1196
+ usage: "forloop space-sprint list [--org-id <id>] [--include-system-org]",
1141
1197
  options: [
1142
1198
  { flag: "--org-id <id>", description: "Filter by organization ID", type: "number" },
1143
1199
  { flag: "--include-system-org", description: "Include system organization sprints" }
1144
1200
  ],
1145
- examples: ["forloop sprint list", "forloop sprint list --org-id 1"],
1201
+ examples: ["forloop space-sprint list", "forloop space-sprint list --org-id 1"],
1146
1202
  async run(config, flags) {
1147
1203
  const resolved = await getClient2();
1148
1204
  if (!resolved) return;
@@ -1157,9 +1213,9 @@ function createSprintListCommand() {
1157
1213
  }
1158
1214
  function createSprintCreateCommand() {
1159
1215
  return defineCommand({
1160
- name: "sprint create",
1216
+ name: "space-sprint create",
1161
1217
  description: "Create a new sprint",
1162
- usage: "forloop sprint create --title <text> --start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD> [flags]",
1218
+ usage: "forloop space-sprint create --title <text> --start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD> [flags]",
1163
1219
  options: [
1164
1220
  { flag: "--title <text>", description: "Sprint title", required: true },
1165
1221
  { flag: "--start-date <date>", description: "Start date (YYYY-MM-DD)", required: true },
@@ -1168,7 +1224,7 @@ function createSprintCreateCommand() {
1168
1224
  { flag: "--private", description: "Make sprint private" },
1169
1225
  { flag: "--org-id <id>", description: "Organization ID", type: "number" }
1170
1226
  ],
1171
- examples: ['forloop sprint create --title "Sprint 15" --start-date 2026-06-09 --end-date 2026-06-23'],
1227
+ examples: ['forloop space-sprint create --title "Sprint 15" --start-date 2026-06-09 --end-date 2026-06-23'],
1172
1228
  async run(config, flags) {
1173
1229
  const resolved = await getClient2();
1174
1230
  if (!resolved) return;
@@ -1191,9 +1247,9 @@ function createSprintCreateCommand() {
1191
1247
  }
1192
1248
  function createSprintUpdateCommand() {
1193
1249
  return defineCommand({
1194
- name: "sprint update",
1250
+ name: "space-sprint update",
1195
1251
  description: "Update sprint details",
1196
- usage: "forloop sprint update --id <number> [flags]",
1252
+ usage: "forloop space-sprint update --id <number> [flags]",
1197
1253
  options: [
1198
1254
  { flag: "--id <number>", description: "Sprint ID", required: true, type: "number" },
1199
1255
  { flag: "--title <text>", description: "New title" },
@@ -1202,7 +1258,7 @@ function createSprintUpdateCommand() {
1202
1258
  { flag: "--end-date <date>", description: "New end date" },
1203
1259
  { flag: "--private", description: "Set visibility to private" }
1204
1260
  ],
1205
- examples: ['forloop sprint update --id 456 --title "Updated Sprint"'],
1261
+ examples: ['forloop space-sprint update --id 456 --title "Updated Sprint"'],
1206
1262
  async run(config, flags) {
1207
1263
  const resolved = await getClient2();
1208
1264
  if (!resolved) return;
@@ -1224,14 +1280,14 @@ function createSprintUpdateCommand() {
1224
1280
  }
1225
1281
  function createSprintDeleteCommand() {
1226
1282
  return defineCommand({
1227
- name: "sprint delete",
1283
+ name: "space-sprint delete",
1228
1284
  description: "Delete a sprint permanently",
1229
- usage: "forloop sprint delete --id <number> --confirm",
1285
+ usage: "forloop space-sprint delete --id <number> --confirm",
1230
1286
  options: [
1231
1287
  { flag: "--id <number>", description: "Sprint ID", required: true, type: "number" },
1232
1288
  { flag: "--confirm", description: "Confirm deletion" }
1233
1289
  ],
1234
- examples: ["forloop sprint delete --id 456 --confirm"],
1290
+ examples: ["forloop space-sprint delete --id 456 --confirm"],
1235
1291
  async run(config, flags) {
1236
1292
  if (!flags.confirm) {
1237
1293
  console.error("Error: --confirm is required to permanently delete a sprint.");
@@ -1245,6 +1301,126 @@ function createSprintDeleteCommand() {
1245
1301
  }
1246
1302
  });
1247
1303
  }
1304
+ function createSubSprintListCommand() {
1305
+ return defineCommand({
1306
+ name: "space-sprint sub-sprint list",
1307
+ description: "List all iterations within a sprint",
1308
+ usage: "forloop space-sprint sub-sprint list [--sprint-id <number>]",
1309
+ options: [
1310
+ { flag: "--sprint-id <number>", description: "Sprint ID (auto-detected if not provided)", type: "number" }
1311
+ ],
1312
+ examples: [
1313
+ "forloop space-sprint sub-sprint list",
1314
+ "forloop space-sprint sub-sprint list --sprint-id 456"
1315
+ ],
1316
+ async run(config, flags) {
1317
+ const resolved = await getClient2();
1318
+ if (!resolved) return;
1319
+ const { client } = resolved;
1320
+ const resolution = await resolveSprintId(flags.sprintId);
1321
+ if (!resolution.sprintId) {
1322
+ console.error("Error: No sprint ID resolved. Use --sprint-id, set FORLOOP_SPRINT_ID, or use a sprint-XXX branch.");
1323
+ process.exit(1);
1324
+ }
1325
+ const subSprints = await client.getSubSprints(resolution.sprintId);
1326
+ print(config, subSprints);
1327
+ }
1328
+ });
1329
+ }
1330
+ function createSubSprintCreateCommand() {
1331
+ return defineCommand({
1332
+ name: "space-sprint sub-sprint create",
1333
+ description: "Create a new iteration (auto-completes the previously active one)",
1334
+ usage: "forloop space-sprint sub-sprint create [--sprint-id <number>] --start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD> [--title <text>]",
1335
+ options: [
1336
+ { flag: "--sprint-id <number>", description: "Sprint ID (auto-detected if not provided)", type: "number" },
1337
+ { flag: "--start-date <date>", description: "Start date (YYYY-MM-DD)", required: true },
1338
+ { flag: "--end-date <date>", description: "End date (YYYY-MM-DD)", required: true },
1339
+ { flag: "--title <text>", description: "Iteration title (auto-generates if not provided)" }
1340
+ ],
1341
+ examples: [
1342
+ "forloop space-sprint sub-sprint create --start-date 2026-08-15 --end-date 2026-08-28",
1343
+ "forloop space-sprint sub-sprint create --sprint-id 456 --start-date 2026-08-15 --end-date 2026-08-28"
1344
+ ],
1345
+ async run(config, flags) {
1346
+ const resolved = await getClient2();
1347
+ if (!resolved) return;
1348
+ const { client } = resolved;
1349
+ if (!flags.startDate || !flags.endDate) {
1350
+ console.error("Error: --start-date and --end-date are required");
1351
+ process.exit(1);
1352
+ }
1353
+ const resolution = await resolveSprintId(flags.sprintId);
1354
+ if (!resolution.sprintId) {
1355
+ console.error("Error: No sprint ID resolved. Use --sprint-id, set FORLOOP_SPRINT_ID, or use a sprint-XXX branch.");
1356
+ process.exit(1);
1357
+ }
1358
+ const subSprint = await client.createSubSprint(resolution.sprintId, {
1359
+ title: flags.title,
1360
+ startDate: flags.startDate,
1361
+ endDate: flags.endDate
1362
+ });
1363
+ print(config, subSprint, `Iteration created: #${subSprint.id} - ${subSprint.title}`);
1364
+ }
1365
+ });
1366
+ }
1367
+ function createSubSprintUpdateCommand() {
1368
+ return defineCommand({
1369
+ name: "space-sprint sub-sprint update",
1370
+ description: "Update an iteration title, dates, or status",
1371
+ usage: "forloop space-sprint sub-sprint update --id <number> [--title <text>] [--start-date <date>] [--end-date <date>] [--status <planned|in_progress|completed>]",
1372
+ options: [
1373
+ { flag: "--id <number>", description: "Sub-sprint ID", required: true, type: "number" },
1374
+ { flag: "--title <text>", description: "New title" },
1375
+ { flag: "--start-date <date>", description: "New start date (YYYY-MM-DD)" },
1376
+ { flag: "--end-date <date>", description: "New end date (YYYY-MM-DD)" },
1377
+ { flag: "--status <string>", description: "New status: planned, in_progress, or completed" }
1378
+ ],
1379
+ examples: [
1380
+ 'forloop space-sprint sub-sprint update --id 5 --title "Iteration 2 \u2014 Payment Integration"',
1381
+ "forloop space-sprint sub-sprint update --id 5 --status completed"
1382
+ ],
1383
+ async run(config, flags) {
1384
+ const resolved = await getClient2();
1385
+ if (!resolved) return;
1386
+ const { client } = resolved;
1387
+ const updateData = {};
1388
+ if (flags.title !== void 0) updateData.title = flags.title;
1389
+ if (flags.startDate !== void 0) updateData.startDate = flags.startDate;
1390
+ if (flags.endDate !== void 0) updateData.endDate = flags.endDate;
1391
+ if (flags.status !== void 0) updateData.status = flags.status;
1392
+ if (Object.keys(updateData).length === 0) {
1393
+ console.error("Error: at least one field to update is required");
1394
+ process.exit(1);
1395
+ }
1396
+ const updated = await client.updateSubSprint(flags.id, updateData);
1397
+ print(config, updated, `Iteration #${updated.id} updated successfully.`);
1398
+ }
1399
+ });
1400
+ }
1401
+ function createSubSprintDeleteCommand() {
1402
+ return defineCommand({
1403
+ name: "space-sprint sub-sprint delete",
1404
+ description: "Soft-delete an iteration",
1405
+ usage: "forloop space-sprint sub-sprint delete --id <number> --confirm",
1406
+ options: [
1407
+ { flag: "--id <number>", description: "Sub-sprint ID", required: true, type: "number" },
1408
+ { flag: "--confirm", description: "Confirm deletion" }
1409
+ ],
1410
+ examples: ["forloop space-sprint sub-sprint delete --id 5 --confirm"],
1411
+ async run(config, flags) {
1412
+ if (!flags.confirm) {
1413
+ console.error("Error: --confirm is required to delete an iteration.");
1414
+ process.exit(1);
1415
+ }
1416
+ const resolved = await getClient2();
1417
+ if (!resolved) return;
1418
+ const { client } = resolved;
1419
+ await client.deleteSubSprint(flags.id);
1420
+ print(config, { success: true }, `Iteration #${flags.id} deleted successfully.`);
1421
+ }
1422
+ });
1423
+ }
1248
1424
 
1249
1425
  // src/commands/org.ts
1250
1426
  async function getClient3() {
@@ -1423,7 +1599,7 @@ function createTemplateListCommand() {
1423
1599
  function createAgentCommands() {
1424
1600
  return {
1425
1601
  "agent history": createAgentHistoryCommand(),
1426
- "agent developer-sprint": createDeveloperSprintCommand(),
1602
+ "agent developer-space-sprint": createDeveloperSprintCommand(),
1427
1603
  "agent developer-status": createDeveloperStatusCommand()
1428
1604
  };
1429
1605
  }
@@ -1462,14 +1638,14 @@ function createAgentHistoryCommand() {
1462
1638
  }
1463
1639
  function createDeveloperSprintCommand() {
1464
1640
  return defineCommand({
1465
- name: "agent developer-sprint",
1641
+ name: "agent developer-space-sprint",
1466
1642
  description: "Trigger the developer agent to implement sprint stories",
1467
- usage: "forloop agent developer-sprint --sprint <id> [--message <text>]",
1643
+ usage: "forloop agent developer-space-sprint --sprint <id> [--message <text>]",
1468
1644
  options: [
1469
1645
  { flag: "--sprint <id>", description: "Sprint ID", required: true, type: "number" },
1470
1646
  { flag: "--message <text>", description: "Instructions for the developer agent" }
1471
1647
  ],
1472
- examples: ['forloop agent developer-sprint --sprint 1 --message "Implement all planned tasks"'],
1648
+ examples: ['forloop agent developer-space-sprint --sprint 1 --message "Implement all planned tasks"'],
1473
1649
  async run(_config, flags) {
1474
1650
  if (!flags.sprint) {
1475
1651
  console.error("Error: --sprint is required");
@@ -2129,10 +2305,10 @@ ${b("Usage:")} forloop <resource> <command> [flags]
2129
2305
 
2130
2306
  ${b("Resources:")}
2131
2307
  ${a("auth")} ${d("Authentication (login, status, logout)")}
2132
- ${a("sprint")} ${d("Sprint operations (list, get, create, update, delete)")}
2308
+ ${a("space-sprint")}${d("Sprint operations (list, get, create, update, delete)")}
2133
2309
  ${a("story")} ${d("Story operations (create, get, update, delete)")}
2134
2310
  ${a("template")} ${d("Template operations (list)")}
2135
- ${a("agent")} ${d("Agent operations (history, developer-sprint, developer-status)")}
2311
+ ${a("agent")} ${d("Agent operations (history, developer-space-sprint, developer-status)")}
2136
2312
  ${a("org")} ${d("Organization operations (list, get, create, update)")}
2137
2313
  ${a("user")} ${d("User operations (profile, quotas)")}
2138
2314
  ${a("file")} ${d("File operations (upload, list, delete, download)")}
@@ -2214,17 +2390,21 @@ ${d("Global flags (--api-key, --output, --quiet, etc.) are always available.")}
2214
2390
  }
2215
2391
  }
2216
2392
  };
2217
- var sprintGetCmd = createSprintCommands()["sprint get"];
2218
- var sprintListCmd = createSprintCommands()["sprint list"];
2219
- var sprintCreateCmd = createSprintCommands()["sprint create"];
2220
- var sprintUpdateCmd = createSprintCommands()["sprint update"];
2221
- var sprintDeleteCmd = createSprintCommands()["sprint delete"];
2393
+ var sprintGetCmd = createSprintCommands()["space-sprint get"];
2394
+ var sprintListCmd = createSprintCommands()["space-sprint list"];
2395
+ var sprintCreateCmd = createSprintCommands()["space-sprint create"];
2396
+ var sprintUpdateCmd = createSprintCommands()["space-sprint update"];
2397
+ var sprintDeleteCmd = createSprintCommands()["space-sprint delete"];
2398
+ var ssListCmd = createSprintCommands()["space-sprint sub-sprint list"];
2399
+ var ssCreateCmd = createSprintCommands()["space-sprint sub-sprint create"];
2400
+ var ssUpdateCmd = createSprintCommands()["space-sprint sub-sprint update"];
2401
+ var ssDeleteCmd = createSprintCommands()["space-sprint sub-sprint delete"];
2222
2402
  var storyCreateCmd = createStoryCommands()["story create"];
2223
2403
  var storyGetCmd = createStoryCommands()["story get"];
2224
2404
  var storyUpdateCmd = createStoryCommands()["story update"];
2225
2405
  var storyDeleteCmd = createStoryCommands()["story delete"];
2226
2406
  var agentHistoryCmd = createAgentCommands()["agent history"];
2227
- var agentDeveloperSprintCmd = createAgentCommands()["agent developer-sprint"];
2407
+ var agentDeveloperSprintCmd = createAgentCommands()["agent developer-space-sprint"];
2228
2408
  var agentDeveloperStatusCmd = createAgentCommands()["agent developer-status"];
2229
2409
  var fileUploadCmd = createFileCommands()["file upload"];
2230
2410
  var fileListCmd = createFileCommands()["file list"];
@@ -2242,10 +2422,15 @@ var registry = new CommandRegistry({
2242
2422
  ...createFolderCommands(),
2243
2423
  ...createSyncCommands(),
2244
2424
  // Aliases
2245
- "sprint show": sprintGetCmd,
2246
- "sprint info": sprintGetCmd,
2425
+ "space-sprint show": sprintGetCmd,
2426
+ "space-sprint info": sprintGetCmd,
2247
2427
  "agent status": agentDeveloperStatusCmd,
2248
- "agent sprint": agentDeveloperSprintCmd
2428
+ "agent space-sprint": agentDeveloperSprintCmd,
2429
+ // Sub-sprint aliases
2430
+ "space-sprint sub-sprint list": ssListCmd,
2431
+ "space-sprint sub-sprint create": ssCreateCmd,
2432
+ "space-sprint sub-sprint update": ssUpdateCmd,
2433
+ "space-sprint sub-sprint delete": ssDeleteCmd
2249
2434
  });
2250
2435
 
2251
2436
  // src/errors/handler.ts
package/install.sh CHANGED
@@ -80,11 +80,11 @@ echo ""
80
80
  echo -e "${BOLD}Next steps:${NC}"
81
81
  echo " 1. Get an API token: https://forloop.cc/profile?tab=api-tokens"
82
82
  echo " 2. Authenticate: forloop auth login --api-key floop_xxxxx"
83
- echo " 3. Start using: forloop sprint list"
83
+ echo " 3. Start using: forloop space-sprint list"
84
84
  echo ""
85
85
  echo -e "${BOLD}Quick reference:${NC}"
86
86
  echo " forloop --help Show all commands"
87
87
  echo " forloop auth login Set your API token"
88
- echo " forloop sprint list List sprints"
88
+ echo " forloop space-sprint list List sprints"
89
89
  echo " forloop agent developer-status Check AI agent status"
90
90
  echo ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forloop-cc/forloop-cli",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Command-line interface for the ForLoop AI development platform",
5
5
  "type": "module",
6
6
  "license": "MIT",