@haystackeditor/cli 0.14.5 → 0.14.6
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/dist/commands/setup.js +15 -8
- package/dist/triage/prompts.js +35 -4
- package/dist/triage/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/commands/setup.js
CHANGED
|
@@ -641,26 +641,33 @@ class InstallationsAuthError extends Error {
|
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
643
|
async function fetchHaystackInstallations(token) {
|
|
644
|
-
//
|
|
645
|
-
//
|
|
646
|
-
|
|
644
|
+
// Detect the Haystack App via the auth-worker, NOT GitHub's
|
|
645
|
+
// `GET /user/installations`. That GitHub endpoint requires a GitHub App
|
|
646
|
+
// user-to-server token; the CLI's `haystack login` token is a classic OAuth
|
|
647
|
+
// token, so GitHub answers 403 ("must authenticate with an access token
|
|
648
|
+
// authorized to a GitHub App") — which made step 0 falsely report the App as
|
|
649
|
+
// uninstalled and exit. The auth-worker resolves installations server-side
|
|
650
|
+
// with the App's own JWT, so it works with the CLI's token. Every entry it
|
|
651
|
+
// returns IS a Haystack installation (the worker only knows about this App),
|
|
652
|
+
// so there's no app_slug to filter on.
|
|
653
|
+
const res = await fetch(`${HAYSTACK_API}/api/github/user-installations`, {
|
|
647
654
|
headers: {
|
|
648
655
|
Authorization: `Bearer ${token}`,
|
|
649
|
-
Accept: 'application/
|
|
656
|
+
Accept: 'application/json',
|
|
650
657
|
'User-Agent': 'Haystack-CLI',
|
|
651
658
|
},
|
|
652
659
|
});
|
|
653
660
|
if (!res.ok) {
|
|
654
|
-
// 401/403 are auth
|
|
655
|
-
// the
|
|
656
|
-
// type so the poll loop can
|
|
661
|
+
// 401/403 here are genuine auth failures (the token the worker validates is
|
|
662
|
+
// bad), unlike the GitHub endpoint's spurious 403. Retrying won't recover;
|
|
663
|
+
// bail with a distinct error type so the poll loop can prompt re-auth.
|
|
657
664
|
if (res.status === 401 || res.status === 403) {
|
|
658
665
|
throw new InstallationsAuthError(res.status, `${res.status} ${await res.text()}`);
|
|
659
666
|
}
|
|
660
667
|
throw new Error(`failed to fetch installations: ${res.status} ${await res.text()}`);
|
|
661
668
|
}
|
|
662
669
|
const data = (await res.json());
|
|
663
|
-
return
|
|
670
|
+
return data.installations ?? [];
|
|
664
671
|
}
|
|
665
672
|
function tryOpenBrowser(url) {
|
|
666
673
|
// Best-effort browser open. Never blocks setup — the URL is also printed.
|
package/dist/triage/prompts.js
CHANGED
|
@@ -45,7 +45,7 @@ const INTENT_DRIFT_SCHEMA = `{
|
|
|
45
45
|
"line": 42,
|
|
46
46
|
"severity": "error | warning | info",
|
|
47
47
|
"message": "Description of the drift or incomplete fulfillment",
|
|
48
|
-
"pattern": "intent_drift | incomplete_fulfillment | scope_creep"
|
|
48
|
+
"pattern": "intent_drift | incomplete_fulfillment | scope_creep | unspecified_decision | ignored_correction | weakened_posture | claimed_but_not_done"
|
|
49
49
|
}
|
|
50
50
|
],
|
|
51
51
|
"summary": "Brief 1-sentence summary",
|
|
@@ -286,6 +286,36 @@ The agent added functionality the user never asked for:
|
|
|
286
286
|
- User asks for one feature → agent bundles in extra features "while we're at it"
|
|
287
287
|
- Any new mechanism not traceable to a user instruction
|
|
288
288
|
|
|
289
|
+
### Unspecified Decision
|
|
290
|
+
The user authorized the task's GOAL, but the agent made a specific decision in HOW it carried it out that shapes the program's end output, externally observable behavior, or the data end-users/callers see — and the user never specified or approved that particular decision, and a reasonable user would plausibly want a say in it. Examples (general — do NOT pattern-match on specific keywords):
|
|
291
|
+
- Silently dropping, capping, sampling, or transforming data that flows to the output
|
|
292
|
+
- Picking a default that determines what end-users see
|
|
293
|
+
- Resolving an ambiguous requirement one way when other materially different behaviors were equally valid
|
|
294
|
+
- Choosing a fixed value where the choice changes results
|
|
295
|
+
Do NOT flag internal implementation choices with no observable effect (naming, file layout, helper structure), decisions forced by correctness, or cosmetic defaults a user would not care about. When unsure whether a user would care, do not flag it — reserve this for decisions with real, user-visible ramifications. The difference from scope creep: scope creep is an unrequested *flow*; an unspecified decision is an unrequested, output-shaping choice *inside a requested flow*.
|
|
296
|
+
|
|
297
|
+
### Ignored Correction
|
|
298
|
+
The user gave an explicit correction or redirection and the final code does NOT honor it:
|
|
299
|
+
- User said "don't use a global / use X instead / that's racy, do Y" and the agent shipped the thing it was told not to
|
|
300
|
+
- Agent applied the correction, then quietly reverted it in a later step
|
|
301
|
+
- A general later "looks good" does NOT cancel a specific earlier correction
|
|
302
|
+
This is high severity by default: the user actively steered and was overridden.
|
|
303
|
+
|
|
304
|
+
### Weakened Posture
|
|
305
|
+
In service of an authorized goal, the agent relaxed or removed a security, safety, or correctness guard the user never asked to weaken:
|
|
306
|
+
- Loosened an auth/permission/validation check, or broadened access (CORS, scopes)
|
|
307
|
+
- Swallowed or silenced an error, removed an assertion/guard, hardcoded a bypass or credential
|
|
308
|
+
- Disabled a test (.skip / xit), suppressed a type or lint check (any, @ts-ignore, disable comments)
|
|
309
|
+
- Lowered a threshold/timeout that existed as a safeguard
|
|
310
|
+
High severity by default. (If the user explicitly asked to remove the guard, it is not a finding.)
|
|
311
|
+
|
|
312
|
+
### Claimed But Not Done
|
|
313
|
+
The agent told the user it completed work that the diff does not actually contain, or contains only in a materially weaker form:
|
|
314
|
+
- "I added error handling for timeouts" but no timeout handling exists in the diff
|
|
315
|
+
- "Added tests for the edge case" but no test assertions exercise it
|
|
316
|
+
- "Made the limit configurable" but the value is still hardcoded
|
|
317
|
+
Compare each concrete claim the agent made to the user against what the diff actually shows. Only flag when the diff clearly contradicts or fails to support the claim; when unsure, do not flag.
|
|
318
|
+
|
|
289
319
|
## Red flags to search for in the diff
|
|
290
320
|
|
|
291
321
|
- Fixed/hardcoded values where dynamic behavior was requested
|
|
@@ -293,6 +323,7 @@ The agent added functionality the user never asked for:
|
|
|
293
323
|
- Empty function bodies or early returns
|
|
294
324
|
- Interface fields that are declared but never assigned anywhere
|
|
295
325
|
- New mechanisms (cooldowns, retries, caches, rate limits) not requested by the user
|
|
326
|
+
- Decisions that drop, limit, or reshape data flowing to the output, or pick a default that changes what end-users see, with no instruction specifying it
|
|
296
327
|
|
|
297
328
|
## Output
|
|
298
329
|
|
|
@@ -303,9 +334,9 @@ ${INTENT_DRIFT_SCHEMA}
|
|
|
303
334
|
\`\`\`
|
|
304
335
|
|
|
305
336
|
- Set \`sessionsChecked\` to the number of trace files you read
|
|
306
|
-
- Set \`passed\` to \`true\`
|
|
307
|
-
- Set \`passed\` to \`false\`
|
|
308
|
-
- For each issue, set \`pattern\` to "intent_drift", "incomplete_fulfillment",
|
|
337
|
+
- Set \`passed\` to \`true\` only when no intent-drift issues are found
|
|
338
|
+
- Set \`passed\` to \`false\` when any issue is found (any pattern, any severity)
|
|
339
|
+
- For each issue, set \`pattern\` to one of: "intent_drift", "incomplete_fulfillment", "scope_creep", "unspecified_decision", "ignored_correction", "weakened_posture", "claimed_but_not_done"
|
|
309
340
|
- You MUST write the result file even if no issues are found
|
|
310
341
|
|
|
311
342
|
## Severity guidelines
|
package/dist/triage/types.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface TriageIssue {
|
|
|
13
13
|
/** For rules validator: rule ID (e.g., PR001) */
|
|
14
14
|
rule?: string;
|
|
15
15
|
/** For intent drift: drift pattern */
|
|
16
|
-
pattern?: 'intent_drift' | 'incomplete_fulfillment' | 'scope_creep';
|
|
16
|
+
pattern?: 'intent_drift' | 'incomplete_fulfillment' | 'scope_creep' | 'unspecified_decision' | 'ignored_correction' | 'weakened_posture' | 'claimed_but_not_done';
|
|
17
17
|
}
|
|
18
18
|
export interface CodeReviewResult {
|
|
19
19
|
checker: 'code-review';
|