holo-codex 0.1.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.
- package/.agents/plugins/marketplace.json +20 -0
- package/CONTRIBUTING.md +54 -0
- package/LICENSE +21 -0
- package/README.md +215 -0
- package/README.zh-CN.md +215 -0
- package/SECURITY.md +39 -0
- package/assets/brand/README.md +35 -0
- package/assets/brand/holo-codex-icon.svg +28 -0
- package/assets/brand/holo-codex-lockup.svg +49 -0
- package/assets/brand/holo-codex-mark.svg +33 -0
- package/assets/brand/holo-codex-plugin-card.png +0 -0
- package/assets/brand/holo-codex-plugin-card.svg +81 -0
- package/assets/brand/holo-codex-readme-hero.png +0 -0
- package/assets/brand/holo-codex-readme-hero.svg +140 -0
- package/assets/brand/holo-codex-social-preview.png +0 -0
- package/assets/brand/holo-codex-social-preview.svg +130 -0
- package/assets/brand/holo-codex-wordmark-options.svg +52 -0
- package/docs/checklists/agent-loop-first-delivery-audit.md +129 -0
- package/docs/examples/generic-loop-repo-hygiene.md +168 -0
- package/docs/install.md +190 -0
- package/docs/local-release-readiness.md +206 -0
- package/docs/release-checklist.md +144 -0
- package/docs/self-bootstrap.md +150 -0
- package/docs/trust-and-safety.md +45 -0
- package/package.json +83 -0
- package/plugins/autonomous-pr-loop/.codex-plugin/plugin.json +17 -0
- package/plugins/autonomous-pr-loop/.mcp.json +13 -0
- package/plugins/autonomous-pr-loop/bin/agent-loop.mjs +31 -0
- package/plugins/autonomous-pr-loop/core/artifacts.ts +164 -0
- package/plugins/autonomous-pr-loop/core/autonomy-policy.ts +206 -0
- package/plugins/autonomous-pr-loop/core/ci.ts +131 -0
- package/plugins/autonomous-pr-loop/core/cli-i18n.ts +123 -0
- package/plugins/autonomous-pr-loop/core/cli.ts +1413 -0
- package/plugins/autonomous-pr-loop/core/command-runner.ts +446 -0
- package/plugins/autonomous-pr-loop/core/command.ts +47 -0
- package/plugins/autonomous-pr-loop/core/config-editor.ts +140 -0
- package/plugins/autonomous-pr-loop/core/config.ts +293 -0
- package/plugins/autonomous-pr-loop/core/controller-host.ts +19 -0
- package/plugins/autonomous-pr-loop/core/dashboard-server.ts +536 -0
- package/plugins/autonomous-pr-loop/core/delivery-work-item.ts +217 -0
- package/plugins/autonomous-pr-loop/core/doctor.ts +335 -0
- package/plugins/autonomous-pr-loop/core/errors.ts +82 -0
- package/plugins/autonomous-pr-loop/core/gate-recovery.ts +176 -0
- package/plugins/autonomous-pr-loop/core/gates.ts +26 -0
- package/plugins/autonomous-pr-loop/core/generic-lifecycle.ts +399 -0
- package/plugins/autonomous-pr-loop/core/git.ts +213 -0
- package/plugins/autonomous-pr-loop/core/github.ts +269 -0
- package/plugins/autonomous-pr-loop/core/gitnexus.ts +90 -0
- package/plugins/autonomous-pr-loop/core/happy.ts +42 -0
- package/plugins/autonomous-pr-loop/core/hook-capture.ts +115 -0
- package/plugins/autonomous-pr-loop/core/hook-events.ts +22 -0
- package/plugins/autonomous-pr-loop/core/hook-installation.ts +85 -0
- package/plugins/autonomous-pr-loop/core/hook-observer.ts +84 -0
- package/plugins/autonomous-pr-loop/core/hook-policy.ts +423 -0
- package/plugins/autonomous-pr-loop/core/hook-router.ts +452 -0
- package/plugins/autonomous-pr-loop/core/index.ts +32 -0
- package/plugins/autonomous-pr-loop/core/local-install.ts +778 -0
- package/plugins/autonomous-pr-loop/core/locale.ts +60 -0
- package/plugins/autonomous-pr-loop/core/loop-shapes.ts +190 -0
- package/plugins/autonomous-pr-loop/core/mcp-controller.ts +1479 -0
- package/plugins/autonomous-pr-loop/core/notification-feed.ts +263 -0
- package/plugins/autonomous-pr-loop/core/plan-parser.ts +206 -0
- package/plugins/autonomous-pr-loop/core/plugin-paths.ts +32 -0
- package/plugins/autonomous-pr-loop/core/policy.ts +65 -0
- package/plugins/autonomous-pr-loop/core/pr-lifecycle.ts +464 -0
- package/plugins/autonomous-pr-loop/core/pr-selector.ts +284 -0
- package/plugins/autonomous-pr-loop/core/profiles.ts +439 -0
- package/plugins/autonomous-pr-loop/core/redaction.ts +17 -0
- package/plugins/autonomous-pr-loop/core/repo-root.ts +22 -0
- package/plugins/autonomous-pr-loop/core/review-comments.ts +77 -0
- package/plugins/autonomous-pr-loop/core/scope-guard.ts +179 -0
- package/plugins/autonomous-pr-loop/core/state-machine.ts +828 -0
- package/plugins/autonomous-pr-loop/core/state-types.ts +130 -0
- package/plugins/autonomous-pr-loop/core/storage.ts +2527 -0
- package/plugins/autonomous-pr-loop/core/types.ts +567 -0
- package/plugins/autonomous-pr-loop/core/worker-events.ts +412 -0
- package/plugins/autonomous-pr-loop/core/worker-policy.ts +72 -0
- package/plugins/autonomous-pr-loop/core/worker-prompts.ts +182 -0
- package/plugins/autonomous-pr-loop/core/worker.ts +809 -0
- package/plugins/autonomous-pr-loop/core/workflow-board.ts +1515 -0
- package/plugins/autonomous-pr-loop/hooks/dist/permission-request.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/dist/post-compact.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/dist/post-tool-use.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/dist/pre-compact.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/dist/pre-tool-use.js +3460 -0
- package/plugins/autonomous-pr-loop/hooks/dist/session-start.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/dist/stop.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/dist/user-prompt-submit.js +2462 -0
- package/plugins/autonomous-pr-loop/hooks/hooks.json +106 -0
- package/plugins/autonomous-pr-loop/hooks/observe-runner.ts +25 -0
- package/plugins/autonomous-pr-loop/hooks/permission-request.ts +4 -0
- package/plugins/autonomous-pr-loop/hooks/post-compact.ts +4 -0
- package/plugins/autonomous-pr-loop/hooks/post-tool-use.ts +4 -0
- package/plugins/autonomous-pr-loop/hooks/pre-compact.ts +4 -0
- package/plugins/autonomous-pr-loop/hooks/pre-tool-use.ts +44 -0
- package/plugins/autonomous-pr-loop/hooks/session-start.ts +4 -0
- package/plugins/autonomous-pr-loop/hooks/stop.ts +4 -0
- package/plugins/autonomous-pr-loop/hooks/user-prompt-submit.ts +4 -0
- package/plugins/autonomous-pr-loop/mcp-server/src/index.ts +87 -0
- package/plugins/autonomous-pr-loop/mcp-server/src/tools.ts +205 -0
- package/plugins/autonomous-pr-loop/package.json +9 -0
- package/plugins/autonomous-pr-loop/schemas/config.schema.json +74 -0
- package/plugins/autonomous-pr-loop/schemas/marketplace.schema.json +46 -0
- package/plugins/autonomous-pr-loop/schemas/plugin.schema.json +32 -0
- package/plugins/autonomous-pr-loop/schemas/state.schema.json +19 -0
- package/plugins/autonomous-pr-loop/schemas/worker-event.schema.json +19 -0
- package/plugins/autonomous-pr-loop/schemas/worker-result.schema.json +58 -0
- package/plugins/autonomous-pr-loop/scripts/agent-loop.ts +44 -0
- package/plugins/autonomous-pr-loop/skills/autonomous-pr-loop/SKILL.md +26 -0
- package/plugins/autonomous-pr-loop/skills/autonomous-pr-loop/agents/openai.yaml +6 -0
- package/plugins/autonomous-pr-loop/ui/index.html +26 -0
- package/plugins/autonomous-pr-loop/ui/public/favicon.svg +7 -0
- package/plugins/autonomous-pr-loop/ui/src/api.ts +639 -0
- package/plugins/autonomous-pr-loop/ui/src/app.tsx +238 -0
- package/plugins/autonomous-pr-loop/ui/src/components/ActivityBadge.tsx +31 -0
- package/plugins/autonomous-pr-loop/ui/src/components/BrandMark.tsx +36 -0
- package/plugins/autonomous-pr-loop/ui/src/components/Collapsible.tsx +6 -0
- package/plugins/autonomous-pr-loop/ui/src/components/CommandPreview.tsx +15 -0
- package/plugins/autonomous-pr-loop/ui/src/components/ConfigEditor.tsx +389 -0
- package/plugins/autonomous-pr-loop/ui/src/components/EmptyState.tsx +10 -0
- package/plugins/autonomous-pr-loop/ui/src/components/ErrorState.tsx +12 -0
- package/plugins/autonomous-pr-loop/ui/src/components/List.tsx +7 -0
- package/plugins/autonomous-pr-loop/ui/src/components/MetricRow.tsx +6 -0
- package/plugins/autonomous-pr-loop/ui/src/components/ResponsiveTable.tsx +65 -0
- package/plugins/autonomous-pr-loop/ui/src/components/RiskBadge.tsx +10 -0
- package/plugins/autonomous-pr-loop/ui/src/components/StatusBadge.tsx +29 -0
- package/plugins/autonomous-pr-loop/ui/src/components/TopMetric.tsx +10 -0
- package/plugins/autonomous-pr-loop/ui/src/fixtures.ts +1152 -0
- package/plugins/autonomous-pr-loop/ui/src/i18n.ts +1105 -0
- package/plugins/autonomous-pr-loop/ui/src/main.tsx +14 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/CommandCenter.tsx +470 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/CommandCenterParts.tsx +276 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/agent-timeline/AgentTimelineView.tsx +73 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/artifact-viewer/ArtifactViewer.tsx +44 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/dry-run-preview/DryRunPreview.tsx +66 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/event-ledger/EventLedger.tsx +17 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/gate-center/GateCenter.tsx +34 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/mission-control/MissionControl.tsx +104 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/mission-control/WorkflowBoard.tsx +577 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/notifications/NotificationsView.tsx +30 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/plan-navigator/PlanNavigator.tsx +19 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/policy-config/PolicyConfig.tsx +22 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/pr-inbox/PrInbox.tsx +26 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/recovery-center/RecoveryCenter.tsx +125 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/scope-guard/ScopeGuard.tsx +16 -0
- package/plugins/autonomous-pr-loop/ui/src/pages/worker-runs/WorkerRuns.tsx +39 -0
- package/plugins/autonomous-pr-loop/ui/src/styles.css +2673 -0
- package/plugins/autonomous-pr-loop/ui/src/theme.ts +57 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Locale settings accepted by config, CLI, and dashboard controls. */
|
|
2
|
+
export const LOCALE_SETTINGS = ["zh-CN", "en-US", "system"] as const;
|
|
3
|
+
|
|
4
|
+
/** Concrete locales with available display dictionaries. */
|
|
5
|
+
export const EFFECTIVE_LOCALES = ["zh-CN", "en-US"] as const;
|
|
6
|
+
|
|
7
|
+
/** Default locale for repository config and display fallback. */
|
|
8
|
+
export const DEFAULT_LOCALE: EffectiveLocale = "zh-CN";
|
|
9
|
+
|
|
10
|
+
/** Persisted locale preference accepted by repo config and UI controls. */
|
|
11
|
+
export type LocaleSetting = (typeof LOCALE_SETTINGS)[number];
|
|
12
|
+
|
|
13
|
+
/** Concrete locale used for selecting display copy. */
|
|
14
|
+
export type EffectiveLocale = (typeof EFFECTIVE_LOCALES)[number];
|
|
15
|
+
|
|
16
|
+
/** Return true when a value is a supported persisted locale setting. */
|
|
17
|
+
export function isLocaleSetting(value: unknown): value is LocaleSetting {
|
|
18
|
+
return typeof value === "string" && LOCALE_SETTINGS.includes(value as LocaleSetting);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Normalize unknown input to a locale setting, or undefined when unsupported. */
|
|
22
|
+
export function normalizeLocaleSetting(value: unknown): LocaleSetting | undefined {
|
|
23
|
+
return isLocaleSetting(value) ? value : undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Resolve persisted/system locale settings to a concrete display locale. */
|
|
27
|
+
export function resolveEffectiveLocale(
|
|
28
|
+
setting: LocaleSetting | undefined,
|
|
29
|
+
systemLocales: readonly string[] = []
|
|
30
|
+
): EffectiveLocale {
|
|
31
|
+
if (setting === "zh-CN" || setting === "en-US") {
|
|
32
|
+
return setting;
|
|
33
|
+
}
|
|
34
|
+
return resolveSystemLocale(systemLocales);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Map browser or process locale tags to supported display locales. */
|
|
38
|
+
export function resolveSystemLocale(systemLocales: readonly string[] = []): EffectiveLocale {
|
|
39
|
+
for (const locale of systemLocales) {
|
|
40
|
+
const normalized = locale.toLowerCase();
|
|
41
|
+
if (normalized === "zh-cn" || normalized.startsWith("zh")) {
|
|
42
|
+
return "zh-CN";
|
|
43
|
+
}
|
|
44
|
+
if (normalized === "en-us" || normalized.startsWith("en")) {
|
|
45
|
+
return "en-US";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return DEFAULT_LOCALE;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Return Node's process/system locale candidates for CLI resolution. */
|
|
52
|
+
export function processLocaleCandidates(): string[] {
|
|
53
|
+
const candidates = [
|
|
54
|
+
process.env.LC_ALL,
|
|
55
|
+
process.env.LC_MESSAGES,
|
|
56
|
+
process.env.LANG,
|
|
57
|
+
Intl.DateTimeFormat().resolvedOptions().locale
|
|
58
|
+
];
|
|
59
|
+
return candidates.filter((value): value is string => typeof value === "string" && value.length > 0);
|
|
60
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { AgentLoopError } from "./errors.js";
|
|
2
|
+
import type { AgentLoopState, StateTransition } from "./state-types.js";
|
|
3
|
+
import type { LoopShapeId, WorkerType } from "./types.js";
|
|
4
|
+
|
|
5
|
+
export interface LoopShape {
|
|
6
|
+
id: LoopShapeId;
|
|
7
|
+
label: string;
|
|
8
|
+
lifecycleKind: "pr" | "generic";
|
|
9
|
+
initialState: AgentLoopState;
|
|
10
|
+
states: AgentLoopState[];
|
|
11
|
+
transitions: StateTransition[];
|
|
12
|
+
terminalStates: AgentLoopState[];
|
|
13
|
+
defaultRoleForState(state: AgentLoopState): WorkerType | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const PR_LOOP_STATES: AgentLoopState[] = [
|
|
17
|
+
"SYNC_MAIN",
|
|
18
|
+
"DISCOVER_PROGRESS",
|
|
19
|
+
"SELECT_NEXT_PR",
|
|
20
|
+
"WRITE_SPEC",
|
|
21
|
+
"CREATE_BRANCH",
|
|
22
|
+
"IMPLEMENT",
|
|
23
|
+
"SELF_CHECK",
|
|
24
|
+
"COMMIT_PUSH_PR",
|
|
25
|
+
"WAIT_REVIEW_OR_CI",
|
|
26
|
+
"FIX_REVIEW",
|
|
27
|
+
"PUSH_FIX",
|
|
28
|
+
"READY_TO_MERGE",
|
|
29
|
+
"MERGE",
|
|
30
|
+
"BLOCKED",
|
|
31
|
+
"STOPPED"
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
export const PR_LOOP_TERMINAL_STATES: AgentLoopState[] = ["BLOCKED", "STOPPED"];
|
|
35
|
+
|
|
36
|
+
export const PR_LOOP_TRANSITIONS: StateTransition[] = [
|
|
37
|
+
{ from: "SYNC_MAIN", to: "DISCOVER_PROGRESS", trigger: "step", guard: "config_present" },
|
|
38
|
+
{ from: "DISCOVER_PROGRESS", to: "SELECT_NEXT_PR", trigger: "step", guard: "config_present" },
|
|
39
|
+
{ from: "SELECT_NEXT_PR", to: "WRITE_SPEC", trigger: "step", guard: "next_pr_unique" },
|
|
40
|
+
{ from: "WRITE_SPEC", to: "CREATE_BRANCH", trigger: "step", guard: "always" },
|
|
41
|
+
{ from: "CREATE_BRANCH", to: "IMPLEMENT", trigger: "step", guard: "always" },
|
|
42
|
+
{ from: "IMPLEMENT", to: "SELF_CHECK", trigger: "step", guard: "always" },
|
|
43
|
+
{ from: "SELF_CHECK", to: "COMMIT_PUSH_PR", trigger: "step", guard: "always" },
|
|
44
|
+
{ from: "COMMIT_PUSH_PR", to: "WAIT_REVIEW_OR_CI", trigger: "step", guard: "always" },
|
|
45
|
+
{ from: "WAIT_REVIEW_OR_CI", to: "FIX_REVIEW", trigger: "step", guard: "always" },
|
|
46
|
+
{ from: "FIX_REVIEW", to: "PUSH_FIX", trigger: "step", guard: "always" },
|
|
47
|
+
{ from: "PUSH_FIX", to: "WAIT_REVIEW_OR_CI", trigger: "step", guard: "always" },
|
|
48
|
+
{ from: "WAIT_REVIEW_OR_CI", to: "READY_TO_MERGE", trigger: "step", guard: "always" },
|
|
49
|
+
{ from: "READY_TO_MERGE", to: "MERGE", trigger: "step", guard: "always" },
|
|
50
|
+
{ from: "MERGE", to: "SYNC_MAIN", trigger: "step", guard: "always" },
|
|
51
|
+
{ from: "SYNC_MAIN", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
52
|
+
{ from: "DISCOVER_PROGRESS", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
53
|
+
{ from: "SELECT_NEXT_PR", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
54
|
+
{ from: "WRITE_SPEC", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
55
|
+
{ from: "CREATE_BRANCH", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
56
|
+
{ from: "IMPLEMENT", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
57
|
+
{ from: "SELF_CHECK", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
58
|
+
{ from: "COMMIT_PUSH_PR", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
59
|
+
{ from: "WAIT_REVIEW_OR_CI", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
60
|
+
{ from: "FIX_REVIEW", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
61
|
+
{ from: "PUSH_FIX", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
62
|
+
{ from: "READY_TO_MERGE", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
63
|
+
{ from: "MERGE", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
64
|
+
{ from: "BLOCKED", to: "STOPPED", trigger: "stop", guard: "always" }
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
/** Return the default worker type delegated by the PR loop state machine. */
|
|
68
|
+
export function prLoopDefaultRoleForState(state: AgentLoopState): WorkerType | undefined {
|
|
69
|
+
if (state === "WRITE_SPEC") {
|
|
70
|
+
return "planner";
|
|
71
|
+
}
|
|
72
|
+
if (state === "IMPLEMENT") {
|
|
73
|
+
return "implementation";
|
|
74
|
+
}
|
|
75
|
+
if (state === "FIX_REVIEW") {
|
|
76
|
+
return "review-fix";
|
|
77
|
+
}
|
|
78
|
+
if (state === "SELF_CHECK") {
|
|
79
|
+
return "reviewer";
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const PR_LOOP_SHAPE: LoopShape = {
|
|
85
|
+
id: "pr-loop",
|
|
86
|
+
label: "PR Loop",
|
|
87
|
+
lifecycleKind: "pr",
|
|
88
|
+
initialState: "SYNC_MAIN",
|
|
89
|
+
states: PR_LOOP_STATES,
|
|
90
|
+
transitions: PR_LOOP_TRANSITIONS,
|
|
91
|
+
terminalStates: PR_LOOP_TERMINAL_STATES,
|
|
92
|
+
defaultRoleForState: prLoopDefaultRoleForState
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const GENERIC_LOOP_STATES: AgentLoopState[] = [
|
|
96
|
+
"DEFINE_GOAL",
|
|
97
|
+
"COLLECT_CONTEXT",
|
|
98
|
+
"PLAN_WORK",
|
|
99
|
+
"EXECUTE_STEP",
|
|
100
|
+
"SELF_REVIEW",
|
|
101
|
+
"HUMAN_GATE",
|
|
102
|
+
"DELIVER",
|
|
103
|
+
"COMPLETE",
|
|
104
|
+
"BLOCKED",
|
|
105
|
+
"STOPPED"
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
export const GENERIC_LOOP_TERMINAL_STATES: AgentLoopState[] = ["COMPLETE", "BLOCKED", "STOPPED"];
|
|
109
|
+
|
|
110
|
+
export const GENERIC_LOOP_TRANSITIONS: StateTransition[] = [
|
|
111
|
+
// Raised by a missing goal-confirmation decision before lifecycle returns a guard.
|
|
112
|
+
{ from: "DEFINE_GOAL", to: "BLOCKED", trigger: "step", guard: "goal_unclear" },
|
|
113
|
+
{ from: "DEFINE_GOAL", to: "COLLECT_CONTEXT", trigger: "step", guard: "goal_clear" },
|
|
114
|
+
{ from: "DEFINE_GOAL", to: "PLAN_WORK", trigger: "step", guard: "skip_context" },
|
|
115
|
+
{ from: "DEFINE_GOAL", to: "STOPPED", trigger: "step", guard: "rejected" },
|
|
116
|
+
{ from: "COLLECT_CONTEXT", to: "PLAN_WORK", trigger: "step", guard: "always" },
|
|
117
|
+
{ from: "PLAN_WORK", to: "EXECUTE_STEP", trigger: "step", guard: "always" },
|
|
118
|
+
{ from: "EXECUTE_STEP", to: "BLOCKED", trigger: "step", guard: "scope_change_requested" },
|
|
119
|
+
{ from: "EXECUTE_STEP", to: "PLAN_WORK", trigger: "step", guard: "scope_change_approved" },
|
|
120
|
+
{ from: "EXECUTE_STEP", to: "SELF_REVIEW", trigger: "step", guard: "always" },
|
|
121
|
+
{ from: "EXECUTE_STEP", to: "STOPPED", trigger: "step", guard: "rejected" },
|
|
122
|
+
{ from: "SELF_REVIEW", to: "EXECUTE_STEP", trigger: "step", guard: "fix_needed_cycles_remain" },
|
|
123
|
+
{ from: "SELF_REVIEW", to: "HUMAN_GATE", trigger: "step", guard: "review_passed" },
|
|
124
|
+
{ from: "SELF_REVIEW", to: "HUMAN_GATE", trigger: "step", guard: "review_cycles_exhausted" },
|
|
125
|
+
{ from: "HUMAN_GATE", to: "DELIVER", trigger: "step", guard: "deliverable_approved" },
|
|
126
|
+
{ from: "HUMAN_GATE", to: "EXECUTE_STEP", trigger: "step", guard: "request_changes" },
|
|
127
|
+
{ from: "HUMAN_GATE", to: "STOPPED", trigger: "step", guard: "rejected" },
|
|
128
|
+
{ from: "DELIVER", to: "COMPLETE", trigger: "step", guard: "always" },
|
|
129
|
+
{ from: "DEFINE_GOAL", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
130
|
+
{ from: "COLLECT_CONTEXT", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
131
|
+
{ from: "PLAN_WORK", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
132
|
+
{ from: "EXECUTE_STEP", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
133
|
+
{ from: "SELF_REVIEW", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
134
|
+
{ from: "HUMAN_GATE", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
135
|
+
{ from: "DELIVER", to: "STOPPED", trigger: "stop", guard: "always" },
|
|
136
|
+
{ from: "BLOCKED", to: "STOPPED", trigger: "stop", guard: "always" }
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
/** Return the default worker type delegated by the generic loop state machine. */
|
|
140
|
+
export function genericLoopDefaultRoleForState(state: AgentLoopState): WorkerType | undefined {
|
|
141
|
+
if (state === "DEFINE_GOAL" || state === "COLLECT_CONTEXT" || state === "PLAN_WORK") {
|
|
142
|
+
return "planner";
|
|
143
|
+
}
|
|
144
|
+
if (state === "EXECUTE_STEP" || state === "DELIVER") {
|
|
145
|
+
return "implementation";
|
|
146
|
+
}
|
|
147
|
+
if (state === "SELF_REVIEW") {
|
|
148
|
+
return "reviewer";
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export const GENERIC_LOOP_SHAPE: LoopShape = {
|
|
154
|
+
id: "generic-loop",
|
|
155
|
+
label: "Generic Loop",
|
|
156
|
+
lifecycleKind: "generic",
|
|
157
|
+
initialState: "DEFINE_GOAL",
|
|
158
|
+
states: GENERIC_LOOP_STATES,
|
|
159
|
+
transitions: GENERIC_LOOP_TRANSITIONS,
|
|
160
|
+
terminalStates: GENERIC_LOOP_TERMINAL_STATES,
|
|
161
|
+
defaultRoleForState: genericLoopDefaultRoleForState
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const LOOP_SHAPES: Record<LoopShapeId, LoopShape> = {
|
|
165
|
+
"pr-loop": PR_LOOP_SHAPE,
|
|
166
|
+
"generic-loop": GENERIC_LOOP_SHAPE
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/** Resolve a configured loop shape, rejecting future unsupported shapes. */
|
|
170
|
+
export function resolveLoopShape(id: string): LoopShape {
|
|
171
|
+
if (id in LOOP_SHAPES) {
|
|
172
|
+
return LOOP_SHAPES[id as LoopShapeId];
|
|
173
|
+
}
|
|
174
|
+
throw new AgentLoopError("invalid_config", "Config loopShape is invalid.");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function loopShapeIds(): LoopShapeId[] {
|
|
178
|
+
return Object.keys(LOOP_SHAPES) as LoopShapeId[];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function sandboxForShapeState(
|
|
182
|
+
shapeId: LoopShapeId,
|
|
183
|
+
state: AgentLoopState,
|
|
184
|
+
workerType: WorkerType
|
|
185
|
+
): "read-only" | "workspace-write" {
|
|
186
|
+
if (shapeId === "generic-loop" && ["DEFINE_GOAL", "COLLECT_CONTEXT", "PLAN_WORK", "SELF_REVIEW"].includes(state)) {
|
|
187
|
+
return "read-only";
|
|
188
|
+
}
|
|
189
|
+
return workerType === "reviewer" ? "read-only" : "workspace-write";
|
|
190
|
+
}
|