@prestyj/cli 5.5.0 → 5.7.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/assets/end-notification.mp3 +0 -0
- package/assets/skills/evidence-led-ui/LICENSES.md +68 -0
- package/assets/skills/evidence-led-ui/SKILL.md +139 -0
- package/{LICENSE → assets/skills/evidence-led-ui/corpus/awesome-design-md/LICENSE} +1 -1
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/airbnb/DESIGN.md +545 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/airtable/DESIGN.md +554 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/apple/DESIGN.md +562 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/binance/DESIGN.md +634 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/bmw/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/bmw-m/DESIGN.md +503 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/bugatti/DESIGN.md +454 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/cal/DESIGN.md +542 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/claude/DESIGN.md +589 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/clay/DESIGN.md +541 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/clickhouse/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/cohere/DESIGN.md +451 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/coinbase/DESIGN.md +570 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/composio/DESIGN.md +506 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/cursor/DESIGN.md +537 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/dell-1996/DESIGN.md +632 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/elevenlabs/DESIGN.md +504 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/expo/DESIGN.md +526 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/ferrari/DESIGN.md +531 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/figma/DESIGN.md +578 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/framer/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/hashicorp/DESIGN.md +575 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/hp/DESIGN.md +670 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/ibm/DESIGN.md +550 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/intercom/DESIGN.md +546 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/kraken/DESIGN.md +125 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/lamborghini/DESIGN.md +288 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/linear.app/DESIGN.md +548 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/lovable/DESIGN.md +298 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mastercard/DESIGN.md +365 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/meta/DESIGN.md +683 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/minimax/DESIGN.md +746 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mintlify/DESIGN.md +852 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/miro/DESIGN.md +825 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mistral.ai/DESIGN.md +773 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mongodb/DESIGN.md +767 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/nike/DESIGN.md +575 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/nintendo-2001/DESIGN.md +649 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/notion/DESIGN.md +821 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/nvidia/DESIGN.md +640 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/ollama/DESIGN.md +539 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/opencode.ai/DESIGN.md +521 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/pinterest/DESIGN.md +597 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/playstation/DESIGN.md +661 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/posthog/DESIGN.md +690 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/raycast/DESIGN.md +669 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/renault/DESIGN.md +589 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/replicate/DESIGN.md +616 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/resend/DESIGN.md +585 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/revolut/DESIGN.md +636 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/runwayml/DESIGN.md +244 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/sanity/DESIGN.md +357 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/sentry/DESIGN.md +551 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/shopify/DESIGN.md +516 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/slack/DESIGN.md +482 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/spacex/DESIGN.md +363 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/spotify/DESIGN.md +246 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/starbucks/DESIGN.md +580 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/stripe/DESIGN.md +487 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/supabase/DESIGN.md +462 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/superhuman/DESIGN.md +448 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/tesla/DESIGN.md +286 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/theverge/DESIGN.md +339 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/together.ai/DESIGN.md +633 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/uber/DESIGN.md +636 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/vercel/DESIGN.md +736 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/vodafone/DESIGN.md +538 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/voltagent/DESIGN.md +521 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/warp/DESIGN.md +526 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/webflow/DESIGN.md +588 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/wired/DESIGN.md +497 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/wise/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/x.ai/DESIGN.md +465 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/zapier/DESIGN.md +537 -0
- package/assets/skills/evidence-led-ui/data/corpus-manifest.json +768 -0
- package/assets/skills/evidence-led-ui/data/observations.json +47053 -0
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +203 -0
- package/assets/skills/evidence-led-ui/references/archetypes.md +97 -0
- package/assets/skills/evidence-led-ui/references/craft-rulings.md +167 -0
- package/assets/skills/evidence-led-ui/references/methodology.md +72 -0
- package/assets/skills/evidence-led-ui/references/observed-patterns.md +68 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +120 -0
- package/assets/skills/evidence-led-ui/references/provenance.md +117 -0
- package/assets/skills/evidence-led-ui/references/quality-rubric.md +126 -0
- package/dist/app-sidecar.js +159 -43
- package/dist/app-sidecar.js.map +1 -1
- package/dist/chat-agents/general.test.js +3 -0
- package/dist/chat-agents/general.test.js.map +1 -1
- package/dist/chat-agents/jiwa.d.ts +53 -0
- package/dist/chat-agents/jiwa.d.ts.map +1 -0
- package/dist/chat-agents/jiwa.js +352 -0
- package/dist/chat-agents/jiwa.js.map +1 -0
- package/dist/chat-agents/jiwa.test.d.ts +2 -0
- package/dist/chat-agents/jiwa.test.d.ts.map +1 -0
- package/dist/chat-agents/jiwa.test.js +66 -0
- package/dist/chat-agents/jiwa.test.js.map +1 -0
- package/dist/chat-agents/shared.d.ts.map +1 -1
- package/dist/chat-agents/shared.js +5 -1
- package/dist/chat-agents/shared.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session-review-coverage.test.d.ts +2 -0
- package/dist/core/agent-session-review-coverage.test.d.ts.map +1 -0
- package/dist/core/agent-session-review-coverage.test.js +57 -0
- package/dist/core/agent-session-review-coverage.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +13 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +143 -38
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +1 -1
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +2 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/goal-worker.test.js +3 -2
- package/dist/core/goal-worker.test.js.map +1 -1
- package/dist/core/ideal-review.d.ts +27 -0
- package/dist/core/ideal-review.d.ts.map +1 -1
- package/dist/core/ideal-review.js +64 -0
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/ideal-review.test.js +34 -1
- package/dist/core/ideal-review.test.js.map +1 -1
- package/dist/core/loop-breaker.d.ts +23 -16
- package/dist/core/loop-breaker.d.ts.map +1 -1
- package/dist/core/loop-breaker.js +52 -11
- package/dist/core/loop-breaker.js.map +1 -1
- package/dist/core/loop-breaker.test.js +37 -16
- package/dist/core/loop-breaker.test.js.map +1 -1
- package/dist/core/lsp/client.d.ts +3 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +20 -0
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/manager.d.ts +32 -9
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +89 -37
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/manager.test.js +56 -4
- package/dist/core/lsp/manager.test.js.map +1 -1
- package/dist/core/nolan-prompt.d.ts +3 -3
- package/dist/core/nolan-prompt.d.ts.map +1 -1
- package/dist/core/nolan-prompt.js +10 -10
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/nolan-prompt.test.js +17 -0
- package/dist/core/nolan-prompt.test.js.map +1 -1
- package/dist/core/run-lifecycle.d.ts +40 -0
- package/dist/core/run-lifecycle.d.ts.map +1 -0
- package/dist/core/run-lifecycle.js +95 -0
- package/dist/core/run-lifecycle.js.map +1 -0
- package/dist/core/run-lifecycle.test.d.ts +2 -0
- package/dist/core/run-lifecycle.test.d.ts.map +1 -0
- package/dist/core/run-lifecycle.test.js +64 -0
- package/dist/core/run-lifecycle.test.js.map +1 -0
- package/dist/core/session-manager.d.ts +25 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +66 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.js +80 -2
- package/dist/core/session-manager.test.js.map +1 -1
- package/dist/core/skills-routing.test.d.ts +2 -0
- package/dist/core/skills-routing.test.d.ts.map +1 -0
- package/dist/core/skills-routing.test.js +70 -0
- package/dist/core/skills-routing.test.js.map +1 -0
- package/dist/core/skills.d.ts +2 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +32 -9
- package/dist/core/skills.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +40 -3
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +342 -30
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +189 -3
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/core/subagent-store.d.ts +20 -0
- package/dist/core/subagent-store.d.ts.map +1 -0
- package/dist/core/subagent-store.js +177 -0
- package/dist/core/subagent-store.js.map +1 -0
- package/dist/core/subagent-store.test.d.ts +2 -0
- package/dist/core/subagent-store.test.d.ts.map +1 -0
- package/dist/core/subagent-store.test.js +94 -0
- package/dist/core/subagent-store.test.js.map +1 -0
- package/dist/modes/agent-home-mode.d.ts.map +1 -1
- package/dist/modes/agent-home-mode.js +10 -3
- package/dist/modes/agent-home-mode.js.map +1 -1
- package/dist/modes/serve-mode.d.ts.map +1 -1
- package/dist/modes/serve-mode.js +10 -3
- package/dist/modes/serve-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +13 -3
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/system-prompt.js +2 -2
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +7 -5
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/goals.d.ts +3 -3
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +8 -3
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/tasks.d.ts +2 -2
- package/dist/tools/web-fetch.d.ts +1 -1
- package/dist/ui/App.d.ts +7 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +63 -17
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +1 -0
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +3 -3
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/Footer.test.d.ts +2 -0
- package/dist/ui/components/Footer.test.d.ts.map +1 -0
- package/dist/ui/components/Footer.test.js +16 -0
- package/dist/ui/components/Footer.test.js.map +1 -0
- package/dist/ui/components/SkillsOverlay.d.ts.map +1 -1
- package/dist/ui/components/SkillsOverlay.js +8 -3
- package/dist/ui/components/SkillsOverlay.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +8 -3
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +70 -25
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.test.js +27 -0
- package/dist/ui/hooks/useAgentLoop.test.js.map +1 -1
- package/dist/ui/hooks/useSessionPersistence.d.ts +4 -2
- package/dist/ui/hooks/useSessionPersistence.d.ts.map +1 -1
- package/dist/ui/hooks/useSessionPersistence.js +7 -1
- package/dist/ui/hooks/useSessionPersistence.js.map +1 -1
- package/dist/ui/render.d.ts +7 -0
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +4 -0
- package/dist/ui/render.js.map +1 -1
- package/package.json +6 -5
package/dist/app-sidecar.js
CHANGED
|
@@ -18,11 +18,13 @@ import os from "node:os";
|
|
|
18
18
|
import path from "node:path";
|
|
19
19
|
import { randomUUID } from "node:crypto";
|
|
20
20
|
import { parseArgs } from "node:util";
|
|
21
|
-
import { formatError } from "@prestyj/ai";
|
|
21
|
+
import { environmentSecrets, formatError, redactValue } from "@prestyj/ai";
|
|
22
22
|
import { runJsonMode } from "./modes/json-mode.js";
|
|
23
23
|
import { runSubagentWorkerMode } from "./modes/subagent-worker-mode.js";
|
|
24
24
|
import { AgentSession } from "./core/agent-session.js";
|
|
25
|
+
import { RunLifecycle } from "./core/run-lifecycle.js";
|
|
25
26
|
import { CHAT_AGENT_IDS, chatAgentSessionsDir, createChatAgent, parseChatAgentId, sessionsDirForChatAgent, switchChatAgent, } from "./chat-agents/index.js";
|
|
27
|
+
import { buildJiwaTools, JiwaStore } from "./chat-agents/jiwa.js";
|
|
26
28
|
import { buildMemoryTools, MemoryStore } from "./chat-agents/memory.js";
|
|
27
29
|
import { buildNolanSystemPrompt, buildNolanAutopilotSystemPrompt } from "./core/nolan-prompt.js";
|
|
28
30
|
import { buildNolanDigest, buildNolanAutopilotContext, buildNolanAutopilotPlanContext, } from "./core/nolan-context.js";
|
|
@@ -517,6 +519,13 @@ async function main() {
|
|
|
517
519
|
}
|
|
518
520
|
},
|
|
519
521
|
});
|
|
522
|
+
const jiwaStore = new JiwaStore({
|
|
523
|
+
onChange: ({ jiwa }) => {
|
|
524
|
+
for (const ctx of sessions.values()) {
|
|
525
|
+
ctx.broadcast("jiwa_change", { count: jiwa.length });
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
});
|
|
520
529
|
// XP/rank progress — loaded once per daemon; awards fan out to every window.
|
|
521
530
|
// Each frame is tagged `origin: true` only for the session that earned the
|
|
522
531
|
// XP, so that window alone plays sounds/chips while the rest just re-render.
|
|
@@ -633,7 +642,7 @@ async function main() {
|
|
|
633
642
|
const sessionPath = typeof body.sessionPath === "string" && body.sessionPath ? body.sessionPath : undefined;
|
|
634
643
|
const id = randomUUID();
|
|
635
644
|
try {
|
|
636
|
-
const ctx = await createSession({ auth, paths, progress, memoryStore }, { id, mode, chatAgent, cwd: sessionCwd, sessionPath });
|
|
645
|
+
const ctx = await createSession({ auth, paths, progress, memoryStore, jiwaStore }, { id, mode, chatAgent, cwd: sessionCwd, sessionPath });
|
|
637
646
|
sessions.set(id, ctx);
|
|
638
647
|
log("INFO", "app-sidecar", "session created", {
|
|
639
648
|
id,
|
|
@@ -886,7 +895,7 @@ async function createProgressManager(agentDir, broadcastAll) {
|
|
|
886
895
|
* logger, PATH, shared auth file, and radio live at the daemon level.
|
|
887
896
|
*/
|
|
888
897
|
async function createSession(deps, opts) {
|
|
889
|
-
const { auth, progress, memoryStore } = deps;
|
|
898
|
+
const { auth, progress, memoryStore, jiwaStore } = deps;
|
|
890
899
|
const paths = deps.paths;
|
|
891
900
|
const mode = opts.mode;
|
|
892
901
|
let chatAgent = opts.chatAgent;
|
|
@@ -921,7 +930,8 @@ async function createSession(deps, opts) {
|
|
|
921
930
|
const clients = new Set();
|
|
922
931
|
let clientSeq = 0;
|
|
923
932
|
function broadcast(type, data) {
|
|
924
|
-
const
|
|
933
|
+
const safePayload = redactValue({ type, data }, { secrets: environmentSecrets(process.env) });
|
|
934
|
+
const frame = `data: ${JSON.stringify(safePayload)}\n\n`;
|
|
925
935
|
for (const c of clients)
|
|
926
936
|
c.res.write(frame);
|
|
927
937
|
}
|
|
@@ -1007,8 +1017,8 @@ async function createSession(deps, opts) {
|
|
|
1007
1017
|
session = createChatAgent(chatAgent, {
|
|
1008
1018
|
...baseSessionOptions,
|
|
1009
1019
|
sessionsDir: paths.sessionsDir,
|
|
1010
|
-
additionalTools: buildMemoryTools(memoryStore),
|
|
1011
|
-
getSystemPromptTail: () => memoryStore.renderForPrompt()
|
|
1020
|
+
additionalTools: [...buildMemoryTools(memoryStore), ...buildJiwaTools(jiwaStore)],
|
|
1021
|
+
getSystemPromptTail: () => `${memoryStore.renderForPrompt()}\n\n${jiwaStore.renderForPrompt()}`,
|
|
1012
1022
|
onAgentChange: async (nextAgent) => {
|
|
1013
1023
|
chatAgent = nextAgent;
|
|
1014
1024
|
broadcast("chat_agent_change", { chatAgent: nextAgent });
|
|
@@ -1129,6 +1139,13 @@ async function createSession(deps, opts) {
|
|
|
1129
1139
|
session.eventBus.on("compaction_start", (d) => broadcast("compaction_start", d));
|
|
1130
1140
|
session.eventBus.on("compaction_end", (d) => broadcast("compaction_end", d));
|
|
1131
1141
|
let running = false;
|
|
1142
|
+
const runLifecycle = new RunLifecycle((runState) => {
|
|
1143
|
+
running = runState !== "idle";
|
|
1144
|
+
if (runState === "cancelling")
|
|
1145
|
+
broadcast("run_cancelling", { runState });
|
|
1146
|
+
});
|
|
1147
|
+
const cancelledRunEndGenerations = new Set();
|
|
1148
|
+
let pendingCancelDrain = null;
|
|
1132
1149
|
let titleGenerated = false;
|
|
1133
1150
|
// Bumped by /cancel — a run whose cancel generation changed mid-flight was
|
|
1134
1151
|
// canceled and earns no XP.
|
|
@@ -1151,6 +1168,7 @@ async function createSession(deps, opts) {
|
|
|
1151
1168
|
let autopilotCancelled = false;
|
|
1152
1169
|
// Hard cap on review→prompt→review rounds per user turn (loop safety).
|
|
1153
1170
|
const MAX_AUTOPILOT_ROUNDS = 3;
|
|
1171
|
+
const CANCEL_TIMEOUT_MS = 5_000;
|
|
1154
1172
|
// Prompt bodies Autopilot Nolan injected into the BUILD session this
|
|
1155
1173
|
// conversation. Passed into every Nolan digest so injected prompts render as
|
|
1156
1174
|
// "Nolan autopilot (injected)" instead of `**User:**` — otherwise multi-round
|
|
@@ -1357,29 +1375,63 @@ async function createSession(deps, opts) {
|
|
|
1357
1375
|
});
|
|
1358
1376
|
}
|
|
1359
1377
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1378
|
+
function abortOwnedWork() {
|
|
1379
|
+
cancelGeneration++;
|
|
1380
|
+
abort.abort();
|
|
1381
|
+
// Stop a run-all sweep and every async child through AgentSession's signal.
|
|
1382
|
+
taskRunAll = false;
|
|
1383
|
+
autopilotCancelled = true;
|
|
1384
|
+
nolanAutoAbort.abort();
|
|
1385
|
+
}
|
|
1386
|
+
function installFreshRunControllers() {
|
|
1387
|
+
abort = new AbortController();
|
|
1388
|
+
session.setSignal(abort.signal);
|
|
1389
|
+
nolanAutoAbort = new AbortController();
|
|
1390
|
+
nolanAutoSession?.setSignal(nolanAutoAbort.signal);
|
|
1391
|
+
}
|
|
1392
|
+
function finishOwnedGeneration(generation, emitCancelledFallback) {
|
|
1393
|
+
const cancelled = runLifecycle.isCancellationRequested(generation);
|
|
1394
|
+
const settlement = runLifecycle.settle(generation);
|
|
1395
|
+
if (!settlement.settled)
|
|
1396
|
+
return cancelled;
|
|
1397
|
+
// A replacement signal is safe only after the provider-backed owner settled.
|
|
1398
|
+
installFreshRunControllers();
|
|
1399
|
+
if (cancelled && emitCancelledFallback && !cancelledRunEndGenerations.has(generation)) {
|
|
1400
|
+
cancelledRunEndGenerations.add(generation);
|
|
1401
|
+
broadcast("run_end", { cancelled: true, runState: runLifecycle.state });
|
|
1402
|
+
}
|
|
1403
|
+
return cancelled;
|
|
1404
|
+
}
|
|
1405
|
+
// Core provider-run bracket. Standalone runs own a lifecycle generation;
|
|
1406
|
+
// injected autopilot runs share the cycle's outer generation.
|
|
1364
1407
|
async function runAgent(label, run) {
|
|
1365
|
-
|
|
1408
|
+
const ownsGeneration = !runLifecycle.running;
|
|
1409
|
+
const generation = ownsGeneration
|
|
1410
|
+
? runLifecycle.begin(abortOwnedWork).generation
|
|
1411
|
+
: runLifecycle.generation;
|
|
1412
|
+
if (ownsGeneration)
|
|
1413
|
+
pendingCancelDrain = null;
|
|
1366
1414
|
// Progress (Ranks): completed, non-canceled runs with ≥1 assistant turn earn
|
|
1367
1415
|
// XP — prompt + any commits authored during the run window.
|
|
1368
1416
|
const runStartedAt = Date.now();
|
|
1369
1417
|
const cancelGenAtStart = cancelGeneration;
|
|
1370
1418
|
const assistantsBeforeRun = countAssistantMessages(session.getMessages());
|
|
1371
1419
|
let runSucceeded = false;
|
|
1372
|
-
broadcast("run_start", { text: label });
|
|
1420
|
+
broadcast("run_start", { text: label, runState: runLifecycle.state });
|
|
1373
1421
|
try {
|
|
1374
|
-
|
|
1422
|
+
if (!runLifecycle.isCancellationRequested(generation))
|
|
1423
|
+
await run();
|
|
1375
1424
|
runSucceeded = true;
|
|
1376
1425
|
}
|
|
1377
1426
|
catch (err) {
|
|
1378
|
-
|
|
1427
|
+
if (!runLifecycle.isCancellationRequested(generation)) {
|
|
1428
|
+
broadcastError("error", "run failed", err);
|
|
1429
|
+
}
|
|
1379
1430
|
}
|
|
1380
1431
|
finally {
|
|
1381
|
-
|
|
1432
|
+
const cancelled = runLifecycle.isCancellationRequested(generation);
|
|
1382
1433
|
if (runSucceeded &&
|
|
1434
|
+
!cancelled &&
|
|
1383
1435
|
cancelGeneration === cancelGenAtStart &&
|
|
1384
1436
|
countAssistantMessages(session.getMessages()) > assistantsBeforeRun) {
|
|
1385
1437
|
// Fire-and-forget — XP must never delay or break run teardown.
|
|
@@ -1389,7 +1441,18 @@ async function createSession(deps, opts) {
|
|
|
1389
1441
|
// background tasks — refresh the footer extras once it settles.
|
|
1390
1442
|
gitBranch = await getGitBranch(cwd).catch(() => gitBranch);
|
|
1391
1443
|
gitIsRepo = await isGitRepo(cwd).catch(() => gitIsRepo);
|
|
1392
|
-
|
|
1444
|
+
if (ownsGeneration)
|
|
1445
|
+
finishOwnedGeneration(generation, false);
|
|
1446
|
+
// A cancelled injected run is still owned by the surrounding autopilot
|
|
1447
|
+
// cycle; its outer finalizer emits the one terminal cancelled run_end.
|
|
1448
|
+
if (!(cancelled && !ownsGeneration)) {
|
|
1449
|
+
if (cancelled)
|
|
1450
|
+
cancelledRunEndGenerations.add(generation);
|
|
1451
|
+
broadcast("run_end", {
|
|
1452
|
+
...(cancelled ? { cancelled: true } : {}),
|
|
1453
|
+
runState: runLifecycle.state,
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1393
1456
|
// Autopilot's review loop is driven explicitly from POST /prompt (see
|
|
1394
1457
|
// runAutopilotCycle), NOT from this shared finally — that keeps the
|
|
1395
1458
|
// injected EZ Coder runs this cycle triggers from recursively re-entering
|
|
@@ -1398,12 +1461,8 @@ async function createSession(deps, opts) {
|
|
|
1398
1461
|
// completed ones so they drop out of the Tasks modal automatically (users
|
|
1399
1462
|
// never have to delete finished tasks by hand).
|
|
1400
1463
|
broadcast("tasks_list", { tasks: pruneDoneTasksSync(cwd) });
|
|
1401
|
-
// Queue drains into the run as steering, so it's empty by run_end —
|
|
1402
|
-
// sync the webview indicator.
|
|
1403
1464
|
broadcast("queued", { count: session.getQueuedCount() });
|
|
1404
1465
|
broadcast("extras", footerExtras());
|
|
1405
|
-
// Generate a session title once, after the first run, for the title bar
|
|
1406
|
-
// (best-effort, async — don't block the response).
|
|
1407
1466
|
if (!titleGenerated) {
|
|
1408
1467
|
titleGenerated = true;
|
|
1409
1468
|
void session.generateTitle().then((title) => {
|
|
@@ -1436,7 +1495,8 @@ async function createSession(deps, opts) {
|
|
|
1436
1495
|
return parseAutopilotVerdict(lastAssistantText(ken.getMessages()));
|
|
1437
1496
|
}
|
|
1438
1497
|
catch (err) {
|
|
1439
|
-
|
|
1498
|
+
if (!autopilotCancelled)
|
|
1499
|
+
broadcastError("autopilot_error", "autopilot review failed", err);
|
|
1440
1500
|
return null;
|
|
1441
1501
|
}
|
|
1442
1502
|
finally {
|
|
@@ -1511,6 +1571,8 @@ async function createSession(deps, opts) {
|
|
|
1511
1571
|
async function runAutopilotCycle(originalRequest) {
|
|
1512
1572
|
if (!autopilot || autopilotCancelled)
|
|
1513
1573
|
return;
|
|
1574
|
+
const generation = runLifecycle.begin(abortOwnedWork).generation;
|
|
1575
|
+
pendingCancelDrain = null;
|
|
1514
1576
|
autopilotActive = true;
|
|
1515
1577
|
// Generation captured by the last plan review; acceptPlan re-checks it so
|
|
1516
1578
|
// a user Accept/Reject landing mid-review always wins.
|
|
@@ -1625,6 +1687,8 @@ async function createSession(deps, opts) {
|
|
|
1625
1687
|
}
|
|
1626
1688
|
finally {
|
|
1627
1689
|
autopilotActive = false;
|
|
1690
|
+
finishOwnedGeneration(generation, true);
|
|
1691
|
+
queueMicrotask(() => void runStrandedQueue());
|
|
1628
1692
|
}
|
|
1629
1693
|
}
|
|
1630
1694
|
// ── Stranded-queue drain ───────────────────────────────
|
|
@@ -1817,7 +1881,7 @@ async function createSession(deps, opts) {
|
|
|
1817
1881
|
});
|
|
1818
1882
|
}
|
|
1819
1883
|
function json(res, status, body) {
|
|
1820
|
-
const payload = JSON.stringify(body);
|
|
1884
|
+
const payload = JSON.stringify(redactValue(body, { secrets: environmentSecrets(process.env) }));
|
|
1821
1885
|
res.writeHead(status, {
|
|
1822
1886
|
"content-type": "application/json",
|
|
1823
1887
|
"access-control-allow-origin": "*",
|
|
@@ -1833,6 +1897,7 @@ async function createSession(deps, opts) {
|
|
|
1833
1897
|
mode,
|
|
1834
1898
|
chatAgent,
|
|
1835
1899
|
running,
|
|
1900
|
+
runState: runLifecycle.state,
|
|
1836
1901
|
ready: true,
|
|
1837
1902
|
thinkingLevel: session.getThinkingLevel() ?? null,
|
|
1838
1903
|
supportedThinkingLevels: getSupportedThinkingLevels(st.provider, st.model),
|
|
@@ -1867,6 +1932,26 @@ async function createSession(deps, opts) {
|
|
|
1867
1932
|
.catch((error) => json(res, 500, { error: error instanceof Error ? error.message : String(error) }));
|
|
1868
1933
|
return;
|
|
1869
1934
|
}
|
|
1935
|
+
if (method === "GET" && url === "/jiwa") {
|
|
1936
|
+
void jiwaStore
|
|
1937
|
+
.snapshot()
|
|
1938
|
+
.then((snapshot) => json(res, 200, snapshot))
|
|
1939
|
+
.catch((error) => json(res, 500, { error: error instanceof Error ? error.message : String(error) }));
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1942
|
+
if (method === "DELETE" && url.startsWith("/jiwa/")) {
|
|
1943
|
+
const id = decodeURIComponent(url.slice("/jiwa/".length));
|
|
1944
|
+
if (!id) {
|
|
1945
|
+
json(res, 400, { error: "Jiwa entry id is required" });
|
|
1946
|
+
return;
|
|
1947
|
+
}
|
|
1948
|
+
void jiwaStore
|
|
1949
|
+
.forget(id)
|
|
1950
|
+
.then(() => jiwaStore.snapshot())
|
|
1951
|
+
.then((snapshot) => json(res, 200, snapshot))
|
|
1952
|
+
.catch((error) => json(res, 500, { error: error instanceof Error ? error.message : String(error) }));
|
|
1953
|
+
return;
|
|
1954
|
+
}
|
|
1870
1955
|
if (method === "GET" && (url === "/events" || url.startsWith("/events?"))) {
|
|
1871
1956
|
res.writeHead(200, {
|
|
1872
1957
|
"content-type": "text/event-stream",
|
|
@@ -1885,6 +1970,7 @@ async function createSession(deps, opts) {
|
|
|
1885
1970
|
mode,
|
|
1886
1971
|
chatAgent,
|
|
1887
1972
|
running,
|
|
1973
|
+
runState: runLifecycle.state,
|
|
1888
1974
|
thinkingLevel: session.getThinkingLevel() ?? null,
|
|
1889
1975
|
supportedThinkingLevels: getSupportedThinkingLevels(st.provider, st.model),
|
|
1890
1976
|
supportsVideo: getModel(st.model)?.supportsVideo ?? false,
|
|
@@ -2381,6 +2467,13 @@ async function createSession(deps, opts) {
|
|
|
2381
2467
|
json(res, 400, { error: "empty prompt" });
|
|
2382
2468
|
return;
|
|
2383
2469
|
}
|
|
2470
|
+
if (runLifecycle.running && runLifecycle.isCancellationRequested(runLifecycle.generation)) {
|
|
2471
|
+
json(res, 409, {
|
|
2472
|
+
error: runLifecycle.state === "cancelling" ? "run_cancelling" : "cancel_failed",
|
|
2473
|
+
runState: runLifecycle.state,
|
|
2474
|
+
});
|
|
2475
|
+
return;
|
|
2476
|
+
}
|
|
2384
2477
|
if (running || autopilotActive) {
|
|
2385
2478
|
// Queue prompts as mid-run steering (mirrors the CLI). Also queue while
|
|
2386
2479
|
// an autopilot cycle is active but between injected runs (build idle,
|
|
@@ -2954,27 +3047,50 @@ async function createSession(deps, opts) {
|
|
|
2954
3047
|
return;
|
|
2955
3048
|
}
|
|
2956
3049
|
if (method === "POST" && url === "/cancel") {
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
3050
|
+
void (async () => {
|
|
3051
|
+
// Even between task runs, cancellation stops the sweep. Active provider
|
|
3052
|
+
// ownership invokes the full abort hook exactly once through lifecycle.
|
|
3053
|
+
taskRunAll = false;
|
|
3054
|
+
autopilotCancelled = true;
|
|
3055
|
+
if (!runLifecycle.running) {
|
|
3056
|
+
nolanAutoAbort.abort();
|
|
3057
|
+
nolanAutoAbort = new AbortController();
|
|
3058
|
+
nolanAutoSession?.setSignal(nolanAutoAbort.signal);
|
|
3059
|
+
}
|
|
3060
|
+
const generation = runLifecycle.generation;
|
|
3061
|
+
if (!pendingCancelDrain || pendingCancelDrain.generation !== generation) {
|
|
3062
|
+
pendingCancelDrain = { generation, text: session.drainQueue() };
|
|
3063
|
+
broadcast("queued", { count: 0 });
|
|
3064
|
+
}
|
|
3065
|
+
const result = await runLifecycle.cancel(CANCEL_TIMEOUT_MS);
|
|
3066
|
+
const drained = pendingCancelDrain.text;
|
|
3067
|
+
if (result.status === "failed") {
|
|
3068
|
+
broadcast("cancel_failed", {
|
|
3069
|
+
error: "cancel_failed",
|
|
3070
|
+
reason: result.reason,
|
|
3071
|
+
runState: runLifecycle.state,
|
|
3072
|
+
});
|
|
3073
|
+
json(res, 504, {
|
|
3074
|
+
error: "cancel_failed",
|
|
3075
|
+
reason: result.reason,
|
|
3076
|
+
runState: runLifecycle.state,
|
|
3077
|
+
drained,
|
|
3078
|
+
});
|
|
3079
|
+
return;
|
|
3080
|
+
}
|
|
3081
|
+
json(res, 200, {
|
|
3082
|
+
cancelled: result.status === "cancelled",
|
|
3083
|
+
runState: runLifecycle.state,
|
|
3084
|
+
drained,
|
|
3085
|
+
});
|
|
3086
|
+
})().catch((error) => {
|
|
3087
|
+
broadcast("cancel_failed", { error: "cancel_failed", runState: runLifecycle.state });
|
|
3088
|
+
json(res, 500, {
|
|
3089
|
+
error: "cancel_failed",
|
|
3090
|
+
message: error instanceof Error ? error.message : String(error),
|
|
3091
|
+
runState: runLifecycle.state,
|
|
3092
|
+
});
|
|
3093
|
+
});
|
|
2978
3094
|
return;
|
|
2979
3095
|
}
|
|
2980
3096
|
if (method === "POST" && url === "/new-session") {
|