@bastani/atomic 0.9.16-alpha.7 → 0.9.16-alpha.8
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/CHANGELOG.md +19 -0
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/README.md +4 -4
- package/dist/builtin/intercom/broker/broker.ts +617 -22
- package/dist/builtin/intercom/broker/client-message-validation.ts +9 -0
- package/dist/builtin/intercom/broker/client.ts +200 -10
- package/dist/builtin/intercom/broker/pending-send-registry.ts +4 -0
- package/dist/builtin/intercom/broker/send-handler.ts +90 -36
- package/dist/builtin/intercom/broker/send-signature.ts +20 -8
- package/dist/builtin/intercom/group.ts +85 -0
- package/dist/builtin/intercom/index.bundle.mjs +680 -53
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/session-target.ts +54 -0
- package/dist/builtin/intercom/skills/intercom/SKILL.md +18 -3
- package/dist/builtin/intercom/source-ownership.ts +31 -0
- package/dist/builtin/intercom/types.ts +115 -0
- package/dist/builtin/mcp/index.bundle.mjs +109 -35
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +173 -51
- package/dist/builtin/web-access/index.bundle.mjs +109 -35
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +15 -0
- package/dist/builtin/workflows/README.md +40 -37
- package/dist/builtin/workflows/builtin/adversarial-verification.js +13 -0
- package/dist/builtin/workflows/builtin/{shared-prompts.ts → chunk-0x6e303p.js} +133 -154
- package/dist/builtin/workflows/builtin/chunk-29wrp38a.js +199 -0
- package/dist/builtin/workflows/builtin/chunk-2dqb5s2q.js +602 -0
- package/dist/builtin/workflows/builtin/chunk-4febxsv4.js +264 -0
- package/dist/builtin/workflows/builtin/chunk-5n10x7j2.js +69730 -0
- package/dist/builtin/workflows/builtin/chunk-5wgwscd0.js +4 -0
- package/dist/builtin/workflows/builtin/chunk-6fqs7c01.js +155 -0
- package/dist/builtin/workflows/builtin/chunk-7430zyas.js +126 -0
- package/dist/builtin/workflows/builtin/chunk-7at6dnkr.js +33 -0
- package/dist/builtin/workflows/builtin/chunk-82ha8p41.js +175 -0
- package/dist/builtin/workflows/builtin/chunk-bfkmzv9h.js +156 -0
- package/dist/builtin/workflows/builtin/chunk-c53y8bdh.js +345 -0
- package/dist/builtin/workflows/builtin/chunk-cdtd3m3w.js +529 -0
- package/dist/builtin/workflows/builtin/chunk-cg9tmks0.js +206 -0
- package/dist/builtin/workflows/builtin/chunk-hdpj1dkw.js +2447 -0
- package/dist/builtin/workflows/builtin/chunk-hzzn6adg.js +221 -0
- package/dist/builtin/workflows/builtin/chunk-nqr34qp3.js +1061 -0
- package/dist/builtin/workflows/builtin/chunk-qwzvgxnq.js +404 -0
- package/dist/builtin/workflows/builtin/chunk-qx2ptjs3.js +215 -0
- package/dist/builtin/workflows/builtin/chunk-v04c5qmd.js +1207 -0
- package/dist/builtin/workflows/builtin/chunk-wpckd35c.js +12 -0
- package/dist/builtin/workflows/builtin/chunk-x2ghn0je.js +4110 -0
- package/dist/builtin/workflows/builtin/chunk-zf28603f.js +1080 -0
- package/dist/builtin/workflows/builtin/classify-and-act.js +12 -0
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +10 -0
- package/dist/builtin/workflows/builtin/generate-and-filter.js +12 -0
- package/dist/builtin/workflows/builtin/goal.js +16 -0
- package/dist/builtin/workflows/builtin/index.js +49 -0
- package/dist/builtin/workflows/builtin/loop-until-done.js +12 -0
- package/dist/builtin/workflows/builtin/open-claude-design.js +11 -0
- package/dist/builtin/workflows/builtin/ralph.js +16 -0
- package/dist/builtin/workflows/builtin/steering-context.d.ts +6 -0
- package/dist/builtin/workflows/builtin/steering-context.js +7 -0
- package/dist/builtin/workflows/builtin/tournament.js +13 -0
- package/dist/builtin/workflows/package.json +10 -7
- package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +41 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +1228 -428
- package/dist/builtin/workflows/src/{index.bundle.mjs → index.js} +956 -427
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +403 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +327 -0
- package/dist/builtin/workflows/src/shared/budget.d.ts +67 -0
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +60 -0
- package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +21 -0
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +12 -5
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.js +2 -0
- package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +2 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -0
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/builtin-install-layout.d.ts +1 -1
- package/dist/core/builtin-install-layout.d.ts.map +1 -1
- package/dist/core/builtin-install-layout.js +1 -1
- package/dist/core/builtin-install-layout.js.map +1 -1
- package/dist/core/codex-fast-mode.d.ts +10 -7
- package/dist/core/codex-fast-mode.d.ts.map +1 -1
- package/dist/core/codex-fast-mode.js +31 -13
- package/dist/core/codex-fast-mode.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +35 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +6 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/model-runtime.d.ts +2 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +4 -0
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +1 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +8 -0
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -5
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-storage.d.ts +2 -0
- package/dist/core/session-manager-storage.d.ts.map +1 -1
- package/dist/core/session-manager-storage.js +4 -2
- package/dist/core/session-manager-storage.js.map +1 -1
- package/dist/core/slash-commands.js +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/workflow-stage-admission.d.ts +6 -1
- package/dist/core/workflow-stage-admission.d.ts.map +1 -1
- package/dist/core/workflow-stage-admission.js +8 -9
- package/dist/core/workflow-stage-admission.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +1 -1
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts +4 -0
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +69 -10
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/rpc/rpc-client-api.d.ts +18 -2
- package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-api.js +33 -5
- package/dist/modes/rpc/rpc-client-api.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +8 -4
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +13 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/intercom.md +15 -6
- package/docs/packages.md +2 -2
- package/docs/providers.md +8 -3
- package/docs/quickstart.md +2 -2
- package/docs/rpc.md +21 -4
- package/docs/settings.md +6 -4
- package/docs/subagents.md +1 -1
- package/docs/usage.md +1 -1
- package/docs/workflows.md +108 -239
- package/npm-shrinkwrap.json +32 -32
- package/package.json +9 -13
- package/dist/builtin/workflows/ambient.d.ts +0 -61
- package/dist/builtin/workflows/builtin/adversarial-verification-prompts.ts +0 -26
- package/dist/builtin/workflows/builtin/adversarial-verification-runner.ts +0 -391
- package/dist/builtin/workflows/builtin/adversarial-verification.ts +0 -34
- package/dist/builtin/workflows/builtin/classify-and-act-prompts.ts +0 -14
- package/dist/builtin/workflows/builtin/classify-and-act-runner.ts +0 -108
- package/dist/builtin/workflows/builtin/classify-and-act.ts +0 -40
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize-prompts.ts +0 -14
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize-runner.ts +0 -96
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +0 -37
- package/dist/builtin/workflows/builtin/generate-and-filter-prompts.ts +0 -41
- package/dist/builtin/workflows/builtin/generate-and-filter-runner.ts +0 -90
- package/dist/builtin/workflows/builtin/generate-and-filter.ts +0 -31
- package/dist/builtin/workflows/builtin/goal-artifacts.ts +0 -64
- package/dist/builtin/workflows/builtin/goal-convergence.ts +0 -87
- package/dist/builtin/workflows/builtin/goal-ledger.ts +0 -139
- package/dist/builtin/workflows/builtin/goal-models.ts +0 -72
- package/dist/builtin/workflows/builtin/goal-orchestrator-prompts.ts +0 -94
- package/dist/builtin/workflows/builtin/goal-prompts.ts +0 -217
- package/dist/builtin/workflows/builtin/goal-reducer.ts +0 -176
- package/dist/builtin/workflows/builtin/goal-reports.ts +0 -76
- package/dist/builtin/workflows/builtin/goal-reverify.ts +0 -305
- package/dist/builtin/workflows/builtin/goal-review.ts +0 -139
- package/dist/builtin/workflows/builtin/goal-runner.ts +0 -504
- package/dist/builtin/workflows/builtin/goal-schemas.ts +0 -89
- package/dist/builtin/workflows/builtin/goal-types.ts +0 -164
- package/dist/builtin/workflows/builtin/goal.ts +0 -78
- package/dist/builtin/workflows/builtin/index.ts +0 -16
- package/dist/builtin/workflows/builtin/loop-until-done-prompts.ts +0 -87
- package/dist/builtin/workflows/builtin/loop-until-done-runner.ts +0 -282
- package/dist/builtin/workflows/builtin/loop-until-done.ts +0 -51
- package/dist/builtin/workflows/builtin/open-claude-design-live-protocol.ts +0 -305
- package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +0 -337
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +0 -347
- package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +0 -313
- package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +0 -311
- package/dist/builtin/workflows/builtin/open-claude-design.ts +0 -57
- package/dist/builtin/workflows/builtin/pattern-artifact-root.ts +0 -28
- package/dist/builtin/workflows/builtin/progress-scoring.ts +0 -230
- package/dist/builtin/workflows/builtin/ralph-core.ts +0 -449
- package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +0 -100
- package/dist/builtin/workflows/builtin/ralph-models.ts +0 -183
- package/dist/builtin/workflows/builtin/ralph-review-gate.ts +0 -103
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +0 -104
- package/dist/builtin/workflows/builtin/ralph-runner.ts +0 -459
- package/dist/builtin/workflows/builtin/ralph.ts +0 -82
- package/dist/builtin/workflows/builtin/review-convergence.ts +0 -229
- package/dist/builtin/workflows/builtin/selection-math.ts +0 -156
- package/dist/builtin/workflows/builtin/steering-context.ts +0 -51
- package/dist/builtin/workflows/builtin/tournament-prompts.ts +0 -70
- package/dist/builtin/workflows/builtin/tournament-runner.ts +0 -400
- package/dist/builtin/workflows/builtin/tournament.ts +0 -73
- package/dist/builtin/workflows/builtin/verification-criteria.ts +0 -330
- package/dist/builtin/workflows/builtin/verification-prompts.ts +0 -206
- package/dist/builtin/workflows/builtin/verification-usage.ts +0 -44
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { Type } from "typebox";
|
|
4
|
-
import { VERIFICATION_SCALE } from "./verification-criteria.js";
|
|
5
|
-
import type { WorkflowTaskResult } from "../src/shared/types.js";
|
|
6
|
-
import { createWorkflowArtifactDirectory } from "../src/shared/workflow-artifacts.js";
|
|
7
|
-
import {
|
|
8
|
-
E2E_VERIFICATION_GUIDANCE,
|
|
9
|
-
keepContext,
|
|
10
|
-
LITERAL_OBJECTIVE_CONTRACT,
|
|
11
|
-
} from "./shared-prompts.js";
|
|
12
|
-
import type { ReviewDecision, ReviewFinding } from "./ralph-review-gate.js";
|
|
13
|
-
import { reviewDecisionApproved } from "./ralph-review-gate.js";
|
|
14
|
-
import {
|
|
15
|
-
parseFailureDiagnostics,
|
|
16
|
-
finalActionRemaining,
|
|
17
|
-
reviewerFailureText,
|
|
18
|
-
summarizeReviewConvergence,
|
|
19
|
-
type ConsolidatedFinding,
|
|
20
|
-
type ParsedReviewDecision,
|
|
21
|
-
type ReviewConvergenceSummary,
|
|
22
|
-
} from "./review-convergence.js";
|
|
23
|
-
import type { ConvergenceEntry } from "./goal-convergence.js";
|
|
24
|
-
import type { ReverifyAuditEntry } from "./goal-reverify.js";
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export const DEFAULT_MAX_LOOPS = 10;
|
|
28
|
-
const DEFAULT_RESEARCH_DIR = "research";
|
|
29
|
-
const IMPLEMENTATION_NOTES_FILENAME = "implementation-notes.md";
|
|
30
|
-
const QA_E2E_VIDEO_FILENAME = "qa-e2e-evidence.webm";
|
|
31
|
-
const MAX_RESEARCH_SLUG_LENGTH = 80;
|
|
32
|
-
// Reviewer fan-out launches two independent reviewers; the loop stops only when
|
|
33
|
-
// both reviewers independently approve. Approval is severity-aware: a reviewer
|
|
34
|
-
// approves when it judged the patch correct, reported no reviewer_error, and
|
|
35
|
-
// filed no *blocking* (P0/P1/P2) finding. P3 nice-to-haves no longer keep the
|
|
36
|
-
// loop iterating, so a single low-priority nit (or a placeholder finding) can no
|
|
37
|
-
// longer strand an otherwise-approved patch. Requiring unanimous approval still
|
|
38
|
-
// means a blocking finding from either reviewer keeps the loop going. See
|
|
39
|
-
// ./ralph-review-gate.ts for the gate types and decision logic.
|
|
40
|
-
export const REVIEWER_COUNT = 2;
|
|
41
|
-
|
|
42
|
-
const reviewFindingSchema = Type.Object(
|
|
43
|
-
{
|
|
44
|
-
title: Type.String(),
|
|
45
|
-
body: Type.String(),
|
|
46
|
-
confidence_score: Type.Number({ minimum: 0, maximum: 1 }),
|
|
47
|
-
objective_alignment: Type.Union([
|
|
48
|
-
Type.Literal("required_by_objective"),
|
|
49
|
-
Type.Literal("consistent_with_objective"),
|
|
50
|
-
Type.Literal("beyond_objective"),
|
|
51
|
-
Type.Literal("contradicts_objective"),
|
|
52
|
-
]),
|
|
53
|
-
priority: Type.Optional(
|
|
54
|
-
Type.Union([Type.Integer({ minimum: 0, maximum: 3 }), Type.Null()]),
|
|
55
|
-
),
|
|
56
|
-
code_location: Type.Object(
|
|
57
|
-
{
|
|
58
|
-
absolute_file_path: Type.String(),
|
|
59
|
-
line_range: Type.Object(
|
|
60
|
-
{
|
|
61
|
-
start: Type.Integer({ minimum: 1 }),
|
|
62
|
-
end: Type.Integer({ minimum: 1 }),
|
|
63
|
-
},
|
|
64
|
-
{ additionalProperties: false },
|
|
65
|
-
),
|
|
66
|
-
},
|
|
67
|
-
{ additionalProperties: false },
|
|
68
|
-
),
|
|
69
|
-
},
|
|
70
|
-
{ additionalProperties: false },
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const requirementsTraceabilitySchema = Type.Object(
|
|
74
|
-
{
|
|
75
|
-
requirement: Type.String(),
|
|
76
|
-
status: Type.Union([
|
|
77
|
-
Type.Literal("proven"),
|
|
78
|
-
Type.Literal("contradicted"),
|
|
79
|
-
Type.Literal("missing"),
|
|
80
|
-
Type.Literal("unverified"),
|
|
81
|
-
]),
|
|
82
|
-
evidence: Type.String(),
|
|
83
|
-
},
|
|
84
|
-
{ additionalProperties: false },
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
const reviewerErrorSchema = Type.Object(
|
|
88
|
-
{
|
|
89
|
-
kind: Type.Union([
|
|
90
|
-
Type.Literal("validation_unavailable"),
|
|
91
|
-
Type.Literal("dependency_unavailable"),
|
|
92
|
-
Type.Literal("tool_failure"),
|
|
93
|
-
Type.Literal("reviewer_failure"),
|
|
94
|
-
]),
|
|
95
|
-
message: Type.String(),
|
|
96
|
-
attempted_recovery: Type.String(),
|
|
97
|
-
},
|
|
98
|
-
{ additionalProperties: false },
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
export const reviewDecisionSchema = Type.Object(
|
|
102
|
-
{
|
|
103
|
-
findings: Type.Array(reviewFindingSchema),
|
|
104
|
-
overall_correctness: Type.Union([
|
|
105
|
-
Type.Literal("patch is correct"),
|
|
106
|
-
Type.Literal("patch is incorrect"),
|
|
107
|
-
]),
|
|
108
|
-
overall_explanation: Type.String(),
|
|
109
|
-
overall_confidence_score: Type.Number({ minimum: 0, maximum: 1 }),
|
|
110
|
-
criterion_scores: Type.Optional(
|
|
111
|
-
Type.Array(Type.Object({
|
|
112
|
-
criterion_id: Type.String(),
|
|
113
|
-
score: VERIFICATION_SCALE.schema,
|
|
114
|
-
}, { additionalProperties: false })),
|
|
115
|
-
),
|
|
116
|
-
requirements_traceability: Type.Array(requirementsTraceabilitySchema),
|
|
117
|
-
stop_review_loop: Type.Boolean(),
|
|
118
|
-
reviewer_error: Type.Optional(
|
|
119
|
-
Type.Union([Type.Null(), reviewerErrorSchema]),
|
|
120
|
-
),
|
|
121
|
-
},
|
|
122
|
-
{ additionalProperties: false },
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
export type PromptSection = readonly [tag: string, content: string];
|
|
126
|
-
|
|
127
|
-
export function taggedPrompt(sections: readonly PromptSection[]): string {
|
|
128
|
-
return sections
|
|
129
|
-
.map(([tag, content]) => {
|
|
130
|
-
const trimmed = content.trim();
|
|
131
|
-
return `<${tag}>\n${trimmed}\n</${tag}>`;
|
|
132
|
-
})
|
|
133
|
-
.join("\n\n");
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function workflowCwdContextSection(workflowCwd: string): PromptSection {
|
|
137
|
-
return [
|
|
138
|
-
"context",
|
|
139
|
-
[
|
|
140
|
-
`Current working directory: ${workflowCwd}`,
|
|
141
|
-
"Use this as the starting directory for repository work in this stage.",
|
|
142
|
-
"Shell commands and relative file paths should be relative to this directory unless you intentionally pass an explicit cwd override.",
|
|
143
|
-
"When delegating subagents, pass along that this is the current working directory.",
|
|
144
|
-
].join("\n"),
|
|
145
|
-
];
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export function positiveInteger(value: number | undefined, fallback: number): number {
|
|
149
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0
|
|
150
|
-
? Math.floor(value)
|
|
151
|
-
: fallback;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export function normalizeBranchInput(
|
|
155
|
-
value: string | undefined,
|
|
156
|
-
fallback: string,
|
|
157
|
-
): string {
|
|
158
|
-
const trimmed = value?.trim();
|
|
159
|
-
if (!trimmed) return fallback;
|
|
160
|
-
|
|
161
|
-
const looksLikeSafeGitRef =
|
|
162
|
-
/^(?!-)(?!.*(?:\.\.|@\{|\/\/|\.lock(?:\/|$)))[A-Za-z0-9][A-Za-z0-9._/@+-]*$/.test(
|
|
163
|
-
trimmed,
|
|
164
|
-
);
|
|
165
|
-
return looksLikeSafeGitRef ? trimmed : fallback;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function slugifyResearchTopic(prompt: string): string {
|
|
169
|
-
const slug = prompt
|
|
170
|
-
.toLowerCase()
|
|
171
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
172
|
-
.replace(/^-+|-+$/g, "")
|
|
173
|
-
.slice(0, MAX_RESEARCH_SLUG_LENGTH)
|
|
174
|
-
.replace(/-+$/g, "");
|
|
175
|
-
return slug.length > 0 ? slug : "research";
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function defaultResearchPath(prompt: string, now = new Date()): string {
|
|
179
|
-
const date = now.toISOString().slice(0, 10);
|
|
180
|
-
return join(DEFAULT_RESEARCH_DIR, `${date}-${slugifyResearchTopic(prompt)}.md`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export async function createImplementationNotesFile(prompt: string, runId?: string): Promise<string> {
|
|
184
|
-
const notesDir = await createWorkflowArtifactDirectory(runId);
|
|
185
|
-
const notesPath = join(notesDir, IMPLEMENTATION_NOTES_FILENAME);
|
|
186
|
-
const initialNotes = [
|
|
187
|
-
"# Implementation Notes",
|
|
188
|
-
"",
|
|
189
|
-
`Task: ${prompt || "(empty prompt)"}`,
|
|
190
|
-
"",
|
|
191
|
-
"## Running Notes",
|
|
192
|
-
"",
|
|
193
|
-
"- Record implementation decisions, deviations from research, tradeoffs, blockers, validation outcomes, and user-relevant facts. Keep entries concise and readable.",
|
|
194
|
-
"- Before reporting progress, audit each claim against a tool result from this session. Report only work you can point to evidence for; say so explicitly when something is unverified.",
|
|
195
|
-
].join("\n");
|
|
196
|
-
await writeFile(notesPath, `${initialNotes}\n`, {
|
|
197
|
-
encoding: "utf8",
|
|
198
|
-
flag: "wx",
|
|
199
|
-
});
|
|
200
|
-
return notesPath;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Stable absolute path the orchestrator records the QA end-to-end proof video to.
|
|
204
|
-
// The directory is created up front so `playwright-cli video-start <path>` can
|
|
205
|
-
// write to it; the video file itself is produced by the orchestrator's QA pass
|
|
206
|
-
// (and overwritten each iteration so it always reflects the latest state). The
|
|
207
|
-
// final pull-request stage attaches it when it exists.
|
|
208
|
-
export async function createQaEvidenceVideoPath(runId?: string): Promise<string> {
|
|
209
|
-
const qaDir = await createWorkflowArtifactDirectory(runId);
|
|
210
|
-
return join(qaDir, QA_E2E_VIDEO_FILENAME);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function renderQaE2eVideoGuidance(qaVideoPath: string): string {
|
|
214
|
-
return [
|
|
215
|
-
E2E_VERIFICATION_GUIDANCE,
|
|
216
|
-
`For a user-visible UI scenario, record the QA pass for review. After \`playwright-cli open\`, use \`playwright-cli video-start ${qaVideoPath}\`, annotate with \`playwright-cli video-chapter\` / \`playwright-cli video-show-actions\`, exercise the complete scenario, then run \`playwright-cli video-stop\`. Write to exactly ${qaVideoPath}, overwriting stale evidence.`,
|
|
217
|
-
`Add a \`## QA E2E Video\` entry to the implementation notes with the absolute path ${qaVideoPath} and one sentence naming the proven scenario. For changes without a user-visible UI scenario, record why video does not apply; never fabricate one.`,
|
|
218
|
-
"If `playwright-cli` or its browser runtime is unavailable, install it once per the skill (`npm install -g @playwright/cli@latest`, then `npx playwright install chromium` when needed). If a concrete attempt still fails, record the commands, observed failure output, smallest validation performed, and that no video was produced.",
|
|
219
|
-
].join("\n");
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export function reviewDecisionFromResult(result: WorkflowTaskResult): ReviewDecision | undefined {
|
|
223
|
-
return result.structured as ReviewDecision | undefined;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
export function parsedReviewDecisionFromResult(
|
|
227
|
-
result: WorkflowTaskResult,
|
|
228
|
-
reviewer: string,
|
|
229
|
-
): ParsedReviewDecision<ReviewDecision> {
|
|
230
|
-
const parsed = reviewDecisionFromResult(result);
|
|
231
|
-
if (parsed !== undefined) {
|
|
232
|
-
return { decision: parsed, parsed: true, diagnostics: [] };
|
|
233
|
-
}
|
|
234
|
-
const diagnostics = parseFailureDiagnostics(reviewer, result.text);
|
|
235
|
-
return {
|
|
236
|
-
decision: reviewerErrorDecision(diagnostics.join("\n")),
|
|
237
|
-
parsed: false,
|
|
238
|
-
diagnostics,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export function ralphReviewConvergence(args: {
|
|
243
|
-
readonly decision: ReviewDecision;
|
|
244
|
-
readonly parsed: boolean;
|
|
245
|
-
readonly diagnostics: readonly string[];
|
|
246
|
-
readonly allowFinalActionRemaining: boolean;
|
|
247
|
-
}): ReviewConvergenceSummary {
|
|
248
|
-
const approved = reviewDecisionApproved(args.decision);
|
|
249
|
-
const hasFinalActionRemaining = args.allowFinalActionRemaining &&
|
|
250
|
-
finalActionRemaining(args.decision.requirements_traceability);
|
|
251
|
-
return summarizeReviewConvergence({
|
|
252
|
-
parsed: args.parsed,
|
|
253
|
-
approved,
|
|
254
|
-
stopReviewLoop: args.decision.stop_review_loop,
|
|
255
|
-
nextAction: approved && hasFinalActionRemaining ? "pull-request" : approved ? "finish" : "implementation",
|
|
256
|
-
finalActionRemaining: approved && hasFinalActionRemaining,
|
|
257
|
-
diagnostics: args.diagnostics,
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export function reviewerErrorDecision(error: string): ReviewDecision {
|
|
262
|
-
return {
|
|
263
|
-
findings: [],
|
|
264
|
-
overall_correctness: "patch is incorrect",
|
|
265
|
-
overall_explanation:
|
|
266
|
-
"Reviewer execution failed, so the review gate cannot safely approve the current repository state.",
|
|
267
|
-
overall_confidence_score: 0,
|
|
268
|
-
stop_review_loop: false,
|
|
269
|
-
requirements_traceability: [],
|
|
270
|
-
reviewer_error: {
|
|
271
|
-
kind: "reviewer_failure",
|
|
272
|
-
message: error,
|
|
273
|
-
attempted_recovery:
|
|
274
|
-
"Model fallbacks were configured for the reviewer stage; continuing without approval.",
|
|
275
|
-
},
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export function reviewerErrorResult(
|
|
280
|
-
error: unknown,
|
|
281
|
-
): WorkflowTaskResult {
|
|
282
|
-
return {
|
|
283
|
-
name: "reviewer-error",
|
|
284
|
-
stageName: "reviewer-error",
|
|
285
|
-
text: reviewerFailureText(error),
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export function artifactSafeName(value: string): string {
|
|
290
|
-
const safe = value
|
|
291
|
-
.toLowerCase()
|
|
292
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
293
|
-
.replace(/^-+|-+$/g, "");
|
|
294
|
-
return safe.length > 0 ? safe : "artifact";
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
type ReviewArtifact = {
|
|
298
|
-
readonly reviewer: string;
|
|
299
|
-
readonly decision: ReviewDecision;
|
|
300
|
-
readonly convergence_decision: ReviewConvergenceSummary;
|
|
301
|
-
readonly raw_text: string;
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
type ReviewRoundArtifact = {
|
|
305
|
-
readonly convergence_decision: ReviewConvergenceSummary;
|
|
306
|
-
readonly convergence: readonly ConvergenceEntry[];
|
|
307
|
-
readonly consolidated_findings?: readonly ConsolidatedFinding<ReviewFinding>[];
|
|
308
|
-
readonly reverification?: readonly ReverifyAuditEntry<ReviewFinding>[];
|
|
309
|
-
readonly reviews: readonly {
|
|
310
|
-
readonly reviewer: string;
|
|
311
|
-
readonly artifact_path: string;
|
|
312
|
-
readonly decision: ReviewDecision;
|
|
313
|
-
readonly convergence_decision: ReviewConvergenceSummary;
|
|
314
|
-
}[];
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
export async function writeJsonArtifact(path: string, content: ReviewArtifact | ReviewRoundArtifact): Promise<string> {
|
|
318
|
-
await mkdir(dirname(path), { recursive: true });
|
|
319
|
-
await writeFile(path, `${JSON.stringify(content, null, 2)}\n`, {
|
|
320
|
-
encoding: "utf8",
|
|
321
|
-
});
|
|
322
|
-
return path;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
export function compactReviewReport(path: string | undefined): string {
|
|
326
|
-
return path === undefined
|
|
327
|
-
? "No reviewer artifact was produced."
|
|
328
|
-
: `Latest review round artifact: ${path}`;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
type ForkContinuationOptions = {
|
|
332
|
-
readonly context?: "fork";
|
|
333
|
-
readonly forkFromSessionFile?: string;
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
export function forkContinuationOptions(
|
|
337
|
-
sessionFile: string | undefined,
|
|
338
|
-
): ForkContinuationOptions {
|
|
339
|
-
return sessionFile === undefined || sessionFile.length === 0
|
|
340
|
-
? {}
|
|
341
|
-
: { context: "fork", forkFromSessionFile: sessionFile };
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export function renderResearchPromptRefinementPrompt(args: {
|
|
345
|
-
readonly request: string;
|
|
346
|
-
readonly acceptanceCriteria: string;
|
|
347
|
-
readonly workflowCwdContext: PromptSection;
|
|
348
|
-
readonly latestReviewReportPath: string | undefined;
|
|
349
|
-
}): string {
|
|
350
|
-
return taggedPrompt([
|
|
351
|
-
["acceptance_criteria", keepContext(args.acceptanceCriteria)],
|
|
352
|
-
["literal_contract", LITERAL_OBJECTIVE_CONTRACT],
|
|
353
|
-
args.workflowCwdContext,
|
|
354
|
-
[
|
|
355
|
-
"review_findings",
|
|
356
|
-
args.latestReviewReportPath === undefined
|
|
357
|
-
? "No prior review artifact is available."
|
|
358
|
-
: [
|
|
359
|
-
`Latest review round artifact: ${args.latestReviewReportPath}`,
|
|
360
|
-
"Include unresolved reviewer findings in the transformed research question only when consistent with the literal objective and acceptance criteria.",
|
|
361
|
-
].join("\n"),
|
|
362
|
-
],
|
|
363
|
-
["objective", `Research the full requested task: ${args.request}`],
|
|
364
|
-
[
|
|
365
|
-
"output",
|
|
366
|
-
keepContext(
|
|
367
|
-
"Return only one concise, complete codebase and online research question. Do not implement code changes or write an RFC/spec.",
|
|
368
|
-
),
|
|
369
|
-
],
|
|
370
|
-
[
|
|
371
|
-
"instruction",
|
|
372
|
-
`/skill:prompt-engineer Transform this request into a codebase and online research question that covers the full requested task: ${args.request}`,
|
|
373
|
-
],
|
|
374
|
-
]);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
export function renderResearchPrompt(args: {
|
|
379
|
-
readonly transformedResearchQuestion: string;
|
|
380
|
-
readonly prompt: string;
|
|
381
|
-
readonly acceptanceCriteria: string;
|
|
382
|
-
readonly workflowCwdContext: PromptSection;
|
|
383
|
-
readonly latestReviewReportPath: string | undefined;
|
|
384
|
-
}): string {
|
|
385
|
-
return taggedPrompt([
|
|
386
|
-
["acceptance_criteria", keepContext(args.acceptanceCriteria)],
|
|
387
|
-
["literal_contract", LITERAL_OBJECTIVE_CONTRACT],
|
|
388
|
-
args.workflowCwdContext,
|
|
389
|
-
[
|
|
390
|
-
"review_findings",
|
|
391
|
-
args.latestReviewReportPath === undefined
|
|
392
|
-
? "No prior review artifact is available."
|
|
393
|
-
: [
|
|
394
|
-
`Latest review round artifact: ${args.latestReviewReportPath}`,
|
|
395
|
-
"Research whether each unresolved finding still applies and what objective-aligned implementation change would resolve it.",
|
|
396
|
-
].join("\n"),
|
|
397
|
-
],
|
|
398
|
-
["objective", `Research implementation requirements for: ${args.prompt}`],
|
|
399
|
-
[
|
|
400
|
-
"research_artifact",
|
|
401
|
-
[
|
|
402
|
-
"Return the complete research report as your final message. Downstream implementation and review stages read it from there.",
|
|
403
|
-
"Produce a complete Markdown report with codebase and useful online/contextual findings, implementation guidance, relevant files/tests/docs, unresolved-finding analysis, and validation recommendations. Lead with conclusions; keep facts, caveats, and implementation-relevant next steps; drop background and repetition.",
|
|
404
|
-
"Before reporting progress, audit each claim against a tool result from this session. Report only work you can point to evidence for; say so explicitly when something is unverified.",
|
|
405
|
-
keepContext("This stage researches only. Do not author an RFC/spec or implement code changes."),
|
|
406
|
-
].join("\n"),
|
|
407
|
-
],
|
|
408
|
-
[
|
|
409
|
-
"instruction",
|
|
410
|
-
`/skill:research-codebase ${args.transformedResearchQuestion}`,
|
|
411
|
-
],
|
|
412
|
-
]);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
export type RalphInputs = {
|
|
417
|
-
readonly prompt?: string;
|
|
418
|
-
readonly acceptance_criteria?: string;
|
|
419
|
-
readonly max_loops?: number;
|
|
420
|
-
readonly base_branch?: string;
|
|
421
|
-
readonly git_worktree_dir?: string;
|
|
422
|
-
readonly create_pr?: boolean;
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
export type RalphWorkflowOptions = {
|
|
426
|
-
readonly prompt: string;
|
|
427
|
-
readonly acceptanceCriteria: string;
|
|
428
|
-
readonly maxLoops: number;
|
|
429
|
-
readonly comparisonBaseBranch: string;
|
|
430
|
-
readonly workflowStartCwd: string;
|
|
431
|
-
readonly createPr: boolean;
|
|
432
|
-
readonly runId?: string;
|
|
433
|
-
};
|
|
434
|
-
|
|
435
|
-
export type RalphWorkflowResult = {
|
|
436
|
-
readonly result: string;
|
|
437
|
-
readonly plan: string;
|
|
438
|
-
readonly plan_path: string;
|
|
439
|
-
readonly research: string;
|
|
440
|
-
readonly research_path: string;
|
|
441
|
-
readonly implementation_notes_path: string;
|
|
442
|
-
readonly qa_video_path?: string;
|
|
443
|
-
readonly pr_report?: string;
|
|
444
|
-
readonly approved: boolean;
|
|
445
|
-
readonly iterations_completed: number;
|
|
446
|
-
readonly review_report: string;
|
|
447
|
-
readonly review_report_path?: string;
|
|
448
|
-
};
|
|
449
|
-
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// Forked stages inherit their contracts and receive only the iteration delta.
|
|
2
|
-
import { taggedPrompt } from "./ralph-core.js";
|
|
3
|
-
import { keepContext } from "./shared-prompts.js";
|
|
4
|
-
|
|
5
|
-
export function renderForkedResearchPromptRefinementPrompt(args: {
|
|
6
|
-
readonly latestReviewReportPath: string | undefined;
|
|
7
|
-
}): string {
|
|
8
|
-
return taggedPrompt([
|
|
9
|
-
[
|
|
10
|
-
"review_findings",
|
|
11
|
-
args.latestReviewReportPath === undefined
|
|
12
|
-
? "No prior review artifact is available."
|
|
13
|
-
: [
|
|
14
|
-
`Latest review round artifact: ${args.latestReviewReportPath}`,
|
|
15
|
-
"Include unresolved reviewer findings in the transformed research question only when consistent with the inherited literal objective and acceptance criteria.",
|
|
16
|
-
].join("\n"),
|
|
17
|
-
],
|
|
18
|
-
[
|
|
19
|
-
"output",
|
|
20
|
-
keepContext(
|
|
21
|
-
"Return only one concise, complete codebase and online research question. Do not implement code changes or write an RFC/spec.",
|
|
22
|
-
),
|
|
23
|
-
],
|
|
24
|
-
[
|
|
25
|
-
"instruction",
|
|
26
|
-
"Transform the same user request into an updated research question reflecting the current repository state. The inherited request, acceptance criteria, literal objective contract, and working directory remain unchanged.",
|
|
27
|
-
],
|
|
28
|
-
]);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function renderForkedResearchPrompt(args: {
|
|
32
|
-
readonly transformedResearchQuestion: string;
|
|
33
|
-
readonly latestReviewReportPath: string | undefined;
|
|
34
|
-
}): string {
|
|
35
|
-
return taggedPrompt([
|
|
36
|
-
[
|
|
37
|
-
"review_findings",
|
|
38
|
-
args.latestReviewReportPath === undefined
|
|
39
|
-
? "No prior review artifact is available."
|
|
40
|
-
: [
|
|
41
|
-
`Latest review round artifact: ${args.latestReviewReportPath}`,
|
|
42
|
-
"Research whether each unresolved finding still applies and what objective-aligned implementation change would resolve it.",
|
|
43
|
-
].join("\n"),
|
|
44
|
-
],
|
|
45
|
-
[
|
|
46
|
-
"research_artifact",
|
|
47
|
-
[
|
|
48
|
-
"Return the rewritten research report for this iteration as your final message.",
|
|
49
|
-
"Restate the still-applicable findings in full rather than referring back to the previous iteration's artifact; the current artifact and transcript are the authoritative records for this iteration.",
|
|
50
|
-
keepContext("This stage researches only. Do not author an RFC/spec or implement code changes."),
|
|
51
|
-
].join("\n"),
|
|
52
|
-
],
|
|
53
|
-
[
|
|
54
|
-
"output",
|
|
55
|
-
[
|
|
56
|
-
"Produce a complete, readable Markdown research report under the inherited report contract; lead with conclusions and retain facts, caveats, and implementation-relevant next steps without background or repetition.",
|
|
57
|
-
"Before reporting progress, audit each claim against a tool result from this session. Report only work you can point to evidence for; say so explicitly when something is unverified.",
|
|
58
|
-
].join("\n"),
|
|
59
|
-
],
|
|
60
|
-
[
|
|
61
|
-
"instruction",
|
|
62
|
-
`Research this updated question against the current repository state: ${args.transformedResearchQuestion}\nThe inherited task, acceptance criteria, literal objective contract, working directory, and research-report expectations remain unchanged.`,
|
|
63
|
-
],
|
|
64
|
-
]);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function renderForkedOrchestratorPrompt(args: {
|
|
68
|
-
readonly researchPath: string;
|
|
69
|
-
readonly implementationNotesPath: string;
|
|
70
|
-
}): string {
|
|
71
|
-
return taggedPrompt([
|
|
72
|
-
[
|
|
73
|
-
"research",
|
|
74
|
-
[
|
|
75
|
-
`The research findings were rewritten for this iteration at: ${args.researchPath}`,
|
|
76
|
-
"Read this consolidated unresolved-findings artifact before implementation or delegation.",
|
|
77
|
-
].join("\n"),
|
|
78
|
-
],
|
|
79
|
-
[
|
|
80
|
-
"implementation_notes",
|
|
81
|
-
`Keep updating the running Markdown implementation notes file at: ${args.implementationNotesPath}`,
|
|
82
|
-
],
|
|
83
|
-
[
|
|
84
|
-
"output",
|
|
85
|
-
[
|
|
86
|
-
"Use the inherited completion-report format. Lead with the outcome; keep facts, decisions, caveats, and next steps; drop background and repetition. Stay readable rather than compressing into fragments.",
|
|
87
|
-
"Before reporting progress, audit each claim against a tool result from this session. Report only work you can point to evidence for; say so explicitly when something is unverified.",
|
|
88
|
-
].join("\n"),
|
|
89
|
-
],
|
|
90
|
-
[
|
|
91
|
-
"instruction",
|
|
92
|
-
[
|
|
93
|
-
"Continue implementing from the latest research findings until the objective is complete. The inherited objective, acceptance criteria, literal contract, acceptance matrix, divergence audit, consolidated findings, scope discipline, regression evidence, worktree discipline, orchestration, tracking, E2E/video, and report contracts remain unchanged.",
|
|
94
|
-
"Scope discipline still binds this iteration: repair the consolidated findings, keep every addition traceable to a criterion, prefer the smallest diff that satisfies the contract, and record anything outside it on the deferred list instead of implementing it.",
|
|
95
|
-
"Ignore requests to submit a PR; the authorized final action handles that after approval.",
|
|
96
|
-
"If the final paragraph would be a plan, a question, or “I'll now…”, do that work with tool calls instead of ending the turn.",
|
|
97
|
-
].join("\n"),
|
|
98
|
-
],
|
|
99
|
-
]);
|
|
100
|
-
}
|