Skip to content

DO NOT MERGE - Revert: feat(cli): Add squad loop command (#767) - #774

Closed
diberry wants to merge 1 commit into
devfrom
revert/767-loop-command
Closed

DO NOT MERGE - Revert: feat(cli): Add squad loop command (#767)#774
diberry wants to merge 1 commit into
devfrom
revert/767-loop-command

Conversation

@diberry

@diberry diberry commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Reverts the squash merge of PR #767 (commit efb56ac). The loop command was merged prematurely — needs further review before landing on dev.

Copilot AI review requested due to automatic review settings April 3, 2026 04:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reverts the previously-merged squad loop feature (PR #767) because it landed prematurely, removing the loop command implementation, its templates, tests, docs, and associated repo state updates.

Changes:

  • Removes the squad loop command implementation (loop.ts) plus the loop.md templates and unit tests.
  • Deletes Loop documentation (CLI reference section + feature page) and the changeset for the CLI release.
  • Adjusts the CLI entry to a placeholder loop handler and updates squad.agent template copies (but currently leaves template canon out of sync).

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/cli/loop.test.ts Removes unit tests that were specific to the Loop command.
templates/squad.agent.md.template Updates a mirrored squad.agent template (currently risks template-sync mismatch vs canonical).
templates/loop.md Removes Loop prompt template from root templates.
packages/squad-cli/templates/squad.agent.md.template Updates CLI package’s mirrored squad.agent template.
packages/squad-cli/templates/loop.md Removes Loop prompt template from CLI package templates.
packages/squad-cli/src/cli/commands/loop.ts Removes Loop command implementation.
packages/squad-cli/src/cli-entry.ts Removes Loop implementation wiring but leaves a stub loop command in help/dispatch.
docs/src/content/docs/reference/cli.md Removes Loop command docs and updates command count.
docs/src/content/docs/features/loop.md Deletes the Loop feature documentation page.
.squad/skills/pr-review-response/SKILL.md Removes a skill file that was introduced/modified as part of the reverted work.
.squad/log/2026-03-27T21-42-00Z-decisions-archival.md Removes a Scribe archival log entry associated with the reverted work.
.squad/agents/eecom/history.md Removes Loop-related learnings entry.
.changeset/loop-command.md Removes the changeset announcing the Loop command release.

4. CROSS-AGENT: Append team updates to affected agents' history.md.
5. DECISIONS ARCHIVE: If decisions.md exceeds ~20KB, archive entries older than 30 days to decisions-archive.md.
6. GIT COMMIT: git add .squad/ && commit (write msg to temp file, use -F). Skip if nothing staged.
7. HISTORY SUMMARIZATION: If any history.md >12KB, summarize old entries to ## Core Context.

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Template-sync CI will likely fail: template-sync.test.ts defines .squad-templates/squad.agent.md as canonical and requires mirror copies (templates/squad.agent.md.template, packages/*/templates/squad.agent.md.template, and .github/agents/squad.agent.md) to be byte-for-byte identical. This change updates a mirror copy but does not update the canonical .squad-templates/squad.agent.md (and .github/agents/squad.agent.md), so the repo will be out of sync. Fix by running node scripts/sync-templates.mjs (or manually applying the same edit) so canonical + all mirrors match exactly.

Suggested change
7. HISTORY SUMMARIZATION: If any history.md >12KB, summarize old entries to ## Core Context.

Copilot uses AI. Check for mistakes.
Comment on lines +180 to 183
console.log(` ${BOLD}loop${RESET} Continuous work loop (Ralph mode)`);
console.log(` Usage: loop [--filter <label>] [--interval <minutes>]`);
console.log(` Default: checks every 10 minutes (Ctrl+C to stop)`);
console.log(` ${BOLD}hire${RESET} Team creation wizard`);

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is described as a revert of adding the squad loop command, but the CLI still advertises loop in the help output and implements a stub handler that prints “full implementation pending”. This leaves users with a documented command that doesn’t work and also conflicts with the docs update that removed squad loop from the CLI reference. Either remove the loop command entirely (help + dispatch), or reintroduce/restore documentation and a working implementation.

Copilot uses AI. Check for mistakes.
Comment on lines 401 to +412
if (cmd === 'loop') {
// --help
if (args.includes('--help') || args.includes('-h')) {
console.log(`\n${BOLD}squad loop${RESET} — Prompt-driven continuous work loop\n`);
console.log(`Usage: squad loop [options]\n`);
console.log(`Reads loop.md and runs it as a continuous work loop.\n`);
console.log(`Options:`);
console.log(` ${BOLD}--init${RESET} Generate a boilerplate loop.md`);
console.log(` ${BOLD}--file <path>${RESET} Path to loop file (default: loop.md)`);
console.log(` ${BOLD}--interval <min>${RESET} Override loop interval in minutes`);
console.log(` ${BOLD}--timeout <min>${RESET} Override max minutes per cycle`);
console.log(` ${BOLD}--copilot-flags "..."${RESET} Extra flags for Copilot CLI`);
console.log(` ${BOLD}--agent-cmd <cmd>${RESET} Override the agent command`);
console.log(`\nCapabilities (composable with the loop):`);
console.log(` ${BOLD}--self-pull${RESET} git fetch/pull at round start`);
console.log(` ${BOLD}--monitor-email${RESET} Scan email for actionable items`);
console.log(` ${BOLD}--monitor-teams${RESET} Scan Teams for actionable messages`);
console.log(` ${BOLD}--decision-hygiene${RESET} Auto-merge decision inbox`);
console.log(` ${BOLD}--retro${RESET} Enforce retrospective checks`);
console.log(`\nFrontmatter (in loop.md):`);
console.log(` configured: true ${DIM}(required — confirms intentional setup)${RESET}`);
console.log(` interval: 10 ${DIM}(minutes between cycles)${RESET}`);
console.log(` timeout: 30 ${DIM}(max minutes per cycle)${RESET}`);
console.log(` description: "..." ${DIM}(shown in status output)${RESET}`);
console.log(`\nExamples:`);
console.log(` squad loop ${DIM}# run loop.md${RESET}`);
console.log(` squad loop --init ${DIM}# generate boilerplate${RESET}`);
console.log(` squad loop --file ops/loop.md ${DIM}# custom loop file${RESET}`);
console.log(` squad loop --monitor-email ${DIM}# with email monitoring${RESET}`);
return;
}

const { runLoop, generateLoopFile } = await import('./cli/commands/loop.js');

// --init: scaffold a boilerplate loop.md
if (args.includes('--init')) {
const fileIdx = args.indexOf('--file');
const filePath = (fileIdx !== -1 && args[fileIdx + 1]) ? args[fileIdx + 1]! : 'loop.md';
const { FSStorageProvider } = await import('@bradygaster/squad-sdk');
const storage = new FSStorageProvider();
const pathMod = await import('node:path');
const absPath = pathMod.default.resolve(process.cwd(), filePath);
if (storage.existsSync(absPath)) {
console.log(`⚠️ ${filePath} already exists. Remove it first to regenerate.`);
} else {
storage.writeSync(absPath, generateLoopFile());
console.log(`✅ Created ${filePath} — open it and set \`configured: true\` to activate.`);
}
return;
}

// Parse flags
const fileIdx = args.indexOf('--file');
const filePath = (fileIdx !== -1 && args[fileIdx + 1]) ? args[fileIdx + 1] : undefined;

const filterIdx = args.indexOf('--filter');
const filter = (filterIdx !== -1 && args[filterIdx + 1]) ? args[filterIdx + 1] : undefined;
const intervalIdx = args.indexOf('--interval');
const interval = (intervalIdx !== -1 && args[intervalIdx + 1])
const intervalMinutes = (intervalIdx !== -1 && args[intervalIdx + 1])
? parseInt(args[intervalIdx + 1]!, 10)
: undefined;

const timeoutIdx = args.indexOf('--timeout');
const timeout = (timeoutIdx !== -1 && args[timeoutIdx + 1])
? parseInt(args[timeoutIdx + 1]!, 10)
: undefined;

const copilotFlagsIdx = args.indexOf('--copilot-flags');
const copilotFlags = (copilotFlagsIdx !== -1 && args[copilotFlagsIdx + 1])
? args[copilotFlagsIdx + 1]
: undefined;

const agentCmdIdx = args.indexOf('--agent-cmd');
const agentCmd = (agentCmdIdx !== -1 && args[agentCmdIdx + 1])
? args[agentCmdIdx + 1]
: undefined;

// Capability flags
const { createDefaultRegistry: createReg } = await import('./cli/commands/watch/index.js');
const reg = createReg();
const capabilities: Record<string, boolean | Record<string, unknown>> = {};
for (const cap of reg.all()) {
if (args.includes(`--${cap.name}`)) capabilities[cap.name] = true;
if (args.includes(`--no-${cap.name}`)) capabilities[cap.name] = false;
: 10;
console.log(`🔄 Squad loop starting... (full implementation pending)`);
if (filter) {
console.log(` Filter: ${filter}`);
}

await runLoop(process.cwd(), {
filePath,
interval,
timeout,
copilotFlags,
agentCmd,
capabilities,
});
console.log(` Interval: ${intervalMinutes} minutes`);

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop command handler currently parses --interval but doesn’t validate it. If a non-numeric value is passed (e.g. --interval abc), parseInt yields NaN and the CLI prints Interval: NaN minutes. If the command is going to remain exposed, validate the parsed value and fail with a clear usage message (or default back to 10).

Copilot uses AI. Check for mistakes.
Comment on lines +25 to 40
## CLI Commands (16 commands)

| Command | Description | Requires `.squad/` |
|---------|-------------|:------------------:|
| `squad` | Enter interactive shell (no args) | No |
| `squad init` | Initialize Squad in the current repo (idempotent — safe to run multiple times) | No |
| `squad init --global` | Create a personal squad in your platform-specific directory | No |
| `squad init --mode remote <path>` | Initialize linked to a remote team root (dual-root mode) | No |
| `squad link <team-repo-path>` | Link project to a remote team root | Yes |
| `squad loop` | Run a prompt-driven work loop from `loop.md` | Yes |
| `squad loop --init` | Create a starter `loop.md` file | Yes |
| `squad loop --file <path>` | Run a loop from a custom file path | Yes |
| `squad start [--tunnel] [--port N] [--command cmd]` | Start Copilot with remote phone access via PTY and WebSocket | No |
| `squad status` | Show which squad is active and why | Yes |
| `squad doctor` | Validate squad setup integrity and diagnose issues (alias: `heartbeat`) | Yes |
| `squad upgrade` | Upgrade Squad-owned files to latest version | Yes |
| `squad upgrade --migrate-directory` | Rename legacy `.ai-team/` directory to `.squad/` | Yes |
| `squad link <team-repo-path>` | Link project to a remote team root | Yes |
| `squad triage` | Auto-triage issues and assign to team (primary name; `watch` is an alias) | Yes |
| `squad triage --interval <min>` | Continuous triage (default: every 10 min) | Yes |

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs now remove squad loop from the CLI reference (and reduce the command count), but the CLI help/dispatcher still exposes a loop command. Once the desired behavior is decided (remove loop vs. keep as alias), please update this table/count to match the shipped CLI to avoid confusing users.

Copilot uses AI. Check for mistakes.
@diberry diberry added the skip-changelog Skip changelog enforcement for this PR label Apr 3, 2026
@diberry diberry changed the title Revert: feat(cli): Add squad loop command (#767) HOLD - Revert: feat(cli): Add squad loop command (#767) Apr 3, 2026
@diberry diberry changed the title HOLD - Revert: feat(cli): Add squad loop command (#767) DO NOT MERGE - Revert: feat(cli): Add squad loop command (#767) Apr 3, 2026
@diberry diberry closed this Apr 3, 2026
@bradygaster
bradygaster deleted the revert/767-loop-command branch August 8, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Skip changelog enforcement for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants