neuvikon 0.2.29 → 0.2.30

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.
Files changed (2) hide show
  1. package/dist/index.mjs +22 -0
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -733,6 +733,27 @@ function parsePayload(raw) {
733
733
  }
734
734
  }
735
735
  /**
736
+ * What actually gets the model/effort switch to happen, versus the
737
+ * AGENTS.md wording alone: tested against real tickets, an agent reading
738
+ * "judge difficulty and switch model" in its rules file consistently read
739
+ * past it and started working at whatever model/effort it already had —
740
+ * the instruction competed with everything else in that file and lost.
741
+ *
742
+ * `UserPromptSubmit` can inject `additionalContext`, which Claude Code
743
+ * surfaces as a system-level reminder on the *same turn* the ticket lands,
744
+ * not as background file content the agent may or may not re-read. It's
745
+ * still just text — this can't force a `/model`/`/effort` call, only put it
746
+ * in front of the model at the one moment it's actually relevant instead of
747
+ * buried in a rules file next to a dozen other instructions.
748
+ */
749
+ const MODEL_TRIAGE_CONTEXT = "A Neuvikon ticket just landed in this prompt. Before reading any file or running `start`: judge how difficult it actually is. If it's a small, mechanical change (button placement, a copy/label edit, a trivial styling tweak, a one-line config change), send `/model haiku` and `/effort low` now, as their own messages, before touching the ticket — there's no reason to spend a frontier model thinking hard about something this small. If it needs real design judgment, touches multiple systems, or you're unsure, stay on the current model and effort level instead.";
750
+ function hookResponse(additionalContext) {
751
+ return JSON.stringify({ hookSpecificOutput: {
752
+ hookEventName: "UserPromptSubmit",
753
+ additionalContext
754
+ } });
755
+ }
756
+ /**
736
757
  * The `UserPromptSubmit` counterpart to `start`. Unlike `start`, this runs on
737
758
  * *every* prompt regardless of whether it mentions a ticket, so it must never
738
759
  * fail the hook and block the user's message — no credentials, no ticket ref,
@@ -745,6 +766,7 @@ async function hookStart() {
745
766
  const { prompt, transcriptPath } = parsePayload(await readStdin());
746
767
  const [ref] = extractTicketRefs(prompt ?? "");
747
768
  if (!ref) return;
769
+ process.stdout.write(hookResponse(MODEL_TRIAGE_CONTEXT));
748
770
  const existing = readSession();
749
771
  if (existing?.ticket === ref) return;
750
772
  const transcript = transcriptPath ?? claudeTranscriptPath();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neuvikon",
3
- "version": "0.2.29",
3
+ "version": "0.2.30",
4
4
  "description": "Tell Neuvikon which ticket your coding agent is working on.",
5
5
  "keywords": [
6
6
  "neuvikon",