zelari-code 2.45.1 → 2.46.1
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/cli/app.js +19 -25
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/components/InputBar.js +17 -27
- package/dist/cli/components/InputBar.js.map +1 -1
- package/dist/cli/components/StatusBar.js +45 -1
- package/dist/cli/components/StatusBar.js.map +1 -1
- package/dist/cli/components/inputDraft.js +61 -0
- package/dist/cli/components/inputDraft.js.map +1 -0
- package/dist/cli/components/statusChips.js +71 -0
- package/dist/cli/components/statusChips.js.map +1 -0
- package/dist/cli/headless/runOneTurn.js +11 -3
- package/dist/cli/headless/runOneTurn.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +15 -7
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/hooks/useGitChanges.js +40 -6
- package/dist/cli/hooks/useGitChanges.js.map +1 -1
- package/dist/cli/kraken/executor.js +22 -1
- package/dist/cli/kraken/executor.js.map +1 -1
- package/dist/cli/main.bundled.js +229 -83
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +5 -14
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/memory/opsKnowledge.js +9 -0
- package/dist/cli/memory/opsKnowledge.js.map +1 -1
- package/dist/cli/tools/taskTool.js +106 -40
- package/dist/cli/tools/taskTool.js.map +1 -1
- package/dist/cli/updater.js +38 -0
- package/dist/cli/updater.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -21104,7 +21104,7 @@ Rules:
|
|
|
21104
21104
|
title: "Kraken Lead Playbook",
|
|
21105
21105
|
// priority 25 = after BEHAVIOR_AGENT (20). Via aiConfig custom modules get +1000.
|
|
21106
21106
|
priority: 25,
|
|
21107
|
-
content: "# Kraken Lead Playbook (super-agent)\n\nYou are the **parent brain**. Sub-agents spawned with task are tentacles: they cannot see this chat and cannot nest further task calls.\n\n## Default workflow (non-trivial work)\n1. **Orient** - list/read key files; optionally task explore (parallel OK for disjoint questions).\n2. **Decompose** - todo_write with concrete slices and acceptance criteria.\n3. **Implement** - one slice at a time via tools or task agent=general for a bounded unit.\n4. **Verify** - after meaningful writes, run checks yourself (bash / typecheck / tests) or task agent=verify. Do not claim done without on-disk evidence.\n5. **Integrate** - summarize files touched + how to verify; if more remains, checkpoint and ask.\n\n## When to spawn task\n- **explore**: unfamiliar area, multi-file search, map call sites (prefer parallel explores).\n- **general**: isolated implement slice with clear path scope (serial writers unless worktree isolation is on).\n- **verify**: post-implement gate (tests/typecheck/smoke).\n\n## Task contracts (required quality)\nEvery task prompt must be self-contained and include:\n- **Goal** (one sentence)\n- **Scope** (paths / symbols allowed; what is out of scope)\n- **Acceptance** (how the parent will know it succeeded)\n- **Constraints** (no drive-by refactors; match existing style)\n\nOptional tool fields: scope (path allowlist hint), acceptance (checklist). Prefer them when available.\n\n## Caps and discipline\n- Prefer at most 4 explore and 2 general spawns per user turn unless the user asks for more.\n- Do not expand scope beyond the user request.\n- Parallel: many explore OK; general writers stay serial unless ZELARI_KRAKEN_WORKTREE=1.\n- Nested task from children is disabled - you are the only orchestrator.\n- Cheap thoroughness defaults: explore=quick|medium; deep only when stuck.\n- Model routing: explore/verify may use ZELARI_KRAKEN_SUB_MODEL (cheaper); general stays on parent model unless ZELARI_KRAKEN_GENERAL_MODEL is set.\n- After every successful task general
|
|
21107
|
+
content: "# Kraken Lead Playbook (super-agent)\n\nYou are the **parent brain**. Sub-agents spawned with task are tentacles: they cannot see this chat and cannot nest further task calls.\n\n## Default workflow (non-trivial work)\n1. **Orient** - list/read key files; optionally task explore (parallel OK for disjoint questions).\n2. **Decompose** - todo_write with concrete slices and acceptance criteria.\n3. **Implement** - one slice at a time via tools or task agent=general for a bounded unit.\n4. **Verify** - after meaningful writes, run checks yourself (bash / typecheck / tests) or task agent=verify. Do not claim done without on-disk evidence.\n5. **Integrate** - summarize files touched + how to verify; if more remains, checkpoint and ask.\n\n## When to spawn task\n- **explore**: unfamiliar area, multi-file search, map call sites (prefer parallel explores).\n- **general**: isolated implement slice with clear path scope (serial writers unless worktree isolation is on).\n- **verify**: post-implement gate (tests/typecheck/smoke).\n\n## Task contracts (required quality)\nEvery task prompt must be self-contained and include:\n- **Goal** (one sentence)\n- **Scope** (paths / symbols allowed; what is out of scope)\n- **Acceptance** (how the parent will know it succeeded)\n- **Constraints** (no drive-by refactors; match existing style)\n\nOptional tool fields: scope (path allowlist hint), acceptance (checklist). Prefer them when available.\n\n## Caps and discipline\n- Prefer at most 4 explore and 2 general spawns per user turn unless the user asks for more.\n- Do not expand scope beyond the user request.\n- Parallel: many explore OK; general writers stay serial unless ZELARI_KRAKEN_WORKTREE=1.\n- Nested task from children is disabled - you are the only orchestrator.\n- Cheap thoroughness defaults: explore=quick|medium; deep only when stuck.\n- Model routing: explore/verify may use ZELARI_KRAKEN_SUB_MODEL (cheaper); general stays on parent model unless ZELARI_KRAKEN_GENERAL_MODEL is set.\n- After every successful task general the runtime auto-spawns a verify tentacle (general->verify obligation, ADR-0033); only a parseable verify PASS clears it, and open debt at turn end blocks strict done (exit 4).\n- Opt-in isolation: ZELARI_KRAKEN_WORKTREE=1 runs general tentacles in a git worktree under .zelari/worktrees/ (KEEP=1 to retain branch for manual merge).\n- Progress bus: tentacle spawns log to .zelari/radio/<session>.jsonl - slash command /kraken shows status.\n\n## Done means verified\nNever end with status theater. Either tools ran and files changed, or you stop with a short report and ask whether to continue."
|
|
21108
21108
|
};
|
|
21109
21109
|
KRAKEN_SELECTION_PLAYBOOK_MODULE = {
|
|
21110
21110
|
type: "behavior-rules",
|
|
@@ -38898,7 +38898,7 @@ var CORE_VERSION;
|
|
|
38898
38898
|
var init_version = __esm({
|
|
38899
38899
|
"packages/core/dist/version.js"() {
|
|
38900
38900
|
"use strict";
|
|
38901
|
-
CORE_VERSION = "2.
|
|
38901
|
+
CORE_VERSION = "2.46.1";
|
|
38902
38902
|
}
|
|
38903
38903
|
});
|
|
38904
38904
|
|
|
@@ -40110,6 +40110,7 @@ var init_cmdline = __esm({
|
|
|
40110
40110
|
var updater_exports = {};
|
|
40111
40111
|
__export(updater_exports, {
|
|
40112
40112
|
REGISTRY_URL: () => REGISTRY_URL,
|
|
40113
|
+
UPDATE_CHECK_DELAY_MS: () => UPDATE_CHECK_DELAY_MS,
|
|
40113
40114
|
checkForUpdate: () => checkForUpdate,
|
|
40114
40115
|
compareSemver: () => compareSemver,
|
|
40115
40116
|
distTagForVersion: () => distTagForVersion,
|
|
@@ -40120,7 +40121,8 @@ __export(updater_exports, {
|
|
|
40120
40121
|
performUpdate: () => performUpdate,
|
|
40121
40122
|
registryUrlForTag: () => registryUrlForTag,
|
|
40122
40123
|
resolveBundledNpmCli: () => resolveBundledNpmCli,
|
|
40123
|
-
resolveInstallKind: () => resolveInstallKind
|
|
40124
|
+
resolveInstallKind: () => resolveInstallKind,
|
|
40125
|
+
runDeferredUpdateCheck: () => runDeferredUpdateCheck
|
|
40124
40126
|
});
|
|
40125
40127
|
import { createRequire } from "node:module";
|
|
40126
40128
|
import { execSync, spawn as spawn6 } from "node:child_process";
|
|
@@ -40251,6 +40253,23 @@ async function checkForUpdate(fetcher = fetch, registryUrl) {
|
|
|
40251
40253
|
updateAvailable: cmp < 0
|
|
40252
40254
|
};
|
|
40253
40255
|
}
|
|
40256
|
+
async function runDeferredUpdateCheck(opts = {}) {
|
|
40257
|
+
const delayMs = opts.delayMs ?? UPDATE_CHECK_DELAY_MS;
|
|
40258
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((resolve11) => setTimeout(resolve11, ms)));
|
|
40259
|
+
const report = opts.report ?? ((message) => {
|
|
40260
|
+
console.error(message);
|
|
40261
|
+
});
|
|
40262
|
+
try {
|
|
40263
|
+
await sleep(delayMs);
|
|
40264
|
+
const info = await (opts.check ?? (() => checkForUpdate()))();
|
|
40265
|
+
if (info.updateAvailable && !info.error) {
|
|
40266
|
+
report(
|
|
40267
|
+
`[zelari-code] \u{1F195} v${info.latestVersion} available (current: v${info.currentVersion}). Run \`zelari-code\` then \`/update --yes\` to upgrade.`
|
|
40268
|
+
);
|
|
40269
|
+
}
|
|
40270
|
+
} catch {
|
|
40271
|
+
}
|
|
40272
|
+
}
|
|
40254
40273
|
async function performUpdate(packageName = "zelari-code", executor = spawn6, resolveNpmCli = resolveBundledNpmCli, channel, installKind = resolveInstallKind()) {
|
|
40255
40274
|
if (installKind === "npx" || installKind === "local") {
|
|
40256
40275
|
return {
|
|
@@ -40307,7 +40326,7 @@ function runNpm(executor, args, mode, npmCliPath) {
|
|
|
40307
40326
|
});
|
|
40308
40327
|
});
|
|
40309
40328
|
}
|
|
40310
|
-
var require2, __dirname2, PKG_ROOT, REGISTRY_URL;
|
|
40329
|
+
var require2, __dirname2, PKG_ROOT, REGISTRY_URL, UPDATE_CHECK_DELAY_MS;
|
|
40311
40330
|
var init_updater = __esm({
|
|
40312
40331
|
"src/cli/updater.ts"() {
|
|
40313
40332
|
"use strict";
|
|
@@ -40316,6 +40335,7 @@ var init_updater = __esm({
|
|
|
40316
40335
|
__dirname2 = path32.dirname(fileURLToPath(import.meta.url));
|
|
40317
40336
|
PKG_ROOT = path32.resolve(__dirname2, "..", "..");
|
|
40318
40337
|
REGISTRY_URL = "https://registry.npmjs.org/zelari-code/latest";
|
|
40338
|
+
UPDATE_CHECK_DELAY_MS = 12e3;
|
|
40319
40339
|
}
|
|
40320
40340
|
});
|
|
40321
40341
|
|
|
@@ -46155,6 +46175,7 @@ function buildUpstreamContext(graph, node) {
|
|
|
46155
46175
|
for (const depId of node.deps) {
|
|
46156
46176
|
const dep = graph.nodes.get(depId);
|
|
46157
46177
|
if (!dep || dep.status !== "done") continue;
|
|
46178
|
+
if (REVIEWER_KINDS.has(node.kind) && WRITER_KINDS2.has(dep.kind)) continue;
|
|
46158
46179
|
const raw = (dep.result ?? "").trim();
|
|
46159
46180
|
if (!raw) continue;
|
|
46160
46181
|
const cap3 = Math.min(MAX_UPSTREAM_CHARS_PER_DEP, budget);
|
|
@@ -46198,7 +46219,7 @@ function roiTaskKindOf(kind2) {
|
|
|
46198
46219
|
if (kind2 === "spec" || kind2 === "conformance") return "review";
|
|
46199
46220
|
return "implement";
|
|
46200
46221
|
}
|
|
46201
|
-
var DEFAULT_MAX_PARALLEL, DEFAULT_FIX_BUDGET, DEFAULT_TRANSACTIONAL, DEFAULT_MAX_REVIEW_ROUNDS, DEFAULT_GRAPH_TIMEOUT_MS, DEFAULT_NODE_TIMEOUT_MS, DEFAULT_WRITER_NODE_TIMEOUT_MS, DEFAULT_CANCEL_GRACE_MS, MAX_UPSTREAM_CHARS_PER_DEP, MAX_UPSTREAM_CHARS_TOTAL, KrakenGraphExecutor;
|
|
46222
|
+
var DEFAULT_MAX_PARALLEL, DEFAULT_FIX_BUDGET, DEFAULT_TRANSACTIONAL, DEFAULT_MAX_REVIEW_ROUNDS, DEFAULT_GRAPH_TIMEOUT_MS, DEFAULT_NODE_TIMEOUT_MS, DEFAULT_WRITER_NODE_TIMEOUT_MS, DEFAULT_CANCEL_GRACE_MS, MAX_UPSTREAM_CHARS_PER_DEP, MAX_UPSTREAM_CHARS_TOTAL, WRITER_KINDS2, REVIEWER_KINDS, KrakenGraphExecutor;
|
|
46202
46223
|
var init_executor = __esm({
|
|
46203
46224
|
"src/cli/kraken/executor.ts"() {
|
|
46204
46225
|
"use strict";
|
|
@@ -46232,6 +46253,12 @@ var init_executor = __esm({
|
|
|
46232
46253
|
DEFAULT_CANCEL_GRACE_MS = 3e4;
|
|
46233
46254
|
MAX_UPSTREAM_CHARS_PER_DEP = 2800;
|
|
46234
46255
|
MAX_UPSTREAM_CHARS_TOTAL = 8e3;
|
|
46256
|
+
WRITER_KINDS2 = /* @__PURE__ */ new Set(["general", "fix"]);
|
|
46257
|
+
REVIEWER_KINDS = /* @__PURE__ */ new Set([
|
|
46258
|
+
"verify",
|
|
46259
|
+
"spec",
|
|
46260
|
+
"conformance"
|
|
46261
|
+
]);
|
|
46235
46262
|
KrakenGraphExecutor = class {
|
|
46236
46263
|
deps;
|
|
46237
46264
|
parentCwd;
|
|
@@ -46353,7 +46380,7 @@ var init_executor = __esm({
|
|
|
46353
46380
|
}
|
|
46354
46381
|
}
|
|
46355
46382
|
isReviewerKind(kind2) {
|
|
46356
|
-
return kind2
|
|
46383
|
+
return REVIEWER_KINDS.has(kind2);
|
|
46357
46384
|
}
|
|
46358
46385
|
/** Execute the graph in place (mutates node statuses) until it settles. */
|
|
46359
46386
|
async execute(graph) {
|
|
@@ -47629,16 +47656,15 @@ function taskVerifyObligation() {
|
|
|
47629
47656
|
const g = globalThis;
|
|
47630
47657
|
return g.__zelariGeneralVerifyDebt ?? null;
|
|
47631
47658
|
}
|
|
47659
|
+
function outcomeMemoryAllowed() {
|
|
47660
|
+
return taskVerifyObligation() === null;
|
|
47661
|
+
}
|
|
47632
47662
|
function maxTaskSpawnsPerTurn() {
|
|
47633
47663
|
const raw = process.env.ZELARI_KRAKEN_MAX_TASK_SPAWNS;
|
|
47634
47664
|
if (raw === void 0 || raw === "") return 6;
|
|
47635
47665
|
const n = Number.parseInt(raw, 10);
|
|
47636
47666
|
return Number.isFinite(n) && n > 0 ? Math.min(n, 32) : 6;
|
|
47637
47667
|
}
|
|
47638
|
-
function verifyHintForGeneral(acceptance) {
|
|
47639
|
-
const acc = acceptance && acceptance.length > 0 ? ` Acceptance to check: ${acceptance.join("; ")}.` : "";
|
|
47640
|
-
return `[kraken:verify-hint] General tentacle finished. Before claiming done, run checks or spawn task agent=verify.${acc}`;
|
|
47641
|
-
}
|
|
47642
47668
|
function buildTaskAutoVerifyPrompt(args) {
|
|
47643
47669
|
const taskPrompt = args.prompt.length > MAX_AUTO_VERIFY_TASK_PROMPT_CHARS ? `${args.prompt.slice(0, MAX_AUTO_VERIFY_TASK_PROMPT_CHARS)}
|
|
47644
47670
|
\u2026 [truncated]` : args.prompt;
|
|
@@ -47656,7 +47682,7 @@ function buildTaskAutoVerifyPrompt(args) {
|
|
|
47656
47682
|
}
|
|
47657
47683
|
parts.push(
|
|
47658
47684
|
"",
|
|
47659
|
-
"Read the files
|
|
47685
|
+
"This brief is BLIND by design: it gives you the goal, the scope and the acceptance criteria ONLY \u2014 never the implementer's summary, self-assessment or claimed command output. Read the files on disk and run the acceptance commands yourself; a PASS must come from output YOU produced. Report the commands you ran and every gap you found.",
|
|
47660
47686
|
"",
|
|
47661
47687
|
"## How to report your verdict",
|
|
47662
47688
|
"End your final message with a line of exactly this form, as the LAST line:",
|
|
@@ -47680,6 +47706,36 @@ ${original.prompt}
|
|
|
47680
47706
|
## Reviewer findings (these are what must change)
|
|
47681
47707
|
${findings || "(the reviewer reported FAIL without detail)"}`;
|
|
47682
47708
|
}
|
|
47709
|
+
async function rememberVerifiedGeneralOutcome(opts) {
|
|
47710
|
+
const memoryService = opts.deps.memoryService;
|
|
47711
|
+
if (!memoryService || opts.deps.memoryAutoWrite === false) return;
|
|
47712
|
+
const content = (opts.general.result ?? "").trim();
|
|
47713
|
+
if (!content) return;
|
|
47714
|
+
try {
|
|
47715
|
+
await memoryService.remember({
|
|
47716
|
+
kind: "outcome",
|
|
47717
|
+
content: content.slice(0, 12e3),
|
|
47718
|
+
importance: 0.75,
|
|
47719
|
+
confidence: 0.98,
|
|
47720
|
+
tags: ["kraken", "tentacle:general"],
|
|
47721
|
+
source: {
|
|
47722
|
+
agent: "kraken-general",
|
|
47723
|
+
sessionId: opts.sessionId,
|
|
47724
|
+
...opts.general.agentId ? { tentacleId: opts.general.agentId } : {},
|
|
47725
|
+
...opts.general.worktreePath ? { worktree: opts.general.worktreePath } : {}
|
|
47726
|
+
},
|
|
47727
|
+
metadata: {
|
|
47728
|
+
writeClass: "auto",
|
|
47729
|
+
description: opts.original.description,
|
|
47730
|
+
scope: opts.original.scope ?? [],
|
|
47731
|
+
acceptance: opts.original.acceptance ?? [],
|
|
47732
|
+
verified: true
|
|
47733
|
+
},
|
|
47734
|
+
writeClass: "auto"
|
|
47735
|
+
});
|
|
47736
|
+
} catch {
|
|
47737
|
+
}
|
|
47738
|
+
}
|
|
47683
47739
|
async function runAutoVerifyAfterGeneral(opts) {
|
|
47684
47740
|
const g = globalThis;
|
|
47685
47741
|
g.__zelariGeneralVerifyDebt = { description: opts.original.description };
|
|
@@ -47769,6 +47825,7 @@ async function runAutoVerifyAfterGeneral(opts) {
|
|
|
47769
47825
|
}
|
|
47770
47826
|
if (verdict === "pass") {
|
|
47771
47827
|
g.__zelariGeneralVerifyDebt = null;
|
|
47828
|
+
await rememberVerifiedGeneralOutcome(opts);
|
|
47772
47829
|
emitVerifyPhase("verify PASS", true, "completed");
|
|
47773
47830
|
return `
|
|
47774
47831
|
|
|
@@ -48238,8 +48295,6 @@ worktree deferred: branch=${worktree.branch} path=${worktree.path} (executor mer
|
|
|
48238
48295
|
${formatWorktreeFooter(worktree, { kept, merge: merge2 })}`;
|
|
48239
48296
|
}
|
|
48240
48297
|
if (agent === "general") {
|
|
48241
|
-
footer += `
|
|
48242
|
-
${verifyHintForGeneral(args.acceptance)}`;
|
|
48243
48298
|
g.__zelariLastGeneralAt = Date.now();
|
|
48244
48299
|
}
|
|
48245
48300
|
endTentacle(liveId, {
|
|
@@ -48275,30 +48330,33 @@ ${verifyHintForGeneral(args.acceptance)}`;
|
|
|
48275
48330
|
if (deps.memoryService && deps.memoryAutoWrite !== false) {
|
|
48276
48331
|
try {
|
|
48277
48332
|
const verifyPass = agent === "verify" && /(?:VERDICT:\s*PASS|status:\s*pass)/i.test(result);
|
|
48278
|
-
const
|
|
48279
|
-
|
|
48280
|
-
|
|
48281
|
-
|
|
48282
|
-
|
|
48283
|
-
|
|
48284
|
-
|
|
48285
|
-
|
|
48286
|
-
|
|
48287
|
-
|
|
48288
|
-
|
|
48289
|
-
|
|
48290
|
-
|
|
48291
|
-
|
|
48292
|
-
|
|
48293
|
-
|
|
48294
|
-
|
|
48295
|
-
|
|
48296
|
-
|
|
48297
|
-
|
|
48298
|
-
|
|
48299
|
-
|
|
48300
|
-
|
|
48301
|
-
|
|
48333
|
+
const allowMemory = agent === "verify" ? verifyPass : agent === "general" ? false : outcomeMemoryAllowed();
|
|
48334
|
+
if (allowMemory) {
|
|
48335
|
+
const memory = await deps.memoryService.remember({
|
|
48336
|
+
kind: agent === "verify" ? "verification" : "finding",
|
|
48337
|
+
content: result.slice(0, 12e3),
|
|
48338
|
+
importance: 0.65,
|
|
48339
|
+
confidence: verifyPass ? 0.98 : 0.72,
|
|
48340
|
+
tags: ["kraken", `tentacle:${agent}`],
|
|
48341
|
+
source: {
|
|
48342
|
+
agent: `kraken-${agent}`,
|
|
48343
|
+
sessionId: sessionId2,
|
|
48344
|
+
tentacleId: opts.nodeId ?? liveId,
|
|
48345
|
+
...worktree?.path ? { worktree: worktree.path } : {}
|
|
48346
|
+
},
|
|
48347
|
+
metadata: {
|
|
48348
|
+
writeClass: agent === "verify" ? "auto" : "candidate",
|
|
48349
|
+
description: args.description,
|
|
48350
|
+
scope: args.scope ?? [],
|
|
48351
|
+
acceptance: args.acceptance ?? [],
|
|
48352
|
+
graphId: opts.graphId,
|
|
48353
|
+
nodeId: opts.nodeId,
|
|
48354
|
+
verified: verifyPass
|
|
48355
|
+
},
|
|
48356
|
+
writeClass: agent === "verify" ? "auto" : "candidate"
|
|
48357
|
+
});
|
|
48358
|
+
memoryId = memory.id;
|
|
48359
|
+
}
|
|
48302
48360
|
} catch {
|
|
48303
48361
|
}
|
|
48304
48362
|
}
|
|
@@ -48501,8 +48559,15 @@ var init_taskTool = __esm({
|
|
|
48501
48559
|
].join("\n");
|
|
48502
48560
|
VERIFY_PROMPT = [
|
|
48503
48561
|
"You are a VERIFY tentacle of Kraken. Confirm whether work is correct on disk.",
|
|
48504
|
-
"You
|
|
48505
|
-
"
|
|
48562
|
+
"You are BLIND: you never see \u2014 and must NEVER trust \u2014 any summary,",
|
|
48563
|
+
'self-assessment, or "result" reported by the agent that did the work. If such',
|
|
48564
|
+
"text is ever shown to you, treat it as an unverified claim, not evidence.",
|
|
48565
|
+
"You may read files and run test/build commands via bash. Run the acceptance",
|
|
48566
|
+
"commands YOURSELF and derive every verdict ONLY from the real command output",
|
|
48567
|
+
"you observed (exit code + stdout/stderr) and the files as they exist on disk.",
|
|
48568
|
+
"Never mark something pass because it was described as done, or because a",
|
|
48569
|
+
"claim said a command was green: a pass needs evidence YOU produced this run.",
|
|
48570
|
+
"Prefer targeted checks over full suite when possible.",
|
|
48506
48571
|
"Report: pass/fail, commands run, key output, and gaps vs Acceptance criteria.",
|
|
48507
48572
|
"If Acceptance criteria are listed, check each one explicitly.",
|
|
48508
48573
|
"End your final message with ONE <verify-report> block per acceptance",
|
|
@@ -60163,6 +60228,9 @@ function emptyResult(enabled, skippedReason) {
|
|
|
60163
60228
|
checkProposals: []
|
|
60164
60229
|
};
|
|
60165
60230
|
}
|
|
60231
|
+
function skippedOpsKnowledgeResult(reason) {
|
|
60232
|
+
return emptyResult(true, reason);
|
|
60233
|
+
}
|
|
60166
60234
|
async function openMemory(projectRoot, env) {
|
|
60167
60235
|
try {
|
|
60168
60236
|
const factory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
@@ -70562,6 +70630,7 @@ async function writeProofSafe(gate, meta3, baseDir = process.cwd()) {
|
|
|
70562
70630
|
`
|
|
70563
70631
|
);
|
|
70564
70632
|
}
|
|
70633
|
+
if (!outcomeMemoryAllowed()) return skippedOpsKnowledgeResult("verify-obligation-open");
|
|
70565
70634
|
return promoteOpsKnowledgeSafe(gate, { projectRoot: baseDir, sessionId: meta3.sessionId });
|
|
70566
70635
|
}
|
|
70567
70636
|
function surfaceOpsKnowledgeNotices(result, opts) {
|
|
@@ -71104,7 +71173,7 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
71104
71173
|
} catch {
|
|
71105
71174
|
}
|
|
71106
71175
|
}
|
|
71107
|
-
if (nativeMemory && memoryAutoWrite && pass.finalReason !== "error") {
|
|
71176
|
+
if (nativeMemory && memoryAutoWrite && pass.finalReason !== "error" && outcomeMemoryAllowed()) {
|
|
71108
71177
|
try {
|
|
71109
71178
|
const finalContent = [...pass.messages].reverse().find((message) => message.role === "assistant" && message.content.trim())?.content.trim();
|
|
71110
71179
|
if (finalContent) {
|
|
@@ -77785,26 +77854,59 @@ import { Box as Box9, Static, useInput as useInput2, useStdin as useStdin2 } fro
|
|
|
77785
77854
|
import React from "react";
|
|
77786
77855
|
import { Box, Text } from "ink";
|
|
77787
77856
|
import TextInput from "ink-text-input";
|
|
77788
|
-
|
|
77857
|
+
|
|
77858
|
+
// src/cli/components/inputDraft.ts
|
|
77859
|
+
import { useSyncExternalStore } from "react";
|
|
77860
|
+
function createInputDraftStore(initial = "") {
|
|
77861
|
+
let value = initial;
|
|
77862
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
77863
|
+
const emit = () => {
|
|
77864
|
+
for (const listener of listeners) listener();
|
|
77865
|
+
};
|
|
77866
|
+
return {
|
|
77867
|
+
get: () => value,
|
|
77868
|
+
set(next) {
|
|
77869
|
+
if (next === value) return;
|
|
77870
|
+
value = next;
|
|
77871
|
+
emit();
|
|
77872
|
+
},
|
|
77873
|
+
clear() {
|
|
77874
|
+
if (value === "") return;
|
|
77875
|
+
value = "";
|
|
77876
|
+
emit();
|
|
77877
|
+
},
|
|
77878
|
+
subscribe(listener) {
|
|
77879
|
+
listeners.add(listener);
|
|
77880
|
+
return () => {
|
|
77881
|
+
listeners.delete(listener);
|
|
77882
|
+
};
|
|
77883
|
+
}
|
|
77884
|
+
};
|
|
77885
|
+
}
|
|
77886
|
+
function useInputDraft(store6) {
|
|
77887
|
+
return useSyncExternalStore(store6.subscribe, store6.get, store6.get);
|
|
77888
|
+
}
|
|
77889
|
+
|
|
77890
|
+
// src/cli/components/InputBar.tsx
|
|
77891
|
+
function InputBarImpl({ draft, onSubmit, disabled }) {
|
|
77892
|
+
const value = useInputDraft(draft);
|
|
77789
77893
|
const onSubmitRef = React.useRef(onSubmit);
|
|
77790
|
-
const onChangeRef = React.useRef(onChange);
|
|
77791
77894
|
onSubmitRef.current = onSubmit;
|
|
77792
|
-
onChangeRef.current = onChange;
|
|
77793
77895
|
const stableSubmit = React.useCallback((v) => onSubmitRef.current(v), []);
|
|
77794
|
-
const stableChange = React.useCallback((v) => onChangeRef.current(v), []);
|
|
77795
77896
|
return /* @__PURE__ */ React.createElement(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "cyan", bold: true }, "\u276F "), /* @__PURE__ */ React.createElement(
|
|
77796
77897
|
TextInput,
|
|
77797
77898
|
{
|
|
77798
77899
|
value,
|
|
77799
|
-
onChange:
|
|
77900
|
+
onChange: draft.set,
|
|
77800
77901
|
onSubmit: stableSubmit,
|
|
77801
77902
|
placeholder: disabled ? "..." : "Prompt, /skills, or @path"
|
|
77802
77903
|
}
|
|
77803
77904
|
));
|
|
77804
77905
|
}
|
|
77805
|
-
|
|
77806
|
-
return prev2.
|
|
77807
|
-
}
|
|
77906
|
+
function inputBarPropsEqual(prev2, next) {
|
|
77907
|
+
return prev2.draft === next.draft && prev2.disabled === next.disabled;
|
|
77908
|
+
}
|
|
77909
|
+
var InputBar = React.memo(InputBarImpl, inputBarPropsEqual);
|
|
77808
77910
|
|
|
77809
77911
|
// src/cli/components/LiveRegion.tsx
|
|
77810
77912
|
import React5 from "react";
|
|
@@ -77961,7 +78063,7 @@ init_duration();
|
|
|
77961
78063
|
init_modelPricing();
|
|
77962
78064
|
import React6 from "react";
|
|
77963
78065
|
import { Box as Box5, Text as Text6 } from "ink";
|
|
77964
|
-
function
|
|
78066
|
+
function StatusBarImpl({
|
|
77965
78067
|
model,
|
|
77966
78068
|
provider,
|
|
77967
78069
|
sessionId: sessionId2,
|
|
@@ -77990,6 +78092,15 @@ function StatusBar({
|
|
|
77990
78092
|
const modeColor = mode === "council" ? "magenta" : mode === "zelari" ? "green" : "red";
|
|
77991
78093
|
return /* @__PURE__ */ React6.createElement(Box5, { paddingX: 1, width: "100%", justifyContent: "space-between", gap: 2 }, /* @__PURE__ */ React6.createElement(Box5, { flexShrink: 2 }, /* @__PURE__ */ React6.createElement(Text6, { wrap: "truncate" }, /* @__PURE__ */ React6.createElement(Text6, { color: sessionActive ? "green" : "gray" }, sessionActive ? "\u25CF" : "\u25CB"), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " "), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: phase2 === "plan" ? "yellow" : "green" }, phase2 === "plan" ? "\u25C7 plan" : "\u25C6 build"), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: modeColor }, modeLabel), verify ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: verify.tone }, verify.label)) : null, permissions ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: permissions.tone }, permissions.label)) : null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), jail ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: jail.tone }, jail.label)) : null, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, provider), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text6, null, model), cwd ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text6, { color: "blue" }, cwd)) : null)), /* @__PURE__ */ React6.createElement(Box5, { flexShrink: 1 }, /* @__PURE__ */ React6.createElement(Text6, { wrap: "truncate" }, busy && elapsedMs !== null ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Spinner, { color: "yellow" }), /* @__PURE__ */ React6.createElement(Text6, { color: "yellow" }, " ", formatDuration(elapsedMs)), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : lastMs !== null ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, "last ", formatDuration(lastMs)), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, queueCount > 0 ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { color: "magenta" }, "queue ", queueCount), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, todoSummary ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { color: "yellow" }, todoSummary), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, krakenLive ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { color: "magenta" }, krakenLive), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, krakenGraph ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { color: "magenta" }, krakenGraph), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, ctxLabel ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { color: "cyan" }, ctxLabel), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, costUsd > 0 ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { color: "green" }, formatCost(costUsd)), cachedTokens > 0 ? /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " (", formatTokens(cachedTokens), " cached)") : null, cacheHitRate > 0 ? /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " ", Math.round(cacheHitRate * 100), "% hit") : null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " \xB7 ")) : null, /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, "session ", sessionId2))));
|
|
77992
78094
|
}
|
|
78095
|
+
function statusChipPropsEqual(prev2, next) {
|
|
78096
|
+
if (prev2 === next) return true;
|
|
78097
|
+
if (!prev2 || !next) return false;
|
|
78098
|
+
return prev2.label === next.label && prev2.tone === next.tone;
|
|
78099
|
+
}
|
|
78100
|
+
function statusBarPropsEqual(prev2, next) {
|
|
78101
|
+
return prev2.model === next.model && prev2.provider === next.provider && prev2.sessionId === next.sessionId && prev2.sessionActive === next.sessionActive && prev2.queueCount === next.queueCount && prev2.busy === next.busy && prev2.mode === next.mode && prev2.phase === next.phase && prev2.cwd === next.cwd && prev2.elapsedMs === next.elapsedMs && prev2.lastMs === next.lastMs && prev2.costUsd === next.costUsd && prev2.cachedTokens === next.cachedTokens && prev2.cacheHitRate === next.cacheHitRate && prev2.contextUsed === next.contextUsed && prev2.contextLimit === next.contextLimit && prev2.todoSummary === next.todoSummary && prev2.krakenLive === next.krakenLive && prev2.krakenGraph === next.krakenGraph && statusChipPropsEqual(prev2.verify, next.verify) && statusChipPropsEqual(prev2.permissions, next.permissions) && statusChipPropsEqual(prev2.jail, next.jail);
|
|
78102
|
+
}
|
|
78103
|
+
var StatusBar = React6.memo(StatusBarImpl, statusBarPropsEqual);
|
|
77993
78104
|
|
|
77994
78105
|
// src/cli/components/SelectList.tsx
|
|
77995
78106
|
import React7, { useState as useState2 } from "react";
|
|
@@ -78199,32 +78310,56 @@ async function snapshotGitChanges(cwd) {
|
|
|
78199
78310
|
files: mergeChanges(parseNumstat(unstaged), parseNumstat(staged), parseUntracked(status))
|
|
78200
78311
|
};
|
|
78201
78312
|
}
|
|
78313
|
+
var GIT_POLL_MS = 4e3;
|
|
78314
|
+
var GIT_IDLE_POLL_MS = 2e4;
|
|
78315
|
+
var GIT_IDLE_AFTER_TICKS = 3;
|
|
78316
|
+
function nextGitPollDelay(quietTicks, opts) {
|
|
78317
|
+
if (opts.hot) return opts.pollMs;
|
|
78318
|
+
return quietTicks >= opts.idleAfterTicks ? Math.max(opts.pollMs, opts.idlePollMs) : opts.pollMs;
|
|
78319
|
+
}
|
|
78202
78320
|
function useGitChanges(opts = {}) {
|
|
78203
|
-
const {
|
|
78321
|
+
const {
|
|
78322
|
+
pollMs = GIT_POLL_MS,
|
|
78323
|
+
idlePollMs = GIT_IDLE_POLL_MS,
|
|
78324
|
+
idleAfterTicks = GIT_IDLE_AFTER_TICKS,
|
|
78325
|
+
hot = false,
|
|
78326
|
+
cwd = process.cwd(),
|
|
78327
|
+
snapshot = snapshotGitChanges
|
|
78328
|
+
} = opts;
|
|
78204
78329
|
const [changes, setChanges] = useState3(EMPTY_GIT_CHANGES);
|
|
78205
78330
|
const lastJson = useRef("");
|
|
78206
78331
|
useEffect2(() => {
|
|
78207
78332
|
let cancelled = false;
|
|
78208
78333
|
let timer = null;
|
|
78334
|
+
let quiet = 0;
|
|
78209
78335
|
const tick = async () => {
|
|
78210
78336
|
try {
|
|
78211
|
-
const snap = await
|
|
78337
|
+
const snap = await snapshot(cwd);
|
|
78212
78338
|
if (cancelled) return;
|
|
78213
78339
|
const json3 = JSON.stringify(snap);
|
|
78214
78340
|
if (json3 !== lastJson.current) {
|
|
78215
78341
|
lastJson.current = json3;
|
|
78342
|
+
quiet = 0;
|
|
78216
78343
|
setChanges(snap);
|
|
78344
|
+
} else {
|
|
78345
|
+
quiet += 1;
|
|
78217
78346
|
}
|
|
78218
78347
|
} catch {
|
|
78348
|
+
quiet += 1;
|
|
78349
|
+
}
|
|
78350
|
+
if (!cancelled) {
|
|
78351
|
+
timer = setTimeout(
|
|
78352
|
+
tick,
|
|
78353
|
+
nextGitPollDelay(quiet, { pollMs, idlePollMs, idleAfterTicks, hot })
|
|
78354
|
+
);
|
|
78219
78355
|
}
|
|
78220
|
-
if (!cancelled) timer = setTimeout(tick, pollMs);
|
|
78221
78356
|
};
|
|
78222
78357
|
void tick();
|
|
78223
78358
|
return () => {
|
|
78224
78359
|
cancelled = true;
|
|
78225
78360
|
if (timer !== null) clearTimeout(timer);
|
|
78226
78361
|
};
|
|
78227
|
-
}, [pollMs, cwd]);
|
|
78362
|
+
}, [pollMs, idlePollMs, idleAfterTicks, hot, cwd, snapshot]);
|
|
78228
78363
|
return changes;
|
|
78229
78364
|
}
|
|
78230
78365
|
|
|
@@ -78258,7 +78393,39 @@ init_paths2();
|
|
|
78258
78393
|
init_sessionTodos();
|
|
78259
78394
|
init_krakenLive();
|
|
78260
78395
|
init_verifyStatus();
|
|
78396
|
+
|
|
78397
|
+
// src/cli/components/statusChips.ts
|
|
78261
78398
|
init_osJail();
|
|
78399
|
+
init_policyLoadMode();
|
|
78400
|
+
function jailStatusChip(env = process.env, platform = process.platform) {
|
|
78401
|
+
const mode = activeJailMode(env);
|
|
78402
|
+
if (mode === "off") return null;
|
|
78403
|
+
const probe = probeJailBackend(platform);
|
|
78404
|
+
if (!probe.available) {
|
|
78405
|
+
return { label: `jail: advisory (${probe.backend})`, tone: "yellow" };
|
|
78406
|
+
}
|
|
78407
|
+
return mode === "required" ? { label: `jail: on (${probe.backend})`, tone: "green" } : { label: `jail: advisory (${probe.backend})`, tone: "yellow" };
|
|
78408
|
+
}
|
|
78409
|
+
function jailChipKey(env, platform) {
|
|
78410
|
+
return [
|
|
78411
|
+
platform,
|
|
78412
|
+
env[OS_JAIL_ENV] ?? "",
|
|
78413
|
+
env.ZELARI_PERMISSION_PRESET ?? "",
|
|
78414
|
+
env[POLICY_LOAD_MODE_ENV] ?? "",
|
|
78415
|
+
env.CI ?? "",
|
|
78416
|
+
activePolicyLoadSurface()
|
|
78417
|
+
].join("|");
|
|
78418
|
+
}
|
|
78419
|
+
var chipCache = null;
|
|
78420
|
+
function cachedJailStatusChip(env = process.env, platform = process.platform) {
|
|
78421
|
+
const key = jailChipKey(env, platform);
|
|
78422
|
+
if (chipCache && chipCache.key === key) return chipCache.chip;
|
|
78423
|
+
const chip = jailStatusChip(env, platform);
|
|
78424
|
+
chipCache = { key, chip };
|
|
78425
|
+
return chip;
|
|
78426
|
+
}
|
|
78427
|
+
|
|
78428
|
+
// src/cli/app.tsx
|
|
78262
78429
|
init_graphStatus();
|
|
78263
78430
|
|
|
78264
78431
|
// packages/core/dist/agents/skills/builtin/debugging.js
|
|
@@ -81375,10 +81542,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
81375
81542
|
() => void 0,
|
|
81376
81543
|
() => void 0
|
|
81377
81544
|
);
|
|
81378
|
-
const opsKnowledge = await promoteOpsKnowledgeSafe(gate, {
|
|
81379
|
-
projectRoot: process.cwd(),
|
|
81380
|
-
sessionId: sessionId2
|
|
81381
|
-
});
|
|
81545
|
+
const opsKnowledge = outcomeMemoryAllowed() ? await promoteOpsKnowledgeSafe(gate, { projectRoot: process.cwd(), sessionId: sessionId2 }) : skippedOpsKnowledgeResult("verify-obligation-open");
|
|
81382
81546
|
const notices = [
|
|
81383
81547
|
...opsKnowledge.proposals,
|
|
81384
81548
|
...opsKnowledge.checkProposals.map(formatCheckProposalNotice)
|
|
@@ -81707,7 +81871,7 @@ _(${clar.context})_` : "") + "\n\u2192 scegli dalla lista oppure digita la rispo
|
|
|
81707
81871
|
} catch {
|
|
81708
81872
|
}
|
|
81709
81873
|
}
|
|
81710
|
-
if (memoryService && memoryAutoWrite && turnSucceeded && assistantContent.trim()) {
|
|
81874
|
+
if (memoryService && memoryAutoWrite && turnSucceeded && assistantContent.trim() && outcomeMemoryAllowed()) {
|
|
81711
81875
|
try {
|
|
81712
81876
|
const cleanedOutcome = cleanAgentContent(assistantContent, {
|
|
81713
81877
|
stripQuestion: true,
|
|
@@ -86580,15 +86744,6 @@ function useTerminalSize(options = {}) {
|
|
|
86580
86744
|
// src/cli/app.tsx
|
|
86581
86745
|
init_chatStats();
|
|
86582
86746
|
init_duration();
|
|
86583
|
-
function jailStatusChip() {
|
|
86584
|
-
const mode = activeJailMode();
|
|
86585
|
-
if (mode === "off") return null;
|
|
86586
|
-
const probe = probeJailBackend();
|
|
86587
|
-
if (!probe.available) {
|
|
86588
|
-
return { label: `jail: advisory (${probe.backend})`, tone: "yellow" };
|
|
86589
|
-
}
|
|
86590
|
-
return mode === "required" ? { label: `jail: on (${probe.backend})`, tone: "green" } : { label: `jail: advisory (${probe.backend})`, tone: "yellow" };
|
|
86591
|
-
}
|
|
86592
86747
|
var MODEL = process.env.OPENAI_MODEL ?? "grok-4.5";
|
|
86593
86748
|
var providerDefaults = {
|
|
86594
86749
|
"openai-compatible": "grok-4.5",
|
|
@@ -86600,7 +86755,8 @@ var providerDefaults = {
|
|
|
86600
86755
|
"anthropic": "claude-sonnet-4-5"
|
|
86601
86756
|
};
|
|
86602
86757
|
function App() {
|
|
86603
|
-
const [
|
|
86758
|
+
const [inputDraft] = useState8(() => createInputDraftStore());
|
|
86759
|
+
const setInput = useCallback5((value) => inputDraft.set(value), [inputDraft]);
|
|
86604
86760
|
const [busy, setBusy] = useState8(false);
|
|
86605
86761
|
const [providerConfig, setProviderConfig] = useState8(() => getProviderConfig());
|
|
86606
86762
|
const [sessionStats, setSessionStats] = useState8({
|
|
@@ -86628,7 +86784,6 @@ function App() {
|
|
|
86628
86784
|
const session = useSession();
|
|
86629
86785
|
usePermissionBroker({ setPicker: setPicker2, setMessages: session.setMessages });
|
|
86630
86786
|
const size = useTerminalSize();
|
|
86631
|
-
const gitChanges = useGitChanges();
|
|
86632
86787
|
const cwd = useMemo(() => shortenCwd(process.cwd(), 32), []);
|
|
86633
86788
|
const timer = useExecutionTimer(busy);
|
|
86634
86789
|
const { isRawModeSupported } = useStdin2();
|
|
@@ -86742,6 +86897,7 @@ function App() {
|
|
|
86742
86897
|
useEffect8(() => {
|
|
86743
86898
|
setSidebarOpen((prev2) => sidebarVisibility(size.columns, size.rows, prev2));
|
|
86744
86899
|
}, [size.columns, size.rows]);
|
|
86900
|
+
const gitChanges = useGitChanges({ hot: busy || sidebarOpen });
|
|
86745
86901
|
const staticKey = `${session.sessionId || "pre-bootstrap"}-${clearEpoch}`;
|
|
86746
86902
|
const staticItems = session.sessionId ? [banner, ...session.messages] : [];
|
|
86747
86903
|
return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Static, { key: staticKey, items: staticItems }, (item) => item.id === "banner-once" ? /* @__PURE__ */ React10.createElement(
|
|
@@ -86776,8 +86932,7 @@ function App() {
|
|
|
86776
86932
|
) : /* @__PURE__ */ React10.createElement(
|
|
86777
86933
|
InputBar,
|
|
86778
86934
|
{
|
|
86779
|
-
|
|
86780
|
-
onChange: setInput,
|
|
86935
|
+
draft: inputDraft,
|
|
86781
86936
|
onSubmit: handleSubmit,
|
|
86782
86937
|
disabled: busy
|
|
86783
86938
|
}
|
|
@@ -86805,7 +86960,7 @@ function App() {
|
|
|
86805
86960
|
krakenGraph: formatKrakenGraphSummary() ?? void 0,
|
|
86806
86961
|
verify: getVerifyChip() ?? void 0,
|
|
86807
86962
|
permissions: permissionsChip(phase2),
|
|
86808
|
-
jail:
|
|
86963
|
+
jail: cachedJailStatusChip()
|
|
86809
86964
|
}
|
|
86810
86965
|
)), sidebarOpen && /* @__PURE__ */ React10.createElement(Sidebar, { version: VERSION, changes: gitChanges, rows: size.rows })));
|
|
86811
86966
|
}
|
|
@@ -87761,17 +87916,8 @@ function runPreflight() {
|
|
|
87761
87916
|
}
|
|
87762
87917
|
async function backgroundUpdateCheck() {
|
|
87763
87918
|
if (process.env.ANATHEMA_DEV === "1") return;
|
|
87764
|
-
await
|
|
87765
|
-
|
|
87766
|
-
const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_updater(), updater_exports));
|
|
87767
|
-
const info = await checkForUpdate2();
|
|
87768
|
-
if (info.updateAvailable && !info.error) {
|
|
87769
|
-
console.error(
|
|
87770
|
-
`[zelari-code] \u{1F195} v${info.latestVersion} available (current: v${info.currentVersion}). Run \`zelari-code\` then \`/update --yes\` to upgrade.`
|
|
87771
|
-
);
|
|
87772
|
-
}
|
|
87773
|
-
} catch {
|
|
87774
|
-
}
|
|
87919
|
+
const { runDeferredUpdateCheck: runDeferredUpdateCheck2 } = await Promise.resolve().then(() => (init_updater(), updater_exports));
|
|
87920
|
+
await runDeferredUpdateCheck2();
|
|
87775
87921
|
}
|
|
87776
87922
|
async function shutdown() {
|
|
87777
87923
|
try {
|