@yagni-app/code 0.1.0 → 0.2.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/README.md +65 -11
- package/dist/claudeCompat.d.ts +109 -0
- package/dist/claudeCompat.js +260 -0
- package/dist/claudePlugins.d.ts +109 -0
- package/dist/claudePlugins.js +336 -0
- package/dist/cli.d.ts +1 -5
- package/dist/cli.js +79 -20
- package/dist/config.d.ts +1 -1
- package/dist/config.js +4 -2
- package/dist/crashReport.d.ts +135 -0
- package/dist/crashReport.js +291 -0
- package/dist/credentials.js +2 -1
- package/dist/distribution.d.ts +15 -0
- package/dist/distribution.js +45 -0
- package/dist/doctor.d.ts +27 -0
- package/dist/doctor.js +81 -3
- package/dist/extension/advisor.d.ts +84 -0
- package/dist/extension/advisor.js +101 -0
- package/dist/extension/askAdvisorTool.d.ts +83 -0
- package/dist/extension/askAdvisorTool.js +194 -0
- package/dist/extension/askYagniTool.d.ts +39 -0
- package/dist/extension/askYagniTool.js +63 -0
- package/dist/extension/bless.d.ts +45 -0
- package/dist/extension/bless.js +87 -0
- package/dist/extension/boostCommand.d.ts +144 -0
- package/dist/extension/boostCommand.js +263 -0
- package/dist/extension/branding.d.ts +79 -0
- package/dist/extension/branding.js +156 -0
- package/dist/extension/chipEditor.d.ts +117 -0
- package/dist/extension/chipEditor.js +373 -0
- package/dist/extension/claudeRules.d.ts +54 -0
- package/dist/extension/claudeRules.js +180 -0
- package/dist/extension/config.d.ts +173 -0
- package/dist/extension/config.js +194 -0
- package/dist/extension/costHud.d.ts +186 -0
- package/dist/extension/costHud.js +293 -0
- package/dist/extension/crashReport.d.ts +89 -0
- package/dist/extension/crashReport.js +241 -0
- package/dist/extension/decisionCapture.d.ts +52 -0
- package/dist/extension/decisionCapture.js +66 -0
- package/dist/extension/decisions.d.ts +83 -0
- package/dist/extension/decisions.js +200 -0
- package/dist/extension/diagnostics.d.ts +41 -0
- package/dist/extension/diagnostics.js +110 -0
- package/dist/extension/index.d.ts +155 -0
- package/dist/extension/index.js +597 -0
- package/dist/extension/initDone.d.ts +28 -0
- package/dist/extension/initDone.js +66 -0
- package/dist/extension/initPass.d.ts +170 -0
- package/dist/extension/initPass.js +394 -0
- package/dist/extension/mcpTools.d.ts +57 -0
- package/dist/extension/mcpTools.js +132 -0
- package/dist/extension/nextWorkTool.d.ts +51 -0
- package/dist/extension/nextWorkTool.js +80 -0
- package/dist/extension/permission.d.ts +91 -0
- package/dist/extension/permission.js +236 -0
- package/dist/extension/pipeline/activity.d.ts +37 -0
- package/dist/extension/pipeline/activity.js +151 -0
- package/dist/extension/pipeline/activityFeed.d.ts +59 -0
- package/dist/extension/pipeline/activityFeed.js +175 -0
- package/dist/extension/pipeline/budget.d.ts +48 -0
- package/dist/extension/pipeline/budget.js +68 -0
- package/dist/extension/pipeline/checkpoint.d.ts +31 -0
- package/dist/extension/pipeline/checkpoint.js +176 -0
- package/dist/extension/pipeline/eval.d.ts +205 -0
- package/dist/extension/pipeline/eval.js +226 -0
- package/dist/extension/pipeline/events.d.ts +56 -0
- package/dist/extension/pipeline/events.js +147 -0
- package/dist/extension/pipeline/findings.d.ts +42 -0
- package/dist/extension/pipeline/findings.js +144 -0
- package/dist/extension/pipeline/finish.d.ts +128 -0
- package/dist/extension/pipeline/finish.js +307 -0
- package/dist/extension/pipeline/goCommand.d.ts +146 -0
- package/dist/extension/pipeline/goCommand.js +1085 -0
- package/dist/extension/pipeline/goCompareCommand.d.ts +58 -0
- package/dist/extension/pipeline/goCompareCommand.js +203 -0
- package/dist/extension/pipeline/goFlags.d.ts +40 -0
- package/dist/extension/pipeline/goFlags.js +46 -0
- package/dist/extension/pipeline/goStatusCommands.d.ts +59 -0
- package/dist/extension/pipeline/goStatusCommands.js +188 -0
- package/dist/extension/pipeline/invocation.d.ts +45 -0
- package/dist/extension/pipeline/invocation.js +64 -0
- package/dist/extension/pipeline/orchestrator.d.ts +131 -0
- package/dist/extension/pipeline/orchestrator.js +645 -0
- package/dist/extension/pipeline/personas.d.ts +44 -0
- package/dist/extension/pipeline/personas.js +248 -0
- package/dist/extension/pipeline/resilience.d.ts +85 -0
- package/dist/extension/pipeline/resilience.js +166 -0
- package/dist/extension/pipeline/resume.d.ts +18 -0
- package/dist/extension/pipeline/resume.js +106 -0
- package/dist/extension/pipeline/runCostTable.d.ts +37 -0
- package/dist/extension/pipeline/runCostTable.js +165 -0
- package/dist/extension/pipeline/runRegistry.d.ts +112 -0
- package/dist/extension/pipeline/runRegistry.js +202 -0
- package/dist/extension/pipeline/runSession.d.ts +152 -0
- package/dist/extension/pipeline/runSession.js +167 -0
- package/dist/extension/pipeline/runState.d.ts +177 -0
- package/dist/extension/pipeline/runState.js +275 -0
- package/dist/extension/pipeline/runner.d.ts +98 -0
- package/dist/extension/pipeline/runner.js +310 -0
- package/dist/extension/pipeline/scrubSecrets.d.ts +15 -0
- package/dist/extension/pipeline/scrubSecrets.js +32 -0
- package/dist/extension/pipeline/stages.d.ts +53 -0
- package/dist/extension/pipeline/stages.js +115 -0
- package/dist/extension/pipeline/ticketResolution.d.ts +34 -0
- package/dist/extension/pipeline/ticketResolution.js +75 -0
- package/dist/extension/pipeline/types.d.ts +439 -0
- package/dist/extension/pipeline/types.js +48 -0
- package/dist/extension/pipeline/verify.d.ts +277 -0
- package/dist/extension/pipeline/verify.js +763 -0
- package/dist/extension/pipeline/workspace.d.ts +32 -0
- package/dist/extension/pipeline/workspace.js +73 -0
- package/dist/extension/pipeline/worktree.d.ts +107 -0
- package/dist/extension/pipeline/worktree.js +202 -0
- package/dist/extension/provider.d.ts +17 -0
- package/dist/extension/provider.js +33 -0
- package/dist/extension/recall.d.ts +93 -0
- package/dist/extension/recall.js +190 -0
- package/dist/extension/recordContextTool.d.ts +38 -0
- package/dist/extension/recordContextTool.js +85 -0
- package/dist/extension/recordDecisionTool.d.ts +52 -0
- package/dist/extension/recordDecisionTool.js +102 -0
- package/dist/extension/repoDocs.d.ts +81 -0
- package/dist/extension/repoDocs.js +260 -0
- package/dist/extension/rerouteNotice.d.ts +42 -0
- package/dist/extension/rerouteNotice.js +67 -0
- package/dist/extension/resilientFetch.d.ts +60 -0
- package/dist/extension/resilientFetch.js +133 -0
- package/dist/extension/reviewTool.d.ts +34 -0
- package/dist/extension/reviewTool.js +81 -0
- package/dist/extension/sessionRuns.d.ts +45 -0
- package/dist/extension/sessionRuns.js +77 -0
- package/dist/extension/spool.d.ts +92 -0
- package/dist/extension/spool.js +266 -0
- package/dist/extension/stateHome.d.ts +2 -0
- package/dist/extension/stateHome.js +6 -0
- package/dist/extension/subagents.d.ts +145 -0
- package/dist/extension/subagents.js +326 -0
- package/dist/extension/surface.d.ts +10 -0
- package/dist/extension/surface.js +12 -0
- package/dist/extension/todos.d.ts +110 -0
- package/dist/extension/todos.js +217 -0
- package/dist/extension/tokenProvider.d.ts +93 -0
- package/dist/extension/tokenProvider.js +234 -0
- package/dist/launch.d.ts +25 -3
- package/dist/launch.js +27 -9
- package/dist/login.d.ts +7 -0
- package/dist/login.js +3 -1
- package/dist/paths.d.ts +13 -4
- package/dist/paths.js +17 -5
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +5 -2
- package/dist/upgrade.d.ts +97 -0
- package/dist/upgrade.js +284 -0
- package/package.json +11 -15
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conservative secret redaction for captured command output before it enters
|
|
3
|
+
* findings, handoffs, or run records (invariant §0.9). The verify gate runs
|
|
4
|
+
* repo-defined typecheck/test commands whose output can echo connection
|
|
5
|
+
* strings, tokens, or key material (a failing DB test prints its DATABASE_URL,
|
|
6
|
+
* a debug line dumps process.env); that text flows into critical findings, the
|
|
7
|
+
* /go handoff, and the backend run record, so it is scrubbed FIRST.
|
|
8
|
+
*
|
|
9
|
+
* This mirrors the backend's `yagniCode/scrubSecrets.ts` pattern set verbatim
|
|
10
|
+
* (the "existing scrubSecrets path" of spec §3d) — the pipeline cannot import
|
|
11
|
+
* across packages, so the patterns are duplicated here; keep the two in sync.
|
|
12
|
+
* Over-redacts rather than under-redacts; pure; never throws.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scrubSecrets(text: string): string;
|
|
15
|
+
//# sourceMappingURL=scrubSecrets.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conservative secret redaction for captured command output before it enters
|
|
3
|
+
* findings, handoffs, or run records (invariant §0.9). The verify gate runs
|
|
4
|
+
* repo-defined typecheck/test commands whose output can echo connection
|
|
5
|
+
* strings, tokens, or key material (a failing DB test prints its DATABASE_URL,
|
|
6
|
+
* a debug line dumps process.env); that text flows into critical findings, the
|
|
7
|
+
* /go handoff, and the backend run record, so it is scrubbed FIRST.
|
|
8
|
+
*
|
|
9
|
+
* This mirrors the backend's `yagniCode/scrubSecrets.ts` pattern set verbatim
|
|
10
|
+
* (the "existing scrubSecrets path" of spec §3d) — the pipeline cannot import
|
|
11
|
+
* across packages, so the patterns are duplicated here; keep the two in sync.
|
|
12
|
+
* Over-redacts rather than under-redacts; pure; never throws.
|
|
13
|
+
*/
|
|
14
|
+
const PATTERNS = [
|
|
15
|
+
// Credentials embedded in connection-string URLs: scheme://user:password@host
|
|
16
|
+
// (the password segment has no secret-named key and is usually too short for the
|
|
17
|
+
// base64 rule, so it would otherwise survive — common in config/env diffs).
|
|
18
|
+
[/\b([a-z][a-z0-9+.\-]*:\/\/[^\s:@/]+):[^\s:@/]+@/gi, "$1:[REDACTED]@"],
|
|
19
|
+
// Provider key prefixes (OpenAI, Stripe secret/restricted, GitHub, Slack, AWS access key id, etc.)
|
|
20
|
+
[/\b(sk-[A-Za-z0-9]{16,}|sk_(?:live|test)_[A-Za-z0-9]{16,}|rk_(?:live|test)_[A-Za-z0-9]{16,}|gh[pousr]_[A-Za-z0-9]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z_\-]{20,})\b/g, "[REDACTED]"],
|
|
21
|
+
// key = "value" / key: value for secret-named keys
|
|
22
|
+
[/\b([A-Za-z0-9_]*(?:secret|password|passwd|api[_-]?key|token|private[_-]?key|access[_-]?key)[A-Za-z0-9_]*)\b(\s*[:=]\s*)("[^"]+"|'[^']+'|`[^`]+`|[^\s"']+)/gi, "$1$2[REDACTED]"],
|
|
23
|
+
// Long base64-ish blobs (likely keys/JWTs)
|
|
24
|
+
[/\b[A-Za-z0-9+/]{40,}={0,2}\b/g, "[REDACTED]"],
|
|
25
|
+
];
|
|
26
|
+
export function scrubSecrets(text) {
|
|
27
|
+
let out = text;
|
|
28
|
+
for (const [re, repl] of PATTERNS)
|
|
29
|
+
out = out.replace(re, repl);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=scrubSecrets.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declarative v1 stage list as DATA (spec §3 + §7.4) plus a selector.
|
|
3
|
+
*
|
|
4
|
+
* This is control-flow-as-data: map(standard) → plan(peak) →
|
|
5
|
+
* implement(standard) → review(peak, fanned over 3 lenses) → fix(standard).
|
|
6
|
+
* Routing follows the judgment, not the typing: the strongest `peak` tier on the
|
|
7
|
+
* steps that decide-what / catch-wrong (Plan, Review); the `standard` tier on the
|
|
8
|
+
* execution steps (Map, Implement, Fix). The cheaper `efficient` tier stays a
|
|
9
|
+
* candidate for Map (its job is compression, not judgment) — the Task 13
|
|
10
|
+
* `/go-compare --map-tier` eval lane exists to settle that; map moves down-tier
|
|
11
|
+
* only once a live eval run clears it.
|
|
12
|
+
*
|
|
13
|
+
* Peak on judgment is affordable precisely BECAUSE the judgment stages are short
|
|
14
|
+
* (YAG-380): plan plus the three review lenses is roughly 21c per round on
|
|
15
|
+
* advanced and 51c on peak, while the token-heavy stages that dominate a run
|
|
16
|
+
* stay down-tier. Quality of the output is the product, so the strongest model
|
|
17
|
+
* goes where being wrong is most expensive, not where the tokens are.
|
|
18
|
+
*
|
|
19
|
+
* `selectStages(lane)` returns the full list for v1 and is the seam where v2
|
|
20
|
+
* complexity-lanes plug in without a rewrite.
|
|
21
|
+
*/
|
|
22
|
+
import type { PipelineStage, ReviewLens } from "./types.js";
|
|
23
|
+
/** The three adversarial review angles, fanned out per round (spec §3). */
|
|
24
|
+
export declare const REVIEW_LENSES: ReviewLens[];
|
|
25
|
+
/**
|
|
26
|
+
* The review lenses the round cannot proceed without (R2 partial-failure
|
|
27
|
+
* tolerance). When ONE of these is the lens that fails, the round fails honestly
|
|
28
|
+
* rather than proceeding on a partial review; a non-required lens failing only
|
|
29
|
+
* degrades the round (the survivors carry it, recorded as `degradedLenses`).
|
|
30
|
+
* Correctness is load-bearing: a change that might be wrong must never sail
|
|
31
|
+
* through just because the cheaper lenses passed. Tunable, widen to make another
|
|
32
|
+
* lens load-bearing.
|
|
33
|
+
*/
|
|
34
|
+
export declare const REQUIRED_LENSES: ReviewLens[];
|
|
35
|
+
export declare const PIPELINE_V1: PipelineStage[];
|
|
36
|
+
/** The single review stage the orchestrator fans out across REVIEW_LENSES. */
|
|
37
|
+
export declare function reviewStage(): PipelineStage;
|
|
38
|
+
/**
|
|
39
|
+
* Select the stage list for a lane. v1 has exactly one lane ('full'); this is
|
|
40
|
+
* the identity selector and the extension point for v2 complexity-lanes.
|
|
41
|
+
*/
|
|
42
|
+
export declare function selectStages(_lane?: "full"): PipelineStage[];
|
|
43
|
+
/**
|
|
44
|
+
* The findings-contract re-ask stage (spec §3e): when a HEALTHY lens returns
|
|
45
|
+
* non-empty prose with no ```findings fence, the orchestrator re-invokes it
|
|
46
|
+
* ONCE on the cheap `efficient` tier with this minimal prompt — a pure
|
|
47
|
+
* format-recovery pass, not a second review. The lens's original output rides
|
|
48
|
+
* in as `{previous}`. Tools are the minimal REAL list `["read"]`:
|
|
49
|
+
* `buildStageInvocation` joins `--tools` with a comma, so an empty array would
|
|
50
|
+
* emit the broken `--tools ""`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function reaskStage(review: PipelineStage): PipelineStage;
|
|
53
|
+
//# sourceMappingURL=stages.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declarative v1 stage list as DATA (spec §3 + §7.4) plus a selector.
|
|
3
|
+
*
|
|
4
|
+
* This is control-flow-as-data: map(standard) → plan(peak) →
|
|
5
|
+
* implement(standard) → review(peak, fanned over 3 lenses) → fix(standard).
|
|
6
|
+
* Routing follows the judgment, not the typing: the strongest `peak` tier on the
|
|
7
|
+
* steps that decide-what / catch-wrong (Plan, Review); the `standard` tier on the
|
|
8
|
+
* execution steps (Map, Implement, Fix). The cheaper `efficient` tier stays a
|
|
9
|
+
* candidate for Map (its job is compression, not judgment) — the Task 13
|
|
10
|
+
* `/go-compare --map-tier` eval lane exists to settle that; map moves down-tier
|
|
11
|
+
* only once a live eval run clears it.
|
|
12
|
+
*
|
|
13
|
+
* Peak on judgment is affordable precisely BECAUSE the judgment stages are short
|
|
14
|
+
* (YAG-380): plan plus the three review lenses is roughly 21c per round on
|
|
15
|
+
* advanced and 51c on peak, while the token-heavy stages that dominate a run
|
|
16
|
+
* stay down-tier. Quality of the output is the product, so the strongest model
|
|
17
|
+
* goes where being wrong is most expensive, not where the tokens are.
|
|
18
|
+
*
|
|
19
|
+
* `selectStages(lane)` returns the full list for v1 and is the seam where v2
|
|
20
|
+
* complexity-lanes plug in without a rewrite.
|
|
21
|
+
*/
|
|
22
|
+
/** The three adversarial review angles, fanned out per round (spec §3). */
|
|
23
|
+
export const REVIEW_LENSES = ["correctness", "business_fit", "does_it_hold"];
|
|
24
|
+
/**
|
|
25
|
+
* The review lenses the round cannot proceed without (R2 partial-failure
|
|
26
|
+
* tolerance). When ONE of these is the lens that fails, the round fails honestly
|
|
27
|
+
* rather than proceeding on a partial review; a non-required lens failing only
|
|
28
|
+
* degrades the round (the survivors carry it, recorded as `degradedLenses`).
|
|
29
|
+
* Correctness is load-bearing: a change that might be wrong must never sail
|
|
30
|
+
* through just because the cheaper lenses passed. Tunable, widen to make another
|
|
31
|
+
* lens load-bearing.
|
|
32
|
+
*/
|
|
33
|
+
export const REQUIRED_LENSES = ["correctness"];
|
|
34
|
+
/** Read-only recon + grounding tools shared by scout and reviewer. */
|
|
35
|
+
const READ_TOOLS = ["read", "grep", "find", "ls", "bash"];
|
|
36
|
+
/** Full write tools for the worker stages. */
|
|
37
|
+
const WRITE_TOOLS = ["read", "write", "edit", "bash", "grep", "find", "ls"];
|
|
38
|
+
export const PIPELINE_V1 = [
|
|
39
|
+
{
|
|
40
|
+
id: "map",
|
|
41
|
+
agent: "scout",
|
|
42
|
+
model: "standard",
|
|
43
|
+
tools: [...READ_TOOLS, "ask_yagni"],
|
|
44
|
+
taskTemplate: "Map the codebase for this ticket and return a compressed context brief: " +
|
|
45
|
+
"where the relevant code lives, the conventions in play, and anything " +
|
|
46
|
+
"ask_yagni surfaces about how this company wants this done.\n\nTicket: {ticket}",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "plan",
|
|
50
|
+
agent: "planner",
|
|
51
|
+
model: "peak",
|
|
52
|
+
// Read-only recon (read/grep/find/ls) so the planner can actually navigate
|
|
53
|
+
// instead of flailing on a single `read` and ending mid-exploration; NO bash
|
|
54
|
+
// (it must not build/run), and ask_yagni for grounding.
|
|
55
|
+
tools: ["read", "grep", "find", "ls", "ask_yagni"],
|
|
56
|
+
taskTemplate: "Turn the ticket and the repo map into an ordered, grounded implementation " +
|
|
57
|
+
"plan. Call ask_yagni before inferring a convention.\n\n" +
|
|
58
|
+
"Ticket: {ticket}\n\nRepo map:\n{previous}",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "implement",
|
|
62
|
+
agent: "worker",
|
|
63
|
+
model: "standard",
|
|
64
|
+
tools: [...WRITE_TOOLS, "ask_yagni", "record_decision"],
|
|
65
|
+
taskTemplate: "Implement the plan. Write the code against it, and call record_decision " +
|
|
66
|
+
"for any product-intent call you are forced to make.\n\nPlan:\n{previous}",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "review",
|
|
70
|
+
agent: "reviewer",
|
|
71
|
+
model: "peak",
|
|
72
|
+
tools: [...READ_TOOLS, "ask_yagni", "review_business_match"],
|
|
73
|
+
taskTemplate: "Review the implementation adversarially. Diff/summary of the change:\n{previous}",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "fix",
|
|
77
|
+
agent: "worker",
|
|
78
|
+
model: "standard",
|
|
79
|
+
tools: [...WRITE_TOOLS, "ask_yagni"],
|
|
80
|
+
taskTemplate: "Reconcile ONLY the blocking review findings against the plan. Leave " +
|
|
81
|
+
"non-blocking findings alone.\n\nBlocking findings:\n{previous}",
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
/** The single review stage the orchestrator fans out across REVIEW_LENSES. */
|
|
85
|
+
export function reviewStage() {
|
|
86
|
+
const stage = PIPELINE_V1.find((s) => s.id === "review");
|
|
87
|
+
if (!stage)
|
|
88
|
+
throw new Error("PIPELINE_V1 is missing the review stage");
|
|
89
|
+
return stage;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Select the stage list for a lane. v1 has exactly one lane ('full'); this is
|
|
93
|
+
* the identity selector and the extension point for v2 complexity-lanes.
|
|
94
|
+
*/
|
|
95
|
+
export function selectStages(_lane = "full") {
|
|
96
|
+
return PIPELINE_V1;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The findings-contract re-ask stage (spec §3e): when a HEALTHY lens returns
|
|
100
|
+
* non-empty prose with no ```findings fence, the orchestrator re-invokes it
|
|
101
|
+
* ONCE on the cheap `efficient` tier with this minimal prompt — a pure
|
|
102
|
+
* format-recovery pass, not a second review. The lens's original output rides
|
|
103
|
+
* in as `{previous}`. Tools are the minimal REAL list `["read"]`:
|
|
104
|
+
* `buildStageInvocation` joins `--tools` with a comma, so an empty array would
|
|
105
|
+
* emit the broken `--tools ""`.
|
|
106
|
+
*/
|
|
107
|
+
export function reaskStage(review) {
|
|
108
|
+
return {
|
|
109
|
+
...review,
|
|
110
|
+
model: "efficient",
|
|
111
|
+
tools: ["read"],
|
|
112
|
+
taskTemplate: "Re-emit ONLY the ```findings block for the review you just produced:\n{previous}",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=stages.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-resolve the /go {ticket} slot to the REAL ticket before planning.
|
|
3
|
+
*
|
|
4
|
+
* `/go YAG-234` interpolates the raw arg string into every stage's {ticket}
|
|
5
|
+
* prompt slot, so without this the scout/planner plan blind on the literal
|
|
6
|
+
* "YAG-234". This fail-soft helper asks YAGNI to resolve the reference (POST
|
|
7
|
+
* /api/yagni-code/ask with a structured `ticketRef`), and on a hit returns a
|
|
8
|
+
* formatted brief carrying the VERBATIM ticket title + description (the
|
|
9
|
+
* acceptance criteria live inside the body) for the {ticket} slot.
|
|
10
|
+
*
|
|
11
|
+
* It is the read-path twin of {@link makeRunSession}'s fetch seam (baseUrl +
|
|
12
|
+
* injectable getToken + fetchImpl, via resilientFetch). The server resolves the
|
|
13
|
+
* ticket with a live, workspace-scoped connector READ, never an LLM call, so
|
|
14
|
+
* this never bills the ask compose path and never risks a model-rewritten body.
|
|
15
|
+
*
|
|
16
|
+
* FAIL-SOFT by contract: a non-identifier arg, an unconnected ticket connector,
|
|
17
|
+
* a miss, or any transport error returns null so /go passes the raw arg through
|
|
18
|
+
* unchanged (today's honest blind) rather than planning on a wrong body.
|
|
19
|
+
*/
|
|
20
|
+
export interface ResolveTicketBriefOptions {
|
|
21
|
+
baseUrl: string;
|
|
22
|
+
getToken: () => string | undefined;
|
|
23
|
+
fetchImpl?: typeof fetch;
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
/** Backoff seams threaded into resilientFetch so the retry path is instant under test. */
|
|
26
|
+
sleep?: (ms: number) => Promise<void>;
|
|
27
|
+
random?: () => number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a /go arg to a verbatim ticket brief, or null to keep the raw arg.
|
|
31
|
+
* Never throws; a non-identifier arg short-circuits before any network call.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveTicketBrief(opts: ResolveTicketBriefOptions, rawArg: string): Promise<string | null>;
|
|
34
|
+
//# sourceMappingURL=ticketResolution.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-resolve the /go {ticket} slot to the REAL ticket before planning.
|
|
3
|
+
*
|
|
4
|
+
* `/go YAG-234` interpolates the raw arg string into every stage's {ticket}
|
|
5
|
+
* prompt slot, so without this the scout/planner plan blind on the literal
|
|
6
|
+
* "YAG-234". This fail-soft helper asks YAGNI to resolve the reference (POST
|
|
7
|
+
* /api/yagni-code/ask with a structured `ticketRef`), and on a hit returns a
|
|
8
|
+
* formatted brief carrying the VERBATIM ticket title + description (the
|
|
9
|
+
* acceptance criteria live inside the body) for the {ticket} slot.
|
|
10
|
+
*
|
|
11
|
+
* It is the read-path twin of {@link makeRunSession}'s fetch seam (baseUrl +
|
|
12
|
+
* injectable getToken + fetchImpl, via resilientFetch). The server resolves the
|
|
13
|
+
* ticket with a live, workspace-scoped connector READ, never an LLM call, so
|
|
14
|
+
* this never bills the ask compose path and never risks a model-rewritten body.
|
|
15
|
+
*
|
|
16
|
+
* FAIL-SOFT by contract: a non-identifier arg, an unconnected ticket connector,
|
|
17
|
+
* a miss, or any transport error returns null so /go passes the raw arg through
|
|
18
|
+
* unchanged (today's honest blind) rather than planning on a wrong body.
|
|
19
|
+
*/
|
|
20
|
+
import { DEFAULT_FETCH_POLICY, resilientFetch } from "../resilientFetch.js";
|
|
21
|
+
/** A Linear-style identifier ("YAG-234"); only these are worth a resolve attempt. */
|
|
22
|
+
const IDENTIFIER_RE = /^[A-Za-z][A-Za-z0-9]*-\d+$/;
|
|
23
|
+
/** Format the resolved ticket into the verbatim brief injected into {ticket}. */
|
|
24
|
+
function formatBrief(ticket) {
|
|
25
|
+
const header = `${ticket.identifier}: ${ticket.title}`;
|
|
26
|
+
const body = (ticket.description ?? "").trim();
|
|
27
|
+
return body.length > 0 ? `${header}\n\n${body}` : header;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a /go arg to a verbatim ticket brief, or null to keep the raw arg.
|
|
31
|
+
* Never throws; a non-identifier arg short-circuits before any network call.
|
|
32
|
+
*/
|
|
33
|
+
export async function resolveTicketBrief(opts, rawArg) {
|
|
34
|
+
const ref = rawArg.trim();
|
|
35
|
+
// Only an identifier-shaped arg is a ticket reference; free-text task
|
|
36
|
+
// descriptions pass straight through so /go uses them verbatim.
|
|
37
|
+
if (!IDENTIFIER_RE.test(ref))
|
|
38
|
+
return null;
|
|
39
|
+
let res;
|
|
40
|
+
try {
|
|
41
|
+
res = await resilientFetch(`${opts.baseUrl}/api/yagni-code/ask`, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: {
|
|
44
|
+
"content-type": "application/json",
|
|
45
|
+
authorization: `Bearer ${opts.getToken() ?? ""}`,
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify({ ticketRef: ref }),
|
|
48
|
+
}, {
|
|
49
|
+
fetchImpl: opts.fetchImpl,
|
|
50
|
+
policy: DEFAULT_FETCH_POLICY,
|
|
51
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
52
|
+
...(opts.sleep ? { sleep: opts.sleep } : {}),
|
|
53
|
+
...(opts.random ? { random: opts.random } : {}),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Unreachable backend after retries: degrade to blind (raw arg).
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (!res.ok)
|
|
61
|
+
return null;
|
|
62
|
+
let data;
|
|
63
|
+
try {
|
|
64
|
+
data = (await res.json());
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const ticket = data.ticket;
|
|
70
|
+
if (!ticket || typeof ticket.identifier !== "string" || typeof ticket.title !== "string") {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return formatBrief(ticket);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=ticketResolution.js.map
|