Skip to content

Commit 358ae42

Browse files
arielshadclaudeshep-agent
authored
feat: combine 17 open PRs (cluster, supply-chain, workflows, plugins, messaging, mcp, exploration + more) onto current main (#740)
## Summary Combines **all 17 open PRs by @arielshad** (everything in the open list **except #731**, as requested) into a single branch, rebased onto **current `main` (v1.210.0)** with conflicts resolved. These PRs forked from an **old main (Mar–Apr)**; the repo history was later rewritten and `main` advanced ~3 months. Each PR's real commits were replayed onto current `main` via 3‑way rebase (reconstructed exact fork points), conflicts resolved, then assembled here. Where `main` had already implemented a PR's feature differently, **main's version was kept** and only genuinely net‑new functionality was integrated (per agreed strategy). **Local verification:** `pnpm typecheck` ✓ (0 errors) · `pnpm lint` (changed files) ✓ · `pnpm build` ✓ · adopt‑branch unit+integration tests ✓. Full unit/int suite run is in progress as follow‑up. ## PRs integrated | PR | Feature | Verdict | |----|---------|---------| | #566 | Cluster entity + agent + CLI + web UI (k8s) | NET‑NEW | | #527 | Policy‑driven supply‑chain security | NET‑NEW (renamed `SecurityPolicy`→`SupplyChainSecurityPolicy` to avoid ASPM clash) | | #441 | Scheduled workflows engine | NET‑NEW (renamed to `Scheduled*` / `scheduled-workflows/` to avoid main's workflow‑steps clash) | | #555 | Pluggable AI tool system (MCP lifecycle) | NET‑NEW | | #512 | Messaging remote control | NET‑NEW | | #513 | Prototype exploration mode | PARTIAL — mapped onto main's existing `BuildMode` (added `Exploration`); dropped the obsolete `fast`→enum migration | | #469 | MCP server for AI agent integration | NET‑NEW | | #367 | Per‑repo webhook enable/disable | NET‑NEW (token renamed `IWebhookService`→`IGitHubWebhookService` to avoid clash) | | #538 | Feature reparenting + auto‑rebase | NET‑NEW (adapted onto main's evolved graph‑state) | | #430 + #434 | `--remote` flag + auto‑fork | PARTIAL — main already had fork fields/import use case; kept main's, added the net‑new bits | | #417 | AgentRun + spec init on adopted branches | NET‑NEW (refactored to inject `ISettingsProvider` for clean‑arch) | | #384 | Agent‑based dev‑environment analysis | PARTIAL — kept main's deploy use cases; added agent ports/services (see note) | | #470 | Evidence image lightbox | NET‑NEW | | #443 | File‑tree merge‑review diff | NET‑NEW | | #409 | `repo init-remote` command | SUPERSEDED — main already has it; kept specs, dropped a stale test | | #399 | Restore deploy state across drawer cycles | SUPERSEDED — main's store‑based deploy architecture already solves it; specs only | ## Integration notes - **Migrations** renumbered to a unique, sequential `120–134` range (above main's `119`); loader globs by filename so no index changes needed. - **TypeSpec** `generated/output.ts` regenerated authoritatively from the merged `tsp/` sources (`pnpm tsp:compile`). - **New deps:** `@modelcontextprotocol/sdk`, `@types/which`, `ws`, `cloudflared`. - **Feature flags** added: `clusters`, `supplyChainSecurity`, `scheduledWorkflows` (wired through tsp/mapper/repo/defaults/feature‑flags/sidebar/settings + all 9 locales). ## Follow‑ups (called out honestly) - **#384**: `AgentDeploymentService`/`DevEnvironmentAgentService` are registered but not yet wired to a consumer — main's deploy flows use their own use cases. Main's `DeploymentService.start()` doesn't accept a command override, so the agent‑analyzed command is currently logged rather than passed; wiring an explicit override is a follow‑up. - Full unit/integration/e2e suite still to be run end‑to‑end; web/Storybook build not yet exercised. 🐑 Combined and reconciled with Shep. https://claude.ai/code/session_01TzQM4PuyfCbUi5dSNezXPE --- _Generated by [Claude Code](https://claude.ai/code/session_01TzQM4PuyfCbUi5dSNezXPE)_ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Shep Bot <shep-agent@users.noreply.github.com>
1 parent c9667e1 commit 358ae42

902 files changed

Lines changed: 93249 additions & 580 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
# ┌──────┬───────────┬─────────────────┬─────────────────┬─────────┬─────────┬───────────┬─────────────────────┐
88
# │ Lint │ Typecheck │ Unit (lin+win) │ E2E CLI (l+w) │ E2E TUI │ E2E Web │ Storybook │ Electron (m+w+l) │
99
# └──────┴───────────┴─────────────────┴─────────────────┴─────────┴─────────┴───────────┴─────────────────────┘
10-
# ┌──────────┬─────────┐
11-
# │ Gitleaks │ Semgrep │
12-
# └──────────┴─────────┘
10+
# ┌──────────┬─────────┬──────────────────
11+
# │ Gitleaks │ Semgrep │ Security Enforce │
12+
# └──────────┴─────────┴──────────────────
1313
# (all parallel)
1414
#
1515
# On push to main only:
@@ -308,6 +308,34 @@ jobs:
308308
p/javascript
309309
p/security-audit
310310
311+
# ===========================================================================
312+
# Supply Chain Security Enforcement
313+
# Runs shep security enforce to validate dependency risk, release integrity,
314+
# and governance posture. Gates release and dev-release jobs.
315+
#
316+
# Master kill switch: set the repository variable or workflow env
317+
# SHEP_SUPPLY_CHAIN_SECURITY=false to make this job a no-op.
318+
# The CLI honors the env var and exits 0 with a "flag disabled" note.
319+
# ===========================================================================
320+
security-enforce:
321+
name: Security Enforce
322+
runs-on: ubuntu-latest
323+
env:
324+
# Default: inherit from repo vars, fall back to true. Flip to 'false' (repo var
325+
# or workflow-level env) to disable the entire feature in CI.
326+
SHEP_SUPPLY_CHAIN_SECURITY: ${{ vars.SHEP_SUPPLY_CHAIN_SECURITY || 'true' }}
327+
steps:
328+
- uses: actions/checkout@v4
329+
- uses: pnpm/action-setup@v4
330+
- uses: actions/setup-node@v4
331+
with:
332+
node-version: ${{ env.NODE_VERSION }}
333+
cache: 'pnpm'
334+
- run: pnpm install --frozen-lockfile
335+
- run: pnpm run tsp:compile
336+
- name: Run security enforcement
337+
run: pnpm dev:cli security enforce --output json
338+
311339
# ===========================================================================
312340
# Security Summary Comment (PRs only)
313341
# Posts aggregated security scan results as a PR comment
@@ -364,6 +392,7 @@ jobs:
364392
- build-electron-apps-only
365393
- security-gitleaks
366394
- security-semgrep
395+
- security-enforce
367396
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[skip ci]')
368397

369398
permissions:
@@ -455,6 +484,7 @@ jobs:
455484
- build-electron
456485
- security-gitleaks
457486
- security-semgrep
487+
- security-enforce
458488
if: github.event_name == 'pull_request'
459489

460490
permissions:

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,5 @@ node_modules/.cache/prettier/
104104
*.bak
105105
storybook-static/
106106
.worktrees/
107-
.plan/
107+
.plan/
108+
.superpowers/

.gitleaksignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
dc0ca49a66f0ffe3ce9b37bd283513bb714ecada:src/presentation/web/components/common/feature-drawer/feature-drawer.stories.tsx:generic-api-key:124
22
42204c37eaad7947bf332782e4609f6480593abb:tests/unit/infrastructure/services/agents/executors/cursor-executor.test.ts:generic-api-key:599
3+
1c6b4761ae042411095cb1af81524853ef48bad7:tests/unit/infrastructure/services/messaging/content-sanitizer.test.ts:generic-api-key:24
34
3173676049f52fb4ff16805d1c50c27e652b7b75:tests/unit/infrastructure/services/messaging/content-sanitizer.test.ts:generic-api-key:24
5+
1c6b4761ae042411095cb1af81524853ef48bad7:tests/unit/infrastructure/services/messaging/content-sanitizer.test.ts:generic-api-key:24
46
cbe61f9d8b22bc0176339855f08b06ceee68fb49:src/presentation/web/components/features/settings/agent-settings-section.stories.tsx:generic-api-key:68
57
cbe61f9d8b22bc0176339855f08b06ceee68fb49:src/presentation/web/components/features/settings/agent-settings-section.stories.tsx:generic-api-key:78
68
d05e96264388c5293b05819845dd77053b97e477:src/presentation/web/components/features/settings/agent-settings-section.stories.tsx:generic-api-key:68
@@ -14,5 +16,3 @@ f2099f97e4e447aac7f141b14a2eb38a39df56f7:src/presentation/web/components/feature
1416
# These are UI fixtures rendered in Storybook to preview the token-auth form — no real
1517
# credentials are involved. PR #554 (one-click cloud deploy) does not touch this file;
1618
# the allowlist is added here only because gitleaks scans full git history.
17-
d05e96264388c5293b05819845dd77053b97e477:src/presentation/web/components/features/settings/agent-settings-section.stories.tsx:generic-api-key:68
18-
d05e96264388c5293b05819845dd77053b97e477:src/presentation/web/components/features/settings/agent-settings-section.stories.tsx:generic-api-key:78
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export async function getWorkflowHistory() {
2+
return {
3+
executions: [],
4+
};
5+
}

.storybook/mocks/app/actions/import-github-repository.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
export async function importGitHubRepository(input: { url: string; dest?: string }): Promise<{
2-
repository?: { id: string; name: string; path: string; remoteUrl?: string };
2+
repository?: {
3+
id: string;
4+
name: string;
5+
path: string;
6+
remoteUrl?: string;
7+
isFork?: boolean;
8+
upstreamUrl?: string;
9+
};
10+
forked?: boolean;
311
error?: string;
412
}> {
513
const name = input.url.split('/').pop() ?? 'unknown';
@@ -10,5 +18,6 @@ export async function importGitHubRepository(input: { url: string; dest?: string
1018
path: `/repos/${name}`,
1119
remoteUrl: input.url.startsWith('http') ? input.url : `https://github.com/${input.url}`,
1220
},
21+
forked: false,
1322
};
1423
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export async function listWorkflows() {
2+
return {
3+
workflows: [],
4+
};
5+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { MessagingPlatform } from '@shepai/core/domain/generated/output';
2+
3+
export async function beginMessagingPairingAction(input: {
4+
platform: MessagingPlatform;
5+
gatewayUrl: string;
6+
}): Promise<{
7+
success: boolean;
8+
error?: string;
9+
session?: {
10+
platform: MessagingPlatform;
11+
code: string;
12+
expiresAt: string;
13+
gatewayUrl: string;
14+
publicUrl: string;
15+
routeId: string;
16+
};
17+
}> {
18+
return {
19+
success: true,
20+
session: {
21+
platform: input.platform,
22+
code: '482913',
23+
expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(),
24+
gatewayUrl: input.gatewayUrl,
25+
publicUrl: `${input.gatewayUrl.replace(/\/$/, '')}/integrations/route-demo/token-demo`,
26+
routeId: 'route-demo',
27+
},
28+
};
29+
}
30+
31+
export async function confirmMessagingPairingAction(
32+
_input: unknown
33+
): Promise<{ success: boolean; error?: string }> {
34+
return { success: true };
35+
}
36+
37+
export async function disconnectMessagingAction(
38+
_input: unknown
39+
): Promise<{ success: boolean; error?: string }> {
40+
return { success: true };
41+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export async function reparentFeature(
2+
_featureId: string,
3+
_parentId: string | null
4+
): Promise<{ success: boolean; error?: string }> {
5+
return { success: true };
6+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export async function getSecurityStateAction(
2+
_repositoryPath: string
3+
): Promise<{ state?: unknown; error?: string }> {
4+
return { state: undefined };
5+
}
6+
7+
export async function enforceSecurityAction(
8+
_repositoryPath: string
9+
): Promise<{ result?: unknown; error?: string }> {
10+
return { result: undefined };
11+
}
12+
13+
export async function updateSecurityModeAction(
14+
_mode: string
15+
): Promise<{ success: boolean; error?: string }> {
16+
return { success: true };
17+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export async function toggleWorkflow() {
2+
return {
3+
success: true,
4+
};
5+
}

0 commit comments

Comments
 (0)