@desplega.ai/agent-swarm 1.131.0 → 1.133.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/README.md +2 -2
- package/dist/{actions-w53mbns9.js → actions-cskpayd7.js} +11 -9
- package/dist/{anthropic-messages-rjmd2e7n.js → anthropic-messages-tpxtbx7b.js} +28 -12
- package/dist/{app-m9gwqsqv.js → app-ang77nbb.js} +8 -6
- package/dist/{assistant-bp65m6f3.js → assistant-b4exebdw.js} +16 -13
- package/dist/{azure-openai-responses-c0yjmbfd.js → azure-openai-responses-m3921t4y.js} +8 -8
- package/dist/{boot-reembed-62p0at2k.js → boot-reembed-ps2aftpb.js} +9 -7
- package/dist/{boot-reembed-xmfp6wdh.js → boot-reembed-znyk3nxb.js} +10 -8
- package/dist/{boot-scrub-logs-rr8q2dms.js → boot-scrub-logs-2ax3xgz1.js} +7 -5
- package/dist/{claude-adapter-2y47mrkd.js → claude-adapter-3ct8kgxw.js} +13 -9
- package/dist/{claude-managed-adapter-gv19tdew.js → claude-managed-adapter-akx4ntf2.js} +2 -2
- package/dist/{cli-t1xze5qh.js → cli-13w2hwkh.js} +1 -1
- package/dist/{cli-efxfnq6q.js → cli-1532szb1.js} +8 -6
- package/dist/{cli-d2tfkcga.js → cli-23d3rseb.js} +33 -17
- package/dist/{cli-nm5gtp1x.js → cli-2a75z9c5.js} +196 -7
- package/dist/{cli-fywms69x.js → cli-2t30rj0d.js} +1 -1
- package/dist/{cli-cvgjwnh1.js → cli-3c3tdgab.js} +10 -10
- package/dist/{cli-pm6xbh84.js → cli-3zzxa9jz.js} +46 -16
- package/dist/{cli-cdeg08wx.js → cli-4k6233gc.js} +1 -1
- package/dist/{cli-t55yw3a1.js → cli-5p2tz05r.js} +2 -2
- package/dist/{cli-0rcyq6d9.js → cli-5z2yhzvd.js} +125 -47
- package/dist/{cli-3kf51j15.js → cli-6zfq31nj.js} +9 -3
- package/dist/{cli-er3a4bb0.js → cli-8m9de10a.js} +6 -1
- package/dist/{cli-gm9cbhbq.js → cli-8t14vg9w.js} +27 -8
- package/dist/{cli-72q8m8gk.js → cli-9nfc2es8.js} +6 -6
- package/dist/{cli-5ze9rv97.js → cli-9ta3pwms.js} +11 -4
- package/dist/{cli-78xwvkhj.js → cli-avr0ns7z.js} +2 -2
- package/dist/{cli-n6h8qt8n.js → cli-c897wyhw.js} +12 -7
- package/dist/{cli-2q72qz2s.js → cli-dgk20ft7.js} +15 -6
- package/dist/cli-et1bbwqf.js +13 -0
- package/dist/{cli-bqw0mt1n.js → cli-f5w27pj3.js} +3 -3
- package/dist/{cli-2wadx7p2.js → cli-f8dre4bz.js} +2 -2
- package/dist/{cli-e7ckcg4v.js → cli-ftwpv451.js} +170 -387
- package/dist/{cli-g6b8x1h8.js → cli-g854s2dw.js} +1 -1
- package/dist/{cli-5kx36evn.js → cli-ggmdxeqa.js} +13 -8
- package/dist/cli-hkwfe3qj.js +530 -0
- package/dist/{cli-5dsbcjjw.js → cli-jqwnqx9m.js} +1 -1
- package/dist/{cli-9dr5qzc0.js → cli-ny122vh4.js} +21 -10
- package/dist/{cli-5v4rw6yd.js → cli-pvzqhbs9.js} +2 -2
- package/dist/cli-pzq5rjym.js +15 -0
- package/dist/{cli-xpxde7rm.js → cli-qes8ef67.js} +48 -30
- package/dist/{cli-sajgpkqg.js → cli-qs9hhsvb.js} +1723 -325
- package/dist/cli-qys3rhhz.js +27 -0
- package/dist/{cli-rzbpmxdr.js → cli-r6tpm37h.js} +2 -2
- package/dist/{cli-qv61hp37.js → cli-rch80c76.js} +2 -2
- package/dist/{cli-0258203w.js → cli-rpp0x4zy.js} +137 -17
- package/dist/{cli-5n6e5yfn.js → cli-s1k0wxhe.js} +12 -7
- package/dist/{cli-psh3c4va.js → cli-sfd9v7sj.js} +1 -1
- package/dist/{cli-70xqj0z3.js → cli-sh3ytsyj.js} +49 -39
- package/dist/{cli-zsspvvm2.js → cli-w1mp9jy7.js} +1 -1
- package/dist/{cli-d3x3x1c9.js → cli-xdb4mpnp.js} +2 -2
- package/dist/{cli-57khth04.js → cli-xmyqv00z.js} +120 -4
- package/dist/{cli-yw8vghx2.js → cli-xv8t8p3c.js} +65 -32
- package/dist/{cli-f1am9szv.js → cli-xxv5pn4f.js} +1 -1
- package/dist/{cli-t76vw5db.js → cli-y08jvxzx.js} +601 -140
- package/dist/{cli-a4jzdpa3.js → cli-zfbf3srj.js} +650 -245
- package/dist/{cli-a40rnf71.js → cli-zmq89k34.js} +6 -6
- package/dist/{cli-qmdnhpej.js → cli-zr9q011v.js} +23 -13
- package/dist/cli.js +22 -22
- package/dist/{codex-adapter-d24q75wk.js → codex-adapter-bef93pq4.js} +9 -7
- package/dist/{codex-hook-hq54t9ft.js → codex-hook-e8dba65p.js} +3 -2
- package/dist/{codex-session-runner-g50vcsex.js → codex-session-runner-5pkxys7x.js} +9 -7
- package/dist/{commands-c3nrc5hg.js → commands-e23s1bff.js} +9 -7
- package/dist/{db-nt7fg3tw.js → db-m3nabatn.js} +17 -5
- package/dist/{google-generative-ai-hysrd8qx.js → google-generative-ai-8maw55xh.js} +11 -8
- package/dist/{google-vertex-p5arrga0.js → google-vertex-8vjqmx8g.js} +11 -8
- package/dist/{handlers-fkr6swat.js → handlers-akazedvr.js} +16 -13
- package/dist/{hook-77wpvnjc.js → hook-ze4cpf0v.js} +55 -41
- package/dist/{hook-g019yehy.js → hook-zfqyyenw.js} +10 -7
- package/dist/{http-jewj0syk.js → http-sja0n6kw.js} +730 -150
- package/dist/index-0gr8vd6k.js +39 -0
- package/dist/{index-7n2xpbd4.js → index-354vkhdv.js} +154 -74
- package/dist/{index-070v4eyb.js → index-5qthek5t.js} +2 -3
- package/dist/{index-hfvggd0z.js → index-95t3cqq5.js} +16 -14
- package/dist/{index-9znhar3x.js → index-sea66619.js} +3 -4
- package/dist/{index-6gm5he8h.js → index-vpn36mma.js} +15 -13
- package/dist/{keepalive-j0fjvqfd.js → keepalive-3sp3meqj.js} +16 -10
- package/dist/{lead-1n8x30xe.js → lead-mefeewkf.js} +39 -36
- package/dist/{maintenance-gvev11sa.js → maintenance-8tbrbjfg.js} +10 -8
- package/dist/mistral-conversations-00zrp7g4.js +717 -0
- package/dist/{oauth-refresh-sweep-s9ecsvh0.js → oauth-refresh-sweep-srjwjz6m.js} +8 -6
- package/dist/{onboard-pvm5b38w.js → onboard-mt2tgyjg.js} +7 -7
- package/dist/{openai-codex-responses-5g27pd6f.js → openai-codex-responses-map32h2s.js} +18 -18
- package/dist/{openai-completions-3vkmfz2a.js → openai-completions-w871b1cq.js} +12 -11
- package/dist/{openai-responses-dg4t7j7a.js → openai-responses-b0j7xnw8.js} +15 -12
- package/dist/{opencode-adapter-1gm38aba.js → opencode-adapter-b39jefcj.js} +5 -3
- package/dist/{openrouter-images-g3gm8931.js → openrouter-images-srfkywy0.js} +4 -4
- package/dist/{otel-impl-p6jvgd9c.js → otel-impl-z6pxt3j9.js} +224 -9
- package/dist/{pi-mono-adapter-t091s27g.js → pi-mono-adapter-btvqmj58.js} +1138 -408
- package/dist/{pricing-refresh-k49rcyed.js → pricing-refresh-kyq8cezh.js} +9 -7
- package/dist/{rbac-roles-cr80g96t.js → rbac-roles-3ryfrfna.js} +8 -6
- package/dist/{rbac-roles-30pspvy7.js → rbac-roles-6qfvbee1.js} +9 -7
- package/dist/{render-v2-xm457ng1.js → render-v2-p61ppjey.js} +8 -6
- package/dist/{seed-pricing-yhpv35fr.js → seed-pricing-j56bbj4y.js} +8 -6
- package/dist/{setup-nytnmwwr.js → setup-tpr6c1kn.js} +2 -2
- package/dist/{worker-msytr2cw.js → worker-9w1v0mbb.js} +39 -36
- package/openapi.json +542 -16
- package/package.json +6 -6
- package/src/be/budget-refusal-notify.ts +14 -7
- package/src/be/db-queries/task-artifacts.ts +182 -0
- package/src/be/db.ts +783 -169
- package/src/be/events.ts +5 -0
- package/src/be/migrations/130_scratch_script_retention_grace.sql +6 -0
- package/src/be/migrations/131_session_logs_created_at_index.sql +2 -0
- package/src/be/migrations/132_multi_runtime_instances.sql +44 -0
- package/src/be/migrations/133_workflow_run_trigger_type.sql +12 -0
- package/src/be/migrations/135_backfill_task_pull_request_attachments.sql +228 -0
- package/src/be/migrations/136_task_requester_provenance.sql +37 -0
- package/src/be/migrations/137_memory_retrieval_composite_index.sql +1 -0
- package/src/be/multi-runtime.ts +430 -0
- package/src/be/scripts/db.ts +43 -1
- package/src/be/scripts/extract-schema.ts +3 -1
- package/src/be/scripts/retention.ts +164 -0
- package/src/be/scripts/run-saved.ts +16 -1
- package/src/be/scripts/typecheck.ts +3 -2
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/steering.ts +1 -1
- package/src/be/swarm-config-guard.ts +18 -0
- package/src/commands/credential-wait.ts +54 -0
- package/src/commands/onboard/steps/core-credentials.tsx +1 -1
- package/src/commands/onboard/steps/custom-templates.tsx +1 -1
- package/src/commands/onboard/steps/harness-credentials.tsx +1 -1
- package/src/commands/onboard/steps/health-check.tsx +1 -1
- package/src/commands/onboard/steps/start.tsx +1 -1
- package/src/commands/profile-sync-audit.ts +56 -0
- package/src/commands/profile-sync.ts +287 -15
- package/src/commands/provider-credentials.ts +46 -19
- package/src/commands/runner.ts +196 -33
- package/src/commands/templates.ts +22 -0
- package/src/github/handlers.ts +55 -9
- package/src/heartbeat/heartbeat.ts +71 -12
- package/src/hooks/hook.ts +49 -33
- package/src/http/active-sessions.ts +11 -1
- package/src/http/agents.ts +261 -30
- package/src/http/all-routes.ts +1 -0
- package/src/http/config.ts +13 -2
- package/src/http/core.ts +102 -4
- package/src/http/db-query-bounded.ts +313 -0
- package/src/http/db-query-shared.ts +249 -0
- package/src/http/db-query.ts +54 -42
- package/src/http/events.ts +2 -0
- package/src/http/index.ts +27 -2
- package/src/http/mcp-bridge.ts +37 -3
- package/src/http/mcp.ts +12 -0
- package/src/http/memory.ts +13 -2
- package/src/http/openapi.ts +1 -0
- package/src/http/poll.ts +70 -27
- package/src/http/route-def.ts +43 -9
- package/src/http/schedules.ts +2 -2
- package/src/http/scripts.ts +31 -4
- package/src/http/session-data.ts +44 -0
- package/src/http/tasks.ts +2 -2
- package/src/http/users.ts +74 -52
- package/src/http/webhooks.ts +5 -2
- package/src/http/workflows.ts +1 -4
- package/src/http/x.ts +14 -0
- package/src/integrations/kapso/inbound.ts +1 -1
- package/src/jira/outbound.ts +39 -8
- package/src/jira/webhook-lifecycle.ts +13 -2
- package/src/linear/outbound.ts +43 -10
- package/src/oauth/keepalive.ts +13 -2
- package/src/prompts/base-prompt.ts +1 -1
- package/src/prompts/session-templates.ts +45 -7
- package/src/providers/claude-adapter.ts +6 -0
- package/src/providers/claude-managed-models.ts +34 -10
- package/src/providers/codex-adapter.ts +6 -0
- package/src/providers/opencode-adapter.ts +6 -0
- package/src/providers/pi-mono-adapter.ts +8 -0
- package/src/providers/pricing-sources.md +24 -0
- package/src/queue-stall-alarm.ts +216 -0
- package/src/scheduler/scheduler.ts +7 -0
- package/src/script-workflows/executor.ts +2 -1
- package/src/scripts-runtime/executors/native.ts +2 -1
- package/src/scripts-runtime/executors/types.ts +5 -0
- package/src/scripts-runtime/loader.ts +5 -0
- package/src/scripts-runtime/swarm-config.ts +8 -0
- package/src/scripts-runtime/swarm-sdk.ts +7 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/tests/budget-claim-gate.test.ts +20 -0
- package/src/tests/claude-adapter.test.ts +32 -0
- package/src/tests/claude-managed-adapter.test.ts +38 -7
- package/src/tests/codex-adapter.test.ts +30 -0
- package/src/tests/create-task-validation.test.ts +128 -0
- package/src/tests/credential-wait.test.ts +67 -1
- package/src/tests/db-query.test.ts +711 -2
- package/src/tests/http-api-integration.test.ts +81 -0
- package/src/tests/http-users.test.ts +166 -1
- package/src/tests/identity-field-budget.test.ts +176 -0
- package/src/tests/mcp-tools-user.test.ts +34 -0
- package/src/tests/mcp-user-route.test.ts +17 -0
- package/src/tests/metrics-http.test.ts +44 -0
- package/src/tests/multi-runtime-registration.test.ts +2703 -0
- package/src/tests/openapi-response-contract.test.ts +24 -0
- package/src/tests/openapi-route-headers.test.ts +83 -0
- package/src/tests/opencode-adapter.test.ts +40 -0
- package/src/tests/outbound-listener-rejection.test.ts +138 -0
- package/src/tests/pi-mono-adapter.test.ts +98 -0
- package/src/tests/profile-sync-warning.test.ts +277 -0
- package/src/tests/profile-sync.test.ts +232 -6
- package/src/tests/prompt-template-session.test.ts +32 -3
- package/src/tests/queue-stall-alarm.test.ts +226 -0
- package/src/tests/requester-comms.test.ts +32 -0
- package/src/tests/runner-requester-profile.test.ts +38 -0
- package/src/tests/sandboxed-process.test.ts +45 -0
- package/src/tests/schedule-target-type.test.ts +38 -0
- package/src/tests/script-connections.test.ts +16 -3
- package/src/tests/scripts-external-api.test.ts +8 -3
- package/src/tests/scripts-http.test.ts +12 -0
- package/src/tests/scripts-retention.test.ts +384 -0
- package/src/tests/scripts-runtime-identity.test.ts +375 -0
- package/src/tests/scripts-runtime.test.ts +4 -3
- package/src/tests/sdk-allowlist.test.ts +47 -0
- package/src/tests/send-task-requested-by.test.ts +9 -0
- package/src/tests/session-costs.test.ts +506 -1
- package/src/tests/shutdown-error-scrubbing.test.ts +92 -0
- package/src/tests/steering-core.test.ts +28 -0
- package/src/tests/task-artifacts.test.ts +386 -0
- package/src/tests/task-attachments-schema.test.ts +17 -1
- package/src/tests/task-completion-idempotency.test.ts +57 -0
- package/src/tests/task-pull-request-backfill-migration.test.ts +321 -0
- package/src/tests/update-profile-api.test.ts +67 -39
- package/src/tests/update-profile-auth.test.ts +48 -4
- package/src/tests/user-attribution-migration.test.ts +54 -0
- package/src/tests/user-identity.test.ts +72 -0
- package/src/tests/workflow-async-v2.test.ts +39 -1
- package/src/tests/workflow-http-v2.test.ts +3 -2
- package/src/tests/workflow-mcp-trigger-schema.test.ts +52 -3
- package/src/tests/workflow-retry-v2.test.ts +45 -1
- package/src/tests/workflow-swarm-script.test.ts +14 -5
- package/src/tools/db-query.ts +18 -8
- package/src/tools/get-task-details.ts +24 -3
- package/src/tools/manage-user.ts +36 -3
- package/src/tools/poll-task.ts +93 -14
- package/src/tools/script-common.ts +5 -0
- package/src/tools/send-task.ts +1 -4
- package/src/tools/store-progress.ts +13 -2
- package/src/tools/swarm-config/delete-config.ts +9 -0
- package/src/tools/swarm-config/set-config.ts +3 -2
- package/src/tools/task-action.ts +30 -0
- package/src/tools/task-tool-ctx.ts +8 -1
- package/src/tools/update-profile.ts +16 -21
- package/src/tools/utils.ts +5 -0
- package/src/tools/workflows/trigger-workflow.ts +7 -1
- package/src/types.ts +165 -1
- package/src/utils/github-pull-request.ts +76 -0
- package/src/utils/identity-field-budget.ts +73 -0
- package/src/utils/multi-runtime.ts +20 -0
- package/src/utils/requester-comms.ts +24 -0
- package/src/utils/sandboxed-process.ts +40 -14
- package/src/workflows/engine.ts +22 -2
- package/src/workflows/executors/swarm-script.ts +24 -1
- package/src/workflows/resume.ts +19 -11
- package/src/workflows/retry-poller.ts +1 -0
- package/src/workflows/triggers.ts +4 -0
- package/templates/schedules/daily-compounding-reflection/content.md +12 -3
- package/templates/skills/db-query-guidance/config.json +14 -0
- package/templates/skills/db-query-guidance/content.md +57 -0
- package/dist/cli-3te4jdkm.js +0 -225
- package/dist/cli-bmze986d.js +0 -7
- package/dist/cli-kh3ba2zf.js +0 -607
- package/dist/index-hp1kdbjj.js +0 -36
- package/dist/mistral-conversations-81fwav0j.js +0 -30578
- package/dist/otel-nqa12wf3.js +0 -3149
- package/dist/{pi-messages-tqj8q6b9.js → pi-messages-sssy32x4.js} +3 -3
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
streamSimple,
|
|
30
30
|
summarizeSession,
|
|
31
31
|
validateToolArguments
|
|
32
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-5z2yhzvd.js";
|
|
33
33
|
import {
|
|
34
34
|
checkToolLoop,
|
|
35
35
|
clearToolHistory
|
|
@@ -42,11 +42,14 @@ import {
|
|
|
42
42
|
buildRatingsFromLlm,
|
|
43
43
|
fetchRetrievalsForTask,
|
|
44
44
|
postRatings
|
|
45
|
-
} from "./cli-
|
|
45
|
+
} from "./cli-f8dre4bz.js";
|
|
46
46
|
import"./cli-e7d20cty.js";
|
|
47
47
|
import {
|
|
48
48
|
applyReasoningEffort
|
|
49
49
|
} from "./cli-8whqavk2.js";
|
|
50
|
+
import {
|
|
51
|
+
swarmRuntimeInstanceId
|
|
52
|
+
} from "./cli-pzq5rjym.js";
|
|
50
53
|
import {
|
|
51
54
|
DEFAULT_OPENROUTER_BASE_URL,
|
|
52
55
|
getOpenRouterBaseUrl
|
|
@@ -54,12 +57,13 @@ import {
|
|
|
54
57
|
import {
|
|
55
58
|
McpHttpClient
|
|
56
59
|
} from "./cli-epan13p1.js";
|
|
57
|
-
import"./cli-
|
|
60
|
+
import"./cli-qys3rhhz.js";
|
|
61
|
+
import"./cli-w1mp9jy7.js";
|
|
58
62
|
import {
|
|
59
63
|
init_secret_scrubber,
|
|
60
64
|
scrubSecrets
|
|
61
65
|
} from "./cli-4j2mrzag.js";
|
|
62
|
-
import"./cli-
|
|
66
|
+
import"./cli-jqwnqx9m.js";
|
|
63
67
|
import {
|
|
64
68
|
require_signal_exit
|
|
65
69
|
} from "./cli-ap1czx8f.js";
|
|
@@ -47994,11 +47998,11 @@ One of the following config files must be in the directory tree: "${p.ROOT_CONFI
|
|
|
47994
47998
|
const r3 = _path().resolve(t3, e3).split(_path().sep);
|
|
47995
47999
|
return new RegExp(["^", ...r3.map((e4, t4) => {
|
|
47996
48000
|
const c = t4 === r3.length - 1;
|
|
47997
|
-
return e4 === "**" ? c ? p : l3 : e4 === "*" ? c ? a : o : e4.startsWith("*.") ? i +
|
|
48001
|
+
return e4 === "**" ? c ? p : l3 : e4 === "*" ? c ? a : o : e4.startsWith("*.") ? i + escapeRegExp2(e4.slice(1)) + (c ? s : n) : escapeRegExp2(e4) + (c ? s : n);
|
|
47998
48002
|
})].join(""));
|
|
47999
48003
|
};
|
|
48000
48004
|
const n = `\\${_path().sep}`, s = `(?:${n}|$)`, i = `[^${n}]+`, o = `(?:${i}${n})`, a = `(?:${i}${s})`, l3 = `${o}*?`, p = `${o}*?${a}?`;
|
|
48001
|
-
function
|
|
48005
|
+
function escapeRegExp2(e3) {
|
|
48002
48006
|
return e3.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
48003
48007
|
}
|
|
48004
48008
|
}, "./node_modules/.pnpm/@babel+core@7.29.0/node_modules/@babel/core/lib/config/plugin.js"(e2, t2, r2) {
|
|
@@ -93190,11 +93194,11 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
|
93190
93194
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
93191
93195
|
var { InvalidArgumentError, UndiciError } = require_errors2();
|
|
93192
93196
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
93193
|
-
function normalizeUrlForMatching(url, matchQuery,
|
|
93197
|
+
function normalizeUrlForMatching(url, matchQuery, normalizeQuery2) {
|
|
93194
93198
|
if (matchQuery === false)
|
|
93195
93199
|
return `${url.origin}${url.pathname}`;
|
|
93196
|
-
if (
|
|
93197
|
-
const normalized = String(
|
|
93200
|
+
if (normalizeQuery2) {
|
|
93201
|
+
const normalized = String(normalizeQuery2(url.searchParams) ?? "");
|
|
93198
93202
|
return normalized ? `${url.origin}${url.pathname}?${normalized}` : `${url.origin}${url.pathname}`;
|
|
93199
93203
|
}
|
|
93200
93204
|
return url.toString();
|
|
@@ -104574,6 +104578,14 @@ function parseArgs(args) {
|
|
|
104574
104578
|
} else if (arg === "--theme" && i + 1 < args.length) {
|
|
104575
104579
|
result.themes = result.themes ?? [];
|
|
104576
104580
|
result.themes.push(args[++i]);
|
|
104581
|
+
} else if (arg === "--use-theme") {
|
|
104582
|
+
const themeName = args[i + 1];
|
|
104583
|
+
if (themeName === undefined || themeName.startsWith("-")) {
|
|
104584
|
+
result.diagnostics.push({ type: "error", message: "--use-theme requires a theme name" });
|
|
104585
|
+
} else {
|
|
104586
|
+
result.useTheme = themeName;
|
|
104587
|
+
i++;
|
|
104588
|
+
}
|
|
104577
104589
|
} else if (arg === "--no-skills" || arg === "-ns") {
|
|
104578
104590
|
result.noSkills = true;
|
|
104579
104591
|
} else if (arg === "--no-prompt-templates" || arg === "-np") {
|
|
@@ -104691,6 +104703,7 @@ ${source_default.bold("Options:")}
|
|
|
104691
104703
|
--prompt-template <path> Load a prompt template file or directory (can be used multiple times)
|
|
104692
104704
|
--no-prompt-templates, -np Disable prompt template discovery and loading
|
|
104693
104705
|
--theme <path> Load a theme file or directory (can be used multiple times)
|
|
104706
|
+
--use-theme <name[/name]> Set the initial interactive theme for this run
|
|
104694
104707
|
--no-themes Disable theme discovery and loading
|
|
104695
104708
|
--no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading
|
|
104696
104709
|
--export <file> Export session file to HTML and exit
|
|
@@ -109061,6 +109074,14 @@ var TUI_KEYBINDINGS = {
|
|
|
109061
109074
|
defaultKeys: [],
|
|
109062
109075
|
description: "Scroll viewport down half a page"
|
|
109063
109076
|
},
|
|
109077
|
+
"tui.altScreen.lineUp": {
|
|
109078
|
+
defaultKeys: [],
|
|
109079
|
+
description: "Scroll viewport up one line"
|
|
109080
|
+
},
|
|
109081
|
+
"tui.altScreen.lineDown": {
|
|
109082
|
+
defaultKeys: [],
|
|
109083
|
+
description: "Scroll viewport down one line"
|
|
109084
|
+
},
|
|
109064
109085
|
"tui.altScreen.previousPrompt": {
|
|
109065
109086
|
defaultKeys: "ctrl+shift+up",
|
|
109066
109087
|
description: "Jump to previous semantic prompt"
|
|
@@ -109069,6 +109090,22 @@ var TUI_KEYBINDINGS = {
|
|
|
109069
109090
|
defaultKeys: "ctrl+shift+down",
|
|
109070
109091
|
description: "Jump to next semantic prompt"
|
|
109071
109092
|
},
|
|
109093
|
+
"tui.altScreen.search": {
|
|
109094
|
+
defaultKeys: "ctrl+shift+f",
|
|
109095
|
+
description: "Search the primary scroll view"
|
|
109096
|
+
},
|
|
109097
|
+
"tui.altScreen.searchNext": {
|
|
109098
|
+
defaultKeys: ["enter", "ctrl+g"],
|
|
109099
|
+
description: "Select the next search match"
|
|
109100
|
+
},
|
|
109101
|
+
"tui.altScreen.searchPrevious": {
|
|
109102
|
+
defaultKeys: ["shift+enter", "ctrl+shift+g"],
|
|
109103
|
+
description: "Select the previous search match"
|
|
109104
|
+
},
|
|
109105
|
+
"tui.altScreen.searchClose": {
|
|
109106
|
+
defaultKeys: "escape",
|
|
109107
|
+
description: "Close transcript search"
|
|
109108
|
+
},
|
|
109072
109109
|
"tui.altScreen.top": { defaultKeys: "home", description: "Scroll viewport to top" },
|
|
109073
109110
|
"tui.altScreen.bottom": { defaultKeys: "end", description: "Scroll viewport to bottom" }
|
|
109074
109111
|
};
|
|
@@ -110207,6 +110244,9 @@ class TuiBase extends Container {
|
|
|
110207
110244
|
hasOverlay() {
|
|
110208
110245
|
return this.overlayStack.some((o) => this.isOverlayVisible(o));
|
|
110209
110246
|
}
|
|
110247
|
+
isOverlayFocused() {
|
|
110248
|
+
return this.overlayStack.some((entry) => entry.component === this.focusedComponent && this.isOverlayVisible(entry));
|
|
110249
|
+
}
|
|
110210
110250
|
isOverlayVisible(entry) {
|
|
110211
110251
|
if (entry.hidden)
|
|
110212
110252
|
return false;
|
|
@@ -113806,6 +113846,15 @@ class LatexParser {
|
|
|
113806
113846
|
}
|
|
113807
113847
|
let command = "";
|
|
113808
113848
|
const first = this.source[this.position] ?? "";
|
|
113849
|
+
if (first === `
|
|
113850
|
+
` || first === "\r") {
|
|
113851
|
+
this.position++;
|
|
113852
|
+
if (first === "\r" && this.source[this.position] === `
|
|
113853
|
+
`) {
|
|
113854
|
+
this.position++;
|
|
113855
|
+
}
|
|
113856
|
+
return " ";
|
|
113857
|
+
}
|
|
113809
113858
|
if (/[A-Za-z]/.test(first)) {
|
|
113810
113859
|
const start = this.position;
|
|
113811
113860
|
while (this.position < this.source.length && /[A-Za-z]/.test(this.source[this.position] ?? "")) {
|
|
@@ -114009,7 +114058,7 @@ class LatexParser {
|
|
|
114009
114058
|
return value2;
|
|
114010
114059
|
}
|
|
114011
114060
|
parseRequiredArgumentValue() {
|
|
114012
|
-
while (this.position < this.source.length &&
|
|
114061
|
+
while (this.position < this.source.length && /\s/.test(this.source[this.position] ?? "")) {
|
|
114013
114062
|
this.position++;
|
|
114014
114063
|
}
|
|
114015
114064
|
if (this.position >= this.source.length) {
|
|
@@ -114899,6 +114948,7 @@ class ScrollView extends Container {
|
|
|
114899
114948
|
contentHeight = 0;
|
|
114900
114949
|
currentViewportHeight = 0;
|
|
114901
114950
|
followingEnd;
|
|
114951
|
+
followSuppressedAtEnd = false;
|
|
114902
114952
|
requestRenderCallback;
|
|
114903
114953
|
transientScrollbarVisible = false;
|
|
114904
114954
|
scrollbarActive = false;
|
|
@@ -114978,15 +115028,21 @@ class ScrollView extends Container {
|
|
|
114978
115028
|
this.scrollbarActive = active;
|
|
114979
115029
|
this.markScrollbarActivity();
|
|
114980
115030
|
}
|
|
114981
|
-
scrollTo(scrollTop) {
|
|
115031
|
+
scrollTo(scrollTop, options = {}) {
|
|
114982
115032
|
const requested = Number.isFinite(scrollTop) ? Math.trunc(scrollTop) : this.currentScrollTop;
|
|
114983
115033
|
const maxScrollTop = Math.max(0, this.contentHeight - this.currentViewportHeight);
|
|
114984
115034
|
const next = Math.max(0, Math.min(maxScrollTop, requested));
|
|
114985
|
-
|
|
115035
|
+
const nextFollowSuppressedAtEnd = options.disableFollow === true && next === maxScrollTop;
|
|
115036
|
+
const nextFollowingEnd = !nextFollowSuppressedAtEnd && this.followEnd && next === maxScrollTop;
|
|
115037
|
+
if (next === this.currentScrollTop && nextFollowingEnd === this.followingEnd && nextFollowSuppressedAtEnd === this.followSuppressedAtEnd) {
|
|
114986
115038
|
return;
|
|
115039
|
+
}
|
|
115040
|
+
const moved = next !== this.currentScrollTop;
|
|
114987
115041
|
this.currentScrollTop = next;
|
|
114988
|
-
this.followingEnd =
|
|
114989
|
-
this.
|
|
115042
|
+
this.followingEnd = nextFollowingEnd;
|
|
115043
|
+
this.followSuppressedAtEnd = nextFollowSuppressedAtEnd;
|
|
115044
|
+
if (moved)
|
|
115045
|
+
this.markScrollbarActivity();
|
|
114990
115046
|
this.requestRenderCallback?.();
|
|
114991
115047
|
}
|
|
114992
115048
|
scrollBy(lines) {
|
|
@@ -114997,18 +115053,21 @@ class ScrollView extends Container {
|
|
|
114997
115053
|
const start = this.followingEnd ? maxScrollTop : this.currentScrollTop;
|
|
114998
115054
|
const next = Math.max(0, Math.min(maxScrollTop, start + requested));
|
|
114999
115055
|
const moved = next - start;
|
|
115056
|
+
const wasFollowingEnd = this.followingEnd;
|
|
115000
115057
|
this.currentScrollTop = next;
|
|
115001
115058
|
this.followingEnd = this.followEnd && next === maxScrollTop;
|
|
115002
|
-
|
|
115059
|
+
this.followSuppressedAtEnd = false;
|
|
115060
|
+
if (moved !== 0)
|
|
115003
115061
|
this.markScrollbarActivity();
|
|
115062
|
+
if (moved !== 0 || this.followingEnd !== wasFollowingEnd)
|
|
115004
115063
|
this.requestRenderCallback?.();
|
|
115005
|
-
}
|
|
115006
115064
|
return requested - moved;
|
|
115007
115065
|
}
|
|
115008
115066
|
scrollToStart() {
|
|
115009
115067
|
const changed = this.currentScrollTop !== 0 || this.followingEnd !== (this.followEnd && this.contentHeight <= this.currentViewportHeight);
|
|
115010
115068
|
this.currentScrollTop = 0;
|
|
115011
115069
|
this.followingEnd = this.followEnd && this.contentHeight <= this.currentViewportHeight;
|
|
115070
|
+
this.followSuppressedAtEnd = false;
|
|
115012
115071
|
if (changed) {
|
|
115013
115072
|
this.markScrollbarActivity();
|
|
115014
115073
|
this.requestRenderCallback?.();
|
|
@@ -115019,6 +115078,7 @@ class ScrollView extends Container {
|
|
|
115019
115078
|
const changed = this.currentScrollTop !== next || this.followingEnd !== this.followEnd;
|
|
115020
115079
|
this.currentScrollTop = next;
|
|
115021
115080
|
this.followingEnd = this.followEnd;
|
|
115081
|
+
this.followSuppressedAtEnd = false;
|
|
115022
115082
|
if (changed) {
|
|
115023
115083
|
this.markScrollbarActivity();
|
|
115024
115084
|
this.requestRenderCallback?.();
|
|
@@ -115033,8 +115093,11 @@ class ScrollView extends Container {
|
|
|
115033
115093
|
this.currentScrollTop = maxScrollTop;
|
|
115034
115094
|
else
|
|
115035
115095
|
this.currentScrollTop = Math.max(0, Math.min(this.currentScrollTop, maxScrollTop));
|
|
115036
|
-
if (this.
|
|
115096
|
+
if (this.currentScrollTop < maxScrollTop)
|
|
115097
|
+
this.followSuppressedAtEnd = false;
|
|
115098
|
+
if (this.followEnd && this.currentScrollTop === maxScrollTop && !this.followSuppressedAtEnd) {
|
|
115037
115099
|
this.followingEnd = true;
|
|
115100
|
+
}
|
|
115038
115101
|
if (this.contentHeight <= this.currentViewportHeight)
|
|
115039
115102
|
this.hideTransientScrollbar();
|
|
115040
115103
|
}
|
|
@@ -115293,6 +115356,8 @@ class VStack extends Stack {
|
|
|
115293
115356
|
// node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js
|
|
115294
115357
|
import { EventEmitter } from "events";
|
|
115295
115358
|
var ESC = "\x1B";
|
|
115359
|
+
var DEFAULT_SEQUENCE_TIMEOUT_MS = 50;
|
|
115360
|
+
var DEFAULT_ESCAPE_TIMEOUT_MS = 10;
|
|
115296
115361
|
var BRACKETED_PASTE_START = "\x1B[200~";
|
|
115297
115362
|
var BRACKETED_PASTE_END = "\x1B[201~";
|
|
115298
115363
|
function isCompleteSequence(data) {
|
|
@@ -115433,12 +115498,14 @@ class StdinBuffer extends EventEmitter {
|
|
|
115433
115498
|
buffer = "";
|
|
115434
115499
|
timeout = null;
|
|
115435
115500
|
timeoutMs;
|
|
115501
|
+
escapeTimeoutMs;
|
|
115436
115502
|
pasteMode = false;
|
|
115437
115503
|
pasteBuffer = "";
|
|
115438
115504
|
pendingKittyPrintableCodepoint;
|
|
115439
115505
|
constructor(options = {}) {
|
|
115440
115506
|
super();
|
|
115441
|
-
this.timeoutMs = options.timeout ??
|
|
115507
|
+
this.timeoutMs = options.timeout ?? DEFAULT_SEQUENCE_TIMEOUT_MS;
|
|
115508
|
+
this.escapeTimeoutMs = options.escapeTimeout ?? DEFAULT_ESCAPE_TIMEOUT_MS;
|
|
115442
115509
|
}
|
|
115443
115510
|
process(data) {
|
|
115444
115511
|
if (this.timeout) {
|
|
@@ -115512,12 +115579,13 @@ class StdinBuffer extends EventEmitter {
|
|
|
115512
115579
|
this.emitDataSequence(sequence);
|
|
115513
115580
|
}
|
|
115514
115581
|
if (this.buffer.length > 0) {
|
|
115582
|
+
const timeoutMs = this.buffer === ESC ? this.escapeTimeoutMs : this.timeoutMs;
|
|
115515
115583
|
this.timeout = setTimeout(() => {
|
|
115516
115584
|
const flushed = this.flush();
|
|
115517
115585
|
for (const sequence of flushed) {
|
|
115518
115586
|
this.emitDataSequence(sequence);
|
|
115519
115587
|
}
|
|
115520
|
-
},
|
|
115588
|
+
}, timeoutMs);
|
|
115521
115589
|
}
|
|
115522
115590
|
}
|
|
115523
115591
|
emitDataSequence(sequence) {
|
|
@@ -115650,6 +115718,19 @@ function normalizeNativeShiftEnterInput(data, shouldDetectNativeShiftEnter, isSh
|
|
|
115650
115718
|
return NATIVE_SHIFT_ENTER_SEQUENCE;
|
|
115651
115719
|
return data;
|
|
115652
115720
|
}
|
|
115721
|
+
var DEFAULT_ESCAPE_TIMEOUT_MS2 = 10;
|
|
115722
|
+
var DEFAULT_SSH_ESCAPE_TIMEOUT_MS = 100;
|
|
115723
|
+
function resolveEscapeTimeoutMs(env = process.env) {
|
|
115724
|
+
const configured = Number(env.PI_TUI_ESC_TIMEOUT);
|
|
115725
|
+
if (Number.isFinite(configured) && configured > 0) {
|
|
115726
|
+
return configured;
|
|
115727
|
+
}
|
|
115728
|
+
if (env.SSH_CONNECTION || env.SSH_TTY) {
|
|
115729
|
+
return DEFAULT_SSH_ESCAPE_TIMEOUT_MS;
|
|
115730
|
+
}
|
|
115731
|
+
return DEFAULT_ESCAPE_TIMEOUT_MS2;
|
|
115732
|
+
}
|
|
115733
|
+
|
|
115653
115734
|
class ProcessTerminal {
|
|
115654
115735
|
wasRaw = false;
|
|
115655
115736
|
inputHandler;
|
|
@@ -115699,7 +115780,7 @@ class ProcessTerminal {
|
|
|
115699
115780
|
this.queryAndEnableKittyProtocol();
|
|
115700
115781
|
}
|
|
115701
115782
|
setupStdinBuffer() {
|
|
115702
|
-
this.stdinBuffer = new StdinBuffer({
|
|
115783
|
+
this.stdinBuffer = new StdinBuffer({ escapeTimeout: resolveEscapeTimeoutMs() });
|
|
115703
115784
|
this.stdinBuffer.on("data", (sequence) => {
|
|
115704
115785
|
const negotiationSequence = this.readKeyboardProtocolNegotiationSequence(sequence);
|
|
115705
115786
|
if (negotiationSequence === "pending") {
|
|
@@ -115967,6 +116048,123 @@ class ProcessTerminal {
|
|
|
115967
116048
|
return true;
|
|
115968
116049
|
}
|
|
115969
116050
|
}
|
|
116051
|
+
// node_modules/@earendil-works/pi-tui/dist/alt-screen-search.js
|
|
116052
|
+
var segmenter2 = getGraphemeSegmenter();
|
|
116053
|
+
function appendMappedText(text, span, corpus) {
|
|
116054
|
+
corpus.text += text;
|
|
116055
|
+
for (let index = 0;index < text.length; index++)
|
|
116056
|
+
corpus.source.push(span);
|
|
116057
|
+
}
|
|
116058
|
+
function buildSearchCorpus(lines) {
|
|
116059
|
+
const corpus = { text: "", source: [] };
|
|
116060
|
+
let pendingSeparator = false;
|
|
116061
|
+
for (let row = 0;row < lines.length; row++) {
|
|
116062
|
+
const line = stripTerminalSequences(lines[row] ?? "");
|
|
116063
|
+
let column = 0;
|
|
116064
|
+
for (const grapheme of segmenter2.segment(line)) {
|
|
116065
|
+
const text = grapheme.segment;
|
|
116066
|
+
const width = visibleWidth(text);
|
|
116067
|
+
if (/^\s+$/u.test(text)) {
|
|
116068
|
+
if (corpus.text.length > 0)
|
|
116069
|
+
pendingSeparator = true;
|
|
116070
|
+
column += width;
|
|
116071
|
+
continue;
|
|
116072
|
+
}
|
|
116073
|
+
if (pendingSeparator) {
|
|
116074
|
+
appendMappedText(" ", undefined, corpus);
|
|
116075
|
+
pendingSeparator = false;
|
|
116076
|
+
}
|
|
116077
|
+
appendMappedText(text, { row, startCol: column, endCol: column + width }, corpus);
|
|
116078
|
+
column += width;
|
|
116079
|
+
}
|
|
116080
|
+
if (corpus.text.length > 0)
|
|
116081
|
+
pendingSeparator = true;
|
|
116082
|
+
}
|
|
116083
|
+
return corpus;
|
|
116084
|
+
}
|
|
116085
|
+
function normalizeQuery(query) {
|
|
116086
|
+
return query.replace(/\s+/gu, " ").trim();
|
|
116087
|
+
}
|
|
116088
|
+
function escapeRegExp(text) {
|
|
116089
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
116090
|
+
}
|
|
116091
|
+
function findAltScreenSearchMatches(lines, query) {
|
|
116092
|
+
const normalizedQuery = normalizeQuery(query);
|
|
116093
|
+
if (!normalizedQuery)
|
|
116094
|
+
return [];
|
|
116095
|
+
const corpus = buildSearchCorpus(lines);
|
|
116096
|
+
const expression = new RegExp(escapeRegExp(normalizedQuery), "giu");
|
|
116097
|
+
const matches = [];
|
|
116098
|
+
for (const match of corpus.text.matchAll(expression)) {
|
|
116099
|
+
const start = match.index;
|
|
116100
|
+
const end = start + match[0].length;
|
|
116101
|
+
const segments = [];
|
|
116102
|
+
for (let index = start;index < end; index++) {
|
|
116103
|
+
const span = corpus.source[index];
|
|
116104
|
+
if (!span)
|
|
116105
|
+
continue;
|
|
116106
|
+
const previous = segments[segments.length - 1];
|
|
116107
|
+
if (previous && previous.row === span.row && span.startCol <= previous.endCol) {
|
|
116108
|
+
previous.endCol = Math.max(previous.endCol, span.endCol);
|
|
116109
|
+
} else {
|
|
116110
|
+
segments.push({ ...span });
|
|
116111
|
+
}
|
|
116112
|
+
}
|
|
116113
|
+
if (segments.length > 0)
|
|
116114
|
+
matches.push({ segments });
|
|
116115
|
+
}
|
|
116116
|
+
return matches;
|
|
116117
|
+
}
|
|
116118
|
+
function getAltScreenSearchMatchKey(match) {
|
|
116119
|
+
const first = match.segments[0];
|
|
116120
|
+
const last = match.segments[match.segments.length - 1];
|
|
116121
|
+
return first && last ? `${first.row}:${first.startCol}:${last.row}:${last.endCol}` : "";
|
|
116122
|
+
}
|
|
116123
|
+
|
|
116124
|
+
class AltScreenSearchComponent {
|
|
116125
|
+
input = new Input;
|
|
116126
|
+
onQueryChange;
|
|
116127
|
+
resultCount = 0;
|
|
116128
|
+
resultIndex = -1;
|
|
116129
|
+
_focused = false;
|
|
116130
|
+
constructor(onQueryChange) {
|
|
116131
|
+
this.onQueryChange = onQueryChange;
|
|
116132
|
+
}
|
|
116133
|
+
get focused() {
|
|
116134
|
+
return this._focused;
|
|
116135
|
+
}
|
|
116136
|
+
set focused(value2) {
|
|
116137
|
+
this._focused = value2;
|
|
116138
|
+
this.input.focused = value2;
|
|
116139
|
+
}
|
|
116140
|
+
setResult(index, count) {
|
|
116141
|
+
this.resultIndex = index;
|
|
116142
|
+
this.resultCount = count;
|
|
116143
|
+
}
|
|
116144
|
+
handleInput(data) {
|
|
116145
|
+
const previous = this.input.getValue();
|
|
116146
|
+
this.input.handleInput(data);
|
|
116147
|
+
const query = this.input.getValue();
|
|
116148
|
+
if (query !== previous)
|
|
116149
|
+
this.onQueryChange(query);
|
|
116150
|
+
}
|
|
116151
|
+
invalidate() {
|
|
116152
|
+
this.input.invalidate();
|
|
116153
|
+
}
|
|
116154
|
+
render(width) {
|
|
116155
|
+
const safeWidth = Math.max(1, width);
|
|
116156
|
+
const label = " Find transcript";
|
|
116157
|
+
const query = this.input.getValue();
|
|
116158
|
+
const status = !query ? "" : this.resultCount === 0 ? "No matches " : `${this.resultIndex + 1}/${this.resultCount} `;
|
|
116159
|
+
const labelWidth = visibleWidth(label);
|
|
116160
|
+
const statusWidth = visibleWidth(status);
|
|
116161
|
+
const gap = " ".repeat(Math.max(1, safeWidth - labelWidth - statusWidth));
|
|
116162
|
+
const title = truncateToWidth(`${label}${gap}${status}`, safeWidth, "");
|
|
116163
|
+
const padding = " ".repeat(Math.max(0, safeWidth - visibleWidth(title)));
|
|
116164
|
+
return [`\x1B[7m${title}${padding}\x1B[27m`, ...this.input.render(safeWidth)];
|
|
116165
|
+
}
|
|
116166
|
+
}
|
|
116167
|
+
|
|
115970
116168
|
// node_modules/@earendil-works/pi-tui/dist/components/alt-screen-flash.js
|
|
115971
116169
|
var DEFAULT_DURATION_MS = 1000;
|
|
115972
116170
|
|
|
@@ -116227,10 +116425,11 @@ function paintBox(box, screen, totalWidth) {
|
|
|
116227
116425
|
if (visibleRows < imageMetadata.rows)
|
|
116228
116426
|
line = cropKittyImageLine(line, 0, visibleRows);
|
|
116229
116427
|
}
|
|
116230
|
-
if (
|
|
116428
|
+
if (box.rect.x === 0 && box.rect.width >= totalWidth && (isImageLine(line) || !screen[row])) {
|
|
116231
116429
|
screen[row] = line;
|
|
116232
|
-
else
|
|
116430
|
+
} else {
|
|
116233
116431
|
screen[row] = compositeTuiLine(screen[row] ?? "", line, box.rect.x, box.rect.width, totalWidth);
|
|
116432
|
+
}
|
|
116234
116433
|
}
|
|
116235
116434
|
}
|
|
116236
116435
|
for (const child of box.children)
|
|
@@ -116359,12 +116558,16 @@ class TuiAltScreen extends TuiBase {
|
|
|
116359
116558
|
selectionPressActive = false;
|
|
116360
116559
|
scrollbarDrag;
|
|
116361
116560
|
scrollbarHover;
|
|
116561
|
+
activeSearch;
|
|
116362
116562
|
pressedUrl;
|
|
116363
116563
|
selectionDragged = false;
|
|
116364
116564
|
wheelScrollLines;
|
|
116365
116565
|
mouseEnabled;
|
|
116566
|
+
searchMatchStyle;
|
|
116567
|
+
searchCurrentMatchStyle;
|
|
116366
116568
|
openUrl;
|
|
116367
116569
|
onRightClickPaste;
|
|
116570
|
+
copySelection;
|
|
116368
116571
|
constructor(terminal, showHardwareCursor, logDirectory, options = {}) {
|
|
116369
116572
|
super(terminal, showHardwareCursor, logDirectory);
|
|
116370
116573
|
this.implicitDocument = {
|
|
@@ -116378,8 +116581,11 @@ class TuiAltScreen extends TuiBase {
|
|
|
116378
116581
|
this.flashes = new AltScreenFlashContainer(() => this.requestRender());
|
|
116379
116582
|
this.wheelScrollLines = Math.max(1, Math.floor(options.wheelScrollLines ?? 1));
|
|
116380
116583
|
this.mouseEnabled = options.mouse ?? true;
|
|
116584
|
+
this.searchMatchStyle = options.searchMatchStyle ?? ((text) => `\x1B[4m${text}\x1B[24m`);
|
|
116585
|
+
this.searchCurrentMatchStyle = options.searchCurrentMatchStyle ?? ((text) => `\x1B[1;7m${text}\x1B[22;27m`);
|
|
116381
116586
|
this.openUrl = options.openUrl;
|
|
116382
116587
|
this.onRightClickPaste = options.onRightClickPaste;
|
|
116588
|
+
this.copySelection = options.copySelection;
|
|
116383
116589
|
this.addInputListener((data) => this.handleViewportInput(data));
|
|
116384
116590
|
}
|
|
116385
116591
|
get viewportTop() {
|
|
@@ -116433,6 +116639,7 @@ class TuiAltScreen extends TuiBase {
|
|
|
116433
116639
|
this.terminal.write(`${ENTER_ALT_SCREEN}${DISABLE_AUTOWRAP}${this.mouseEnabled ? mouseSequence : ""}\x1B[2J\x1B[H\x1B[?25l`);
|
|
116434
116640
|
}
|
|
116435
116641
|
beforeTerminalStop(_options) {
|
|
116642
|
+
this.closeSearch();
|
|
116436
116643
|
this.stopSelectionAutoScroll();
|
|
116437
116644
|
this.selectionPressActive = false;
|
|
116438
116645
|
this.stopScrollbarHover();
|
|
@@ -116548,12 +116755,119 @@ class TuiAltScreen extends TuiBase {
|
|
|
116548
116755
|
return;
|
|
116549
116756
|
}
|
|
116550
116757
|
}
|
|
116758
|
+
openSearch() {
|
|
116759
|
+
if (this.activeSearch) {
|
|
116760
|
+
this.activeSearch.overlay?.focus();
|
|
116761
|
+
return;
|
|
116762
|
+
}
|
|
116763
|
+
const component = new AltScreenSearchComponent((query) => this.updateSearchQuery(query));
|
|
116764
|
+
const search = {
|
|
116765
|
+
component,
|
|
116766
|
+
query: "",
|
|
116767
|
+
matches: [],
|
|
116768
|
+
selectedIndex: -1,
|
|
116769
|
+
anchorRow: this.getPrimaryScrollView().scrollTop,
|
|
116770
|
+
selectionMode: "query"
|
|
116771
|
+
};
|
|
116772
|
+
this.activeSearch = search;
|
|
116773
|
+
search.overlay = this.showOverlay(component, {
|
|
116774
|
+
anchor: "top-right",
|
|
116775
|
+
width: "40%",
|
|
116776
|
+
minWidth: 24,
|
|
116777
|
+
margin: 1
|
|
116778
|
+
});
|
|
116779
|
+
}
|
|
116780
|
+
closeSearch() {
|
|
116781
|
+
const search = this.activeSearch;
|
|
116782
|
+
if (!search)
|
|
116783
|
+
return;
|
|
116784
|
+
this.activeSearch = undefined;
|
|
116785
|
+
search.overlay?.hide();
|
|
116786
|
+
this.requestRender();
|
|
116787
|
+
}
|
|
116788
|
+
updateSearchQuery(query) {
|
|
116789
|
+
const search = this.activeSearch;
|
|
116790
|
+
if (!search || query === search.query)
|
|
116791
|
+
return;
|
|
116792
|
+
const selected = search.matches[search.selectedIndex];
|
|
116793
|
+
search.anchorRow = selected?.segments[0]?.row ?? this.getPrimaryScrollView().scrollTop;
|
|
116794
|
+
search.query = query;
|
|
116795
|
+
search.selectionMode = "query";
|
|
116796
|
+
search.component.setResult(-1, 0);
|
|
116797
|
+
this.requestRender();
|
|
116798
|
+
}
|
|
116799
|
+
navigateSearch(direction) {
|
|
116800
|
+
const search = this.activeSearch;
|
|
116801
|
+
if (!search?.query)
|
|
116802
|
+
return;
|
|
116803
|
+
search.selectionMode = direction < 0 ? "previous" : "next";
|
|
116804
|
+
this.requestRender();
|
|
116805
|
+
}
|
|
116806
|
+
refreshSearch(layout) {
|
|
116807
|
+
const search = this.activeSearch;
|
|
116808
|
+
if (!search)
|
|
116809
|
+
return false;
|
|
116810
|
+
const scrollView = layout.primaryScrollView ?? this.implicitScrollView;
|
|
116811
|
+
const box = getScrollViewBox(layout, scrollView);
|
|
116812
|
+
const lines = box?.scrollContentLines;
|
|
116813
|
+
if (!lines || !search.query.trim()) {
|
|
116814
|
+
search.matches = [];
|
|
116815
|
+
search.selectedIndex = -1;
|
|
116816
|
+
search.selectedKey = undefined;
|
|
116817
|
+
search.selectionMode = "retain";
|
|
116818
|
+
search.component.setResult(-1, 0);
|
|
116819
|
+
return false;
|
|
116820
|
+
}
|
|
116821
|
+
const shouldRevealSelection = search.selectionMode !== "retain";
|
|
116822
|
+
const matches = findAltScreenSearchMatches(lines, search.query);
|
|
116823
|
+
const exactIndex = search.selectedKey ? matches.findIndex((match) => getAltScreenSearchMatchKey(match) === search.selectedKey) : -1;
|
|
116824
|
+
let selectedIndex = -1;
|
|
116825
|
+
if (matches.length > 0) {
|
|
116826
|
+
if (search.selectionMode === "query") {
|
|
116827
|
+
selectedIndex = matches.findIndex((match) => (match.segments[0]?.row ?? 0) >= search.anchorRow);
|
|
116828
|
+
if (selectedIndex < 0)
|
|
116829
|
+
selectedIndex = 0;
|
|
116830
|
+
} else if (search.selectionMode === "next") {
|
|
116831
|
+
const baseIndex = exactIndex >= 0 ? exactIndex : Math.min(search.selectedIndex, matches.length - 1);
|
|
116832
|
+
selectedIndex = baseIndex < 0 ? 0 : (baseIndex + 1) % matches.length;
|
|
116833
|
+
} else if (search.selectionMode === "previous") {
|
|
116834
|
+
const baseIndex = exactIndex >= 0 ? exactIndex : Math.min(search.selectedIndex, matches.length - 1);
|
|
116835
|
+
selectedIndex = baseIndex < 0 ? matches.length - 1 : (baseIndex - 1 + matches.length) % matches.length;
|
|
116836
|
+
} else {
|
|
116837
|
+
selectedIndex = exactIndex >= 0 ? exactIndex : Math.min(Math.max(0, search.selectedIndex), matches.length - 1);
|
|
116838
|
+
}
|
|
116839
|
+
}
|
|
116840
|
+
search.matches = matches;
|
|
116841
|
+
search.selectedIndex = selectedIndex;
|
|
116842
|
+
search.selectedKey = selectedIndex >= 0 ? getAltScreenSearchMatchKey(matches[selectedIndex]) : undefined;
|
|
116843
|
+
search.selectionMode = "retain";
|
|
116844
|
+
search.component.setResult(selectedIndex, matches.length);
|
|
116845
|
+
if (!shouldRevealSelection)
|
|
116846
|
+
return false;
|
|
116847
|
+
const selected = matches[selectedIndex];
|
|
116848
|
+
const firstSegment = selected?.segments[0];
|
|
116849
|
+
const lastSegment = selected?.segments[selected.segments.length - 1];
|
|
116850
|
+
if (!box || !firstSegment || !lastSegment || scrollView.viewportHeight <= 0)
|
|
116851
|
+
return false;
|
|
116852
|
+
const before = scrollView.scrollTop;
|
|
116853
|
+
const visibleBottom = before + scrollView.viewportHeight - 1;
|
|
116854
|
+
let target = before;
|
|
116855
|
+
if (firstSegment.row < before || lastSegment.row > visibleBottom) {
|
|
116856
|
+
target = firstSegment.row - Math.floor(scrollView.viewportHeight / 3);
|
|
116857
|
+
}
|
|
116858
|
+
scrollView.scrollTo(target, { disableFollow: true });
|
|
116859
|
+
return scrollView.scrollTop !== before;
|
|
116860
|
+
}
|
|
116551
116861
|
flash(message, durationMs) {
|
|
116552
116862
|
this.flashes.flash(message, durationMs);
|
|
116553
116863
|
}
|
|
116864
|
+
shouldDeferViewportInputToOverlay() {
|
|
116865
|
+
return this.isOverlayFocused() && this.activeSearch?.overlay?.isFocused() !== true;
|
|
116866
|
+
}
|
|
116554
116867
|
handleViewportInput(data) {
|
|
116555
116868
|
if (data === FOCUS_OUT) {
|
|
116556
116869
|
const hadActiveSelection = this.selectionPressActive;
|
|
116870
|
+
const hadNonEmptyActiveSelection = hadActiveSelection && this.getSelectionBounds() !== undefined;
|
|
116557
116871
|
this.selectionPressActive = false;
|
|
116558
116872
|
this.stopSelectionAutoScroll();
|
|
116559
116873
|
this.stopScrollbarHover();
|
|
@@ -116565,15 +116879,18 @@ class TuiAltScreen extends TuiBase {
|
|
|
116565
116879
|
this.selectionFocus = undefined;
|
|
116566
116880
|
this.selectionGranularity = "character";
|
|
116567
116881
|
this.selectionInitialRange = undefined;
|
|
116882
|
+
if (hadNonEmptyActiveSelection)
|
|
116883
|
+
this.requestRender();
|
|
116568
116884
|
}
|
|
116569
116885
|
this.lastClick = undefined;
|
|
116570
|
-
this.requestRender();
|
|
116571
116886
|
return { consume: true };
|
|
116572
116887
|
}
|
|
116573
116888
|
if (data === FOCUS_IN)
|
|
116574
116889
|
return { consume: true };
|
|
116575
116890
|
const wheelEvent = this.parseWheelEvent(data);
|
|
116576
116891
|
if (wheelEvent) {
|
|
116892
|
+
if (this.shouldDeferViewportInputToOverlay())
|
|
116893
|
+
return;
|
|
116577
116894
|
this.routeWheel(wheelEvent);
|
|
116578
116895
|
return { consume: true };
|
|
116579
116896
|
}
|
|
@@ -116592,6 +116909,30 @@ class TuiAltScreen extends TuiBase {
|
|
|
116592
116909
|
return { consume: true };
|
|
116593
116910
|
const keybindings = getKeybindings();
|
|
116594
116911
|
const isRelease = isKeyRelease(data);
|
|
116912
|
+
if (keybindings.matches(data, "tui.altScreen.search")) {
|
|
116913
|
+
if (!isRelease)
|
|
116914
|
+
this.openSearch();
|
|
116915
|
+
return { consume: true };
|
|
116916
|
+
}
|
|
116917
|
+
if (this.activeSearch?.overlay?.isFocused()) {
|
|
116918
|
+
if (keybindings.matches(data, "tui.altScreen.searchNext")) {
|
|
116919
|
+
if (!isRelease)
|
|
116920
|
+
this.navigateSearch(1);
|
|
116921
|
+
return { consume: true };
|
|
116922
|
+
}
|
|
116923
|
+
if (keybindings.matches(data, "tui.altScreen.searchPrevious")) {
|
|
116924
|
+
if (!isRelease)
|
|
116925
|
+
this.navigateSearch(-1);
|
|
116926
|
+
return { consume: true };
|
|
116927
|
+
}
|
|
116928
|
+
if (keybindings.matches(data, "tui.altScreen.searchClose")) {
|
|
116929
|
+
if (!isRelease)
|
|
116930
|
+
this.closeSearch();
|
|
116931
|
+
return { consume: true };
|
|
116932
|
+
}
|
|
116933
|
+
}
|
|
116934
|
+
if (this.shouldDeferViewportInputToOverlay())
|
|
116935
|
+
return;
|
|
116595
116936
|
if (keybindings.matches(data, "tui.altScreen.pageUp")) {
|
|
116596
116937
|
if (!isRelease) {
|
|
116597
116938
|
this.scrollBy(-Math.max(1, this.getPrimaryScrollView().viewportHeight - PAGE_SCROLL_OVERLAP));
|
|
@@ -116614,6 +116955,16 @@ class TuiAltScreen extends TuiBase {
|
|
|
116614
116955
|
this.scrollBy(Math.max(1, Math.floor(this.getPrimaryScrollView().viewportHeight / 2)));
|
|
116615
116956
|
return { consume: true };
|
|
116616
116957
|
}
|
|
116958
|
+
if (keybindings.matches(data, "tui.altScreen.lineUp")) {
|
|
116959
|
+
if (!isRelease)
|
|
116960
|
+
this.scrollBy(-1);
|
|
116961
|
+
return { consume: true };
|
|
116962
|
+
}
|
|
116963
|
+
if (keybindings.matches(data, "tui.altScreen.lineDown")) {
|
|
116964
|
+
if (!isRelease)
|
|
116965
|
+
this.scrollBy(1);
|
|
116966
|
+
return { consume: true };
|
|
116967
|
+
}
|
|
116617
116968
|
if (keybindings.matches(data, "tui.altScreen.previousPrompt")) {
|
|
116618
116969
|
if (!isRelease)
|
|
116619
116970
|
this.scrollToPrompt(-1);
|
|
@@ -116907,7 +117258,8 @@ class TuiAltScreen extends TuiBase {
|
|
|
116907
117258
|
this.selectionDragPointer = undefined;
|
|
116908
117259
|
}
|
|
116909
117260
|
handleSelectionMouseEvent(event) {
|
|
116910
|
-
|
|
117261
|
+
const button = event.button & 3;
|
|
117262
|
+
if (button !== 0 && !(event.release && button === 3))
|
|
116911
117263
|
return;
|
|
116912
117264
|
const anchorScrollView = this.selectionAnchor?.scrollView;
|
|
116913
117265
|
const point = this.getSelectionPoint(event, anchorScrollView);
|
|
@@ -116983,7 +117335,7 @@ class TuiAltScreen extends TuiBase {
|
|
|
116983
117335
|
}
|
|
116984
117336
|
return { start: Math.max(minColumn, start), end: Math.min(maxColumn, end) };
|
|
116985
117337
|
}
|
|
116986
|
-
copySelectionToClipboard() {
|
|
117338
|
+
async copySelectionToClipboard() {
|
|
116987
117339
|
const selection = this.getSelectionBounds();
|
|
116988
117340
|
if (!selection)
|
|
116989
117341
|
return;
|
|
@@ -117006,9 +117358,83 @@ class TuiAltScreen extends TuiBase {
|
|
|
117006
117358
|
`);
|
|
117007
117359
|
if (text.length === 0)
|
|
117008
117360
|
return;
|
|
117361
|
+
if (this.copySelection) {
|
|
117362
|
+
const ok = await this.copySelection(text);
|
|
117363
|
+
this.flash(ok ? "Copied!" : "Copy failed");
|
|
117364
|
+
return;
|
|
117365
|
+
}
|
|
117009
117366
|
this.terminal.write(`\x1B]52;c;${Buffer.from(text).toString("base64")}\x07`);
|
|
117010
117367
|
this.flash("Copied!");
|
|
117011
117368
|
}
|
|
117369
|
+
applySearchTextHighlight(text, current) {
|
|
117370
|
+
const style = current ? this.searchCurrentMatchStyle : this.searchMatchStyle;
|
|
117371
|
+
let result = "";
|
|
117372
|
+
let plainStart = 0;
|
|
117373
|
+
let index = 0;
|
|
117374
|
+
while (index < text.length) {
|
|
117375
|
+
const ansi = extractAnsiCode(text, index);
|
|
117376
|
+
if (!ansi) {
|
|
117377
|
+
index += 1;
|
|
117378
|
+
continue;
|
|
117379
|
+
}
|
|
117380
|
+
if (index > plainStart)
|
|
117381
|
+
result += style(text.slice(plainStart, index));
|
|
117382
|
+
result += ansi.code;
|
|
117383
|
+
index += ansi.length;
|
|
117384
|
+
plainStart = index;
|
|
117385
|
+
}
|
|
117386
|
+
if (plainStart < text.length)
|
|
117387
|
+
result += style(text.slice(plainStart));
|
|
117388
|
+
return result;
|
|
117389
|
+
}
|
|
117390
|
+
applySearchHighlights(screen, layout) {
|
|
117391
|
+
const search = this.activeSearch;
|
|
117392
|
+
if (!search || search.selectedIndex < 0 || search.matches.length === 0)
|
|
117393
|
+
return screen;
|
|
117394
|
+
const scrollView = layout.primaryScrollView ?? this.implicitScrollView;
|
|
117395
|
+
const box = getScrollViewBox(layout, scrollView);
|
|
117396
|
+
if (!box)
|
|
117397
|
+
return screen;
|
|
117398
|
+
const rangesByRow = new Map;
|
|
117399
|
+
const scrollbarColumn = getScrollbarGeometry(box)?.column;
|
|
117400
|
+
const minRow = Math.max(0, box.rect.y, box.clip.y);
|
|
117401
|
+
const maxRow = Math.min(screen.length, box.rect.y + box.rect.height, box.clip.y + box.clip.height);
|
|
117402
|
+
const minColumn = Math.max(0, box.rect.x, box.clip.x);
|
|
117403
|
+
const maxColumn = Math.min(this.terminal.columns, box.rect.x + box.rect.width, box.clip.x + box.clip.width, scrollbarColumn ?? Number.POSITIVE_INFINITY);
|
|
117404
|
+
for (let matchIndex = 0;matchIndex < search.matches.length; matchIndex++) {
|
|
117405
|
+
for (const segment of search.matches[matchIndex].segments) {
|
|
117406
|
+
const row = box.rect.y + segment.row - scrollView.scrollTop;
|
|
117407
|
+
if (row < minRow || row >= maxRow)
|
|
117408
|
+
continue;
|
|
117409
|
+
const startCol = Math.max(minColumn, box.rect.x + segment.startCol);
|
|
117410
|
+
const endCol = Math.min(maxColumn, box.rect.x + segment.endCol);
|
|
117411
|
+
if (endCol <= startCol)
|
|
117412
|
+
continue;
|
|
117413
|
+
const ranges = rangesByRow.get(row) ?? [];
|
|
117414
|
+
ranges.push({ startCol, endCol, current: matchIndex === search.selectedIndex });
|
|
117415
|
+
rangesByRow.set(row, ranges);
|
|
117416
|
+
}
|
|
117417
|
+
}
|
|
117418
|
+
const result = [...screen];
|
|
117419
|
+
for (const [row, ranges] of rangesByRow) {
|
|
117420
|
+
let line = result[row] ?? "";
|
|
117421
|
+
if (isImageLine(line))
|
|
117422
|
+
continue;
|
|
117423
|
+
const lineWidth = visibleWidth(line);
|
|
117424
|
+
for (const range of ranges.sort((a, b2) => b2.startCol - a.startCol)) {
|
|
117425
|
+
const startCol = Math.min(range.startCol, lineWidth);
|
|
117426
|
+
const endCol = Math.min(range.endCol, lineWidth);
|
|
117427
|
+
if (endCol <= startCol)
|
|
117428
|
+
continue;
|
|
117429
|
+
const before = sliceByColumn(line, 0, startCol, true);
|
|
117430
|
+
const highlighted = sliceByColumn(line, startCol, endCol - startCol, true);
|
|
117431
|
+
const after = sliceByColumn(line, endCol, Math.max(0, lineWidth - endCol), true);
|
|
117432
|
+
line = `${before}${this.applySearchTextHighlight(highlighted, range.current)}${after}`;
|
|
117433
|
+
}
|
|
117434
|
+
result[row] = line;
|
|
117435
|
+
}
|
|
117436
|
+
return result;
|
|
117437
|
+
}
|
|
117012
117438
|
applySelectionHighlight(text) {
|
|
117013
117439
|
let result = "\x1B[7m";
|
|
117014
117440
|
let index = 0;
|
|
@@ -117097,8 +117523,12 @@ class TuiAltScreen extends TuiBase {
|
|
|
117097
117523
|
const width = Math.max(1, this.terminal.columns);
|
|
117098
117524
|
const height = Math.max(1, this.terminal.rows);
|
|
117099
117525
|
const root = this.layoutRoot ?? this.implicitScrollView;
|
|
117100
|
-
|
|
117526
|
+
let nextLayout = renderLayoutFrame(root, width, height, () => this.requestRender());
|
|
117527
|
+
if (this.refreshSearch(nextLayout)) {
|
|
117528
|
+
nextLayout = renderLayoutFrame(root, width, height, () => this.requestRender());
|
|
117529
|
+
}
|
|
117101
117530
|
let screen = nextLayout.lines.map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
117531
|
+
screen = this.applySearchHighlights(screen, nextLayout);
|
|
117102
117532
|
screen = this.compositeOverlays(screen, width, height);
|
|
117103
117533
|
if (screen.length > height)
|
|
117104
117534
|
screen = screen.slice(screen.length - height);
|
|
@@ -117847,6 +118277,8 @@ var ThemeJsonSchema = exports_typebox.Object({
|
|
|
117847
118277
|
thinkingText: ColorValueSchema,
|
|
117848
118278
|
selectedBg: ColorValueSchema,
|
|
117849
118279
|
scrollbarThumb: exports_typebox.Optional(ColorValueSchema),
|
|
118280
|
+
searchMatchBg: exports_typebox.Optional(ColorValueSchema),
|
|
118281
|
+
searchMatchText: exports_typebox.Optional(ColorValueSchema),
|
|
117850
118282
|
userMessageBg: ColorValueSchema,
|
|
117851
118283
|
userMessageText: ColorValueSchema,
|
|
117852
118284
|
customMessageBg: ColorValueSchema,
|
|
@@ -118022,7 +118454,9 @@ function withThemeColorFallbacks(colors) {
|
|
|
118022
118454
|
return {
|
|
118023
118455
|
...colors,
|
|
118024
118456
|
thinkingMax: colors.thinkingMax ?? colors.thinkingXhigh,
|
|
118025
|
-
scrollbarThumb: colors.scrollbarThumb ?? colors.selectedBg
|
|
118457
|
+
scrollbarThumb: colors.scrollbarThumb ?? colors.selectedBg,
|
|
118458
|
+
searchMatchBg: colors.searchMatchBg ?? colors.selectedBg,
|
|
118459
|
+
searchMatchText: colors.searchMatchText ?? colors.text
|
|
118026
118460
|
};
|
|
118027
118461
|
}
|
|
118028
118462
|
|
|
@@ -118039,14 +118473,19 @@ class Theme {
|
|
|
118039
118473
|
this.sourceInfo = options.sourceInfo;
|
|
118040
118474
|
this.mode = mode;
|
|
118041
118475
|
this.fgColors = new Map;
|
|
118042
|
-
const colors = {
|
|
118476
|
+
const colors = {
|
|
118477
|
+
...fgColors,
|
|
118478
|
+
thinkingMax: fgColors.thinkingMax ?? fgColors.thinkingXhigh,
|
|
118479
|
+
searchMatchText: fgColors.searchMatchText ?? fgColors.text
|
|
118480
|
+
};
|
|
118043
118481
|
for (const [key, value2] of Object.entries(colors)) {
|
|
118044
118482
|
this.fgColors.set(key, fgAnsi(value2, mode));
|
|
118045
118483
|
}
|
|
118046
118484
|
this.bgColors = new Map;
|
|
118047
118485
|
const backgrounds = {
|
|
118048
118486
|
...bgColors,
|
|
118049
|
-
scrollbarThumb: bgColors.scrollbarThumb ?? bgColors.selectedBg
|
|
118487
|
+
scrollbarThumb: bgColors.scrollbarThumb ?? bgColors.selectedBg,
|
|
118488
|
+
searchMatchBg: bgColors.searchMatchBg ?? bgColors.selectedBg
|
|
118050
118489
|
};
|
|
118051
118490
|
for (const [key, value2] of Object.entries(backgrounds)) {
|
|
118052
118491
|
this.bgColors.set(key, bgAnsi(value2, mode));
|
|
@@ -118262,6 +118701,7 @@ function createTheme(themeJson, mode, sourcePath) {
|
|
|
118262
118701
|
const bgColorKeys = new Set([
|
|
118263
118702
|
"selectedBg",
|
|
118264
118703
|
"scrollbarThumb",
|
|
118704
|
+
"searchMatchBg",
|
|
118265
118705
|
"userMessageBg",
|
|
118266
118706
|
"customMessageBg",
|
|
118267
118707
|
"toolPendingBg",
|
|
@@ -120546,7 +120986,7 @@ class SessionManager {
|
|
|
120546
120986
|
if (this.fileEntries.length === 0) {
|
|
120547
120987
|
const explicitPath = this.sessionFile;
|
|
120548
120988
|
if (statSync4(explicitPath).size > 0) {
|
|
120549
|
-
throw new Error(`Session file is not a valid
|
|
120989
|
+
throw new Error(`Session file is not a valid ${APP_NAME} session: ${explicitPath}`);
|
|
120550
120990
|
}
|
|
120551
120991
|
this.newSession();
|
|
120552
120992
|
this.sessionFile = explicitPath;
|
|
@@ -122400,6 +122840,7 @@ __export(exports_dist2, {
|
|
|
122400
122840
|
setDefaultStreamFn: () => setDefaultStreamFn,
|
|
122401
122841
|
sessionEntryToContextMessages: () => sessionEntryToContextMessages2,
|
|
122402
122842
|
serializeConversation: () => serializeConversation2,
|
|
122843
|
+
scanningEntries: () => scanningEntries,
|
|
122403
122844
|
sanitizeBinaryOutput: () => sanitizeBinaryOutput2,
|
|
122404
122845
|
runAgentLoopContinue: () => runAgentLoopContinue,
|
|
122405
122846
|
runAgentLoop: () => runAgentLoop,
|
|
@@ -122415,7 +122856,6 @@ __export(exports_dist2, {
|
|
|
122415
122856
|
getOrUndefined: () => getOrUndefined,
|
|
122416
122857
|
getOrThrow: () => getOrThrow,
|
|
122417
122858
|
getLastAssistantUsage: () => getLastAssistantUsage2,
|
|
122418
|
-
getFileSystemResultOrThrow: () => getFileSystemResultOrThrow,
|
|
122419
122859
|
generateSummaryWithUsage: () => generateSummaryWithUsage2,
|
|
122420
122860
|
generateSummary: () => generateSummary2,
|
|
122421
122861
|
generateBranchSummary: () => generateBranchSummary2,
|
|
@@ -124192,10 +124632,10 @@ class Session {
|
|
|
124192
124632
|
assertValidCursor(query.cursor?.afterSeq);
|
|
124193
124633
|
return this.storage.findEntries(resultLimit === query.limit ? query : { ...query, limit: resultLimit });
|
|
124194
124634
|
}
|
|
124195
|
-
async queryBranchEntries(
|
|
124635
|
+
async queryBranchEntries(defaultLane, query = {}, resultLimit = query.limit) {
|
|
124196
124636
|
assertValidLimit(query.limit);
|
|
124197
124637
|
assertValidCursor(query.cursor?.afterSeq);
|
|
124198
|
-
const start = query.start ?? await this.getLeafIdForLane(
|
|
124638
|
+
const start = query.start ?? await this.getLeafIdForLane(defaultLane);
|
|
124199
124639
|
if (start === null)
|
|
124200
124640
|
return [];
|
|
124201
124641
|
const storageQuery = resultLimit === query.limit ? query : { ...query, limit: resultLimit };
|
|
@@ -124232,15 +124672,88 @@ class Session {
|
|
|
124232
124672
|
}
|
|
124233
124673
|
}
|
|
124234
124674
|
|
|
124675
|
+
// node_modules/@earendil-works/pi-agent-core/dist/harness/types.js
|
|
124676
|
+
function ok(value2) {
|
|
124677
|
+
return { ok: true, value: value2 };
|
|
124678
|
+
}
|
|
124679
|
+
function err(error) {
|
|
124680
|
+
return { ok: false, error };
|
|
124681
|
+
}
|
|
124682
|
+
function getOrThrow(result) {
|
|
124683
|
+
if (!result.ok)
|
|
124684
|
+
throw result.error;
|
|
124685
|
+
return result.value;
|
|
124686
|
+
}
|
|
124687
|
+
function getOrUndefined(result) {
|
|
124688
|
+
return result.ok ? result.value : undefined;
|
|
124689
|
+
}
|
|
124690
|
+
function toError(error) {
|
|
124691
|
+
if (error instanceof Error)
|
|
124692
|
+
return error;
|
|
124693
|
+
if (typeof error === "string")
|
|
124694
|
+
return new Error(error);
|
|
124695
|
+
try {
|
|
124696
|
+
return new Error(JSON.stringify(error));
|
|
124697
|
+
} catch {
|
|
124698
|
+
return new Error(String(error));
|
|
124699
|
+
}
|
|
124700
|
+
}
|
|
124701
|
+
|
|
124702
|
+
class FileError extends Error {
|
|
124703
|
+
code;
|
|
124704
|
+
path;
|
|
124705
|
+
constructor(code, message, path7, cause) {
|
|
124706
|
+
super(message, cause === undefined ? undefined : { cause });
|
|
124707
|
+
this.name = "FileError";
|
|
124708
|
+
this.code = code;
|
|
124709
|
+
this.path = path7;
|
|
124710
|
+
}
|
|
124711
|
+
}
|
|
124712
|
+
|
|
124713
|
+
class ExecutionError extends Error {
|
|
124714
|
+
code;
|
|
124715
|
+
constructor(code, message, cause) {
|
|
124716
|
+
super(message, cause === undefined ? undefined : { cause });
|
|
124717
|
+
this.name = "ExecutionError";
|
|
124718
|
+
this.code = code;
|
|
124719
|
+
}
|
|
124720
|
+
}
|
|
124721
|
+
|
|
124722
|
+
class CompactionError extends Error {
|
|
124723
|
+
code;
|
|
124724
|
+
constructor(code, message, cause) {
|
|
124725
|
+
super(message, cause === undefined ? undefined : { cause });
|
|
124726
|
+
this.name = "CompactionError";
|
|
124727
|
+
this.code = code;
|
|
124728
|
+
}
|
|
124729
|
+
}
|
|
124730
|
+
|
|
124731
|
+
class BranchSummaryError extends Error {
|
|
124732
|
+
code;
|
|
124733
|
+
constructor(code, message, cause) {
|
|
124734
|
+
super(message, cause === undefined ? undefined : { cause });
|
|
124735
|
+
this.name = "BranchSummaryError";
|
|
124736
|
+
this.code = code;
|
|
124737
|
+
}
|
|
124738
|
+
}
|
|
124739
|
+
|
|
124235
124740
|
// node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.js
|
|
124741
|
+
class JsonlDecodeError extends Error {
|
|
124742
|
+
kind;
|
|
124743
|
+
constructor(kind, message, cause) {
|
|
124744
|
+
super(message, cause === undefined ? undefined : { cause });
|
|
124745
|
+
this.name = "JsonlDecodeError";
|
|
124746
|
+
this.kind = kind;
|
|
124747
|
+
}
|
|
124748
|
+
}
|
|
124236
124749
|
function fileResult(result, message) {
|
|
124237
124750
|
if (!result.ok) {
|
|
124238
124751
|
throw new SessionError(result.error.code === "not_found" ? "not_found" : "storage", `${message}: ${result.error.message}`, result.error);
|
|
124239
124752
|
}
|
|
124240
124753
|
return result.value;
|
|
124241
124754
|
}
|
|
124242
|
-
function invalidFile(path7, line,
|
|
124243
|
-
return new SessionError("invalid_entry", `Invalid JSONL v4 session ${path7}: line ${line} ${message}`, cause);
|
|
124755
|
+
function invalidFile(path7, line, cause) {
|
|
124756
|
+
return new SessionError("invalid_entry", `Invalid JSONL v4 session ${path7}: line ${line} ${cause.message}`, cause);
|
|
124244
124757
|
}
|
|
124245
124758
|
|
|
124246
124759
|
// node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js
|
|
@@ -124268,70 +124781,82 @@ var OPERATION_KINDS = new Set(["run", "compaction", "navigation"]);
|
|
|
124268
124781
|
function isObject(value2) {
|
|
124269
124782
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
124270
124783
|
}
|
|
124271
|
-
function parseObject(line
|
|
124784
|
+
function parseObject(line) {
|
|
124272
124785
|
let value2;
|
|
124273
124786
|
try {
|
|
124274
124787
|
value2 = JSON.parse(line);
|
|
124275
124788
|
} catch (error) {
|
|
124276
|
-
throw
|
|
124789
|
+
throw new JsonlDecodeError("syntax", "is not valid JSON", error instanceof Error ? error : undefined);
|
|
124277
124790
|
}
|
|
124278
124791
|
if (!isObject(value2))
|
|
124279
|
-
throw
|
|
124792
|
+
throw new JsonlDecodeError("schema", "is not a JSON object");
|
|
124280
124793
|
return value2;
|
|
124281
124794
|
}
|
|
124282
|
-
function requireString(value2,
|
|
124795
|
+
function requireString(value2, field) {
|
|
124283
124796
|
if (typeof value2 !== "string")
|
|
124284
|
-
throw
|
|
124797
|
+
throw new JsonlDecodeError("schema", `has invalid ${field}`);
|
|
124285
124798
|
return value2;
|
|
124286
124799
|
}
|
|
124287
|
-
function requireSequence(value2
|
|
124288
|
-
if (!Number.isSafeInteger(value2) || value2 <= 0)
|
|
124289
|
-
throw
|
|
124800
|
+
function requireSequence(value2) {
|
|
124801
|
+
if (!Number.isSafeInteger(value2) || value2 <= 0) {
|
|
124802
|
+
throw new JsonlDecodeError("schema", "has invalid seq");
|
|
124803
|
+
}
|
|
124290
124804
|
return value2;
|
|
124291
124805
|
}
|
|
124292
|
-
function requireTimestamp(value2
|
|
124293
|
-
if (!Number.isSafeInteger(value2) || value2 < 0)
|
|
124294
|
-
throw
|
|
124806
|
+
function requireTimestamp(value2) {
|
|
124807
|
+
if (!Number.isSafeInteger(value2) || value2 < 0) {
|
|
124808
|
+
throw new JsonlDecodeError("schema", "has invalid timestamp");
|
|
124809
|
+
}
|
|
124295
124810
|
return value2;
|
|
124296
124811
|
}
|
|
124297
|
-
function requireNullableId(value2,
|
|
124812
|
+
function requireNullableId(value2, field) {
|
|
124298
124813
|
if (value2 !== null && typeof value2 !== "string") {
|
|
124299
|
-
throw
|
|
124814
|
+
throw new JsonlDecodeError("schema", `has invalid ${field}`);
|
|
124300
124815
|
}
|
|
124301
124816
|
return value2;
|
|
124302
124817
|
}
|
|
124303
|
-
function
|
|
124304
|
-
const value2 = parseObject(line
|
|
124818
|
+
function decodeHeader(line) {
|
|
124819
|
+
const value2 = parseObject(line);
|
|
124305
124820
|
if (value2.kind !== "header")
|
|
124306
|
-
throw
|
|
124821
|
+
throw new JsonlDecodeError("schema", "is not a header");
|
|
124307
124822
|
if (value2.version !== 4)
|
|
124308
|
-
throw
|
|
124823
|
+
throw new JsonlDecodeError("schema", "has unsupported session version");
|
|
124309
124824
|
const parentSessionId = value2.parentSessionId;
|
|
124310
124825
|
if (parentSessionId !== undefined && typeof parentSessionId !== "string") {
|
|
124311
|
-
throw
|
|
124826
|
+
throw new JsonlDecodeError("schema", "has invalid parentSessionId");
|
|
124312
124827
|
}
|
|
124313
124828
|
const legacyParentSessionPath = value2.legacyParentSessionPath;
|
|
124314
124829
|
if (legacyParentSessionPath !== undefined && typeof legacyParentSessionPath !== "string") {
|
|
124315
|
-
throw
|
|
124830
|
+
throw new JsonlDecodeError("schema", "has invalid legacyParentSessionPath");
|
|
124316
124831
|
}
|
|
124317
124832
|
if (parentSessionId !== undefined && legacyParentSessionPath !== undefined) {
|
|
124318
|
-
throw
|
|
124833
|
+
throw new JsonlDecodeError("schema", "has both parentSessionId and legacyParentSessionPath");
|
|
124319
124834
|
}
|
|
124320
124835
|
const metadataValue = value2.metadata;
|
|
124321
|
-
if (metadataValue !== undefined && !isObject(metadataValue))
|
|
124322
|
-
throw
|
|
124836
|
+
if (metadataValue !== undefined && !isObject(metadataValue)) {
|
|
124837
|
+
throw new JsonlDecodeError("schema", "has invalid metadata");
|
|
124838
|
+
}
|
|
124323
124839
|
const metadata = metadataValue;
|
|
124324
124840
|
return {
|
|
124325
124841
|
kind: "header",
|
|
124326
124842
|
version: 4,
|
|
124327
|
-
id: requireString(value2.id,
|
|
124328
|
-
createdAt: requireTimestamp(value2.createdAt
|
|
124329
|
-
cwd: requireString(value2.cwd,
|
|
124843
|
+
id: requireString(value2.id, "id"),
|
|
124844
|
+
createdAt: requireTimestamp(value2.createdAt),
|
|
124845
|
+
cwd: requireString(value2.cwd, "cwd"),
|
|
124330
124846
|
parentSessionId,
|
|
124331
124847
|
legacyParentSessionPath,
|
|
124332
124848
|
metadata
|
|
124333
124849
|
};
|
|
124334
124850
|
}
|
|
124851
|
+
function parseHeader(line) {
|
|
124852
|
+
try {
|
|
124853
|
+
return ok(decodeHeader(line));
|
|
124854
|
+
} catch (error) {
|
|
124855
|
+
if (error instanceof JsonlDecodeError)
|
|
124856
|
+
return err(error);
|
|
124857
|
+
throw error;
|
|
124858
|
+
}
|
|
124859
|
+
}
|
|
124335
124860
|
function encodeHeader(header) {
|
|
124336
124861
|
return `${JSON.stringify(header)}
|
|
124337
124862
|
`;
|
|
@@ -124349,73 +124874,97 @@ function metadataFromHeader(header, path7, modifiedAt) {
|
|
|
124349
124874
|
...header.metadata === undefined ? {} : { metadata: header.metadata }
|
|
124350
124875
|
};
|
|
124351
124876
|
}
|
|
124352
|
-
function
|
|
124353
|
-
const
|
|
124354
|
-
const
|
|
124355
|
-
|
|
124356
|
-
|
|
124357
|
-
|
|
124358
|
-
|
|
124359
|
-
|
|
124360
|
-
|
|
124361
|
-
|
|
124362
|
-
|
|
124363
|
-
|
|
124364
|
-
|
|
124365
|
-
|
|
124366
|
-
|
|
124367
|
-
|
|
124368
|
-
|
|
124369
|
-
|
|
124370
|
-
|
|
124371
|
-
|
|
124372
|
-
|
|
124373
|
-
|
|
124374
|
-
|
|
124375
|
-
|
|
124376
|
-
|
|
124377
|
-
|
|
124378
|
-
|
|
124379
|
-
|
|
124380
|
-
|
|
124381
|
-
|
|
124382
|
-
|
|
124383
|
-
|
|
124384
|
-
|
|
124385
|
-
|
|
124386
|
-
|
|
124387
|
-
|
|
124388
|
-
|
|
124389
|
-
|
|
124390
|
-
|
|
124391
|
-
|
|
124877
|
+
function parseEntryMutation(value2, seq) {
|
|
124878
|
+
const lane = value2.lane === undefined ? undefined : requireString(value2.lane, "lane");
|
|
124879
|
+
const id = requireString(value2.id, "id");
|
|
124880
|
+
const type = requireString(value2.type, "entry type");
|
|
124881
|
+
if (!ENTRY_TYPES.has(type)) {
|
|
124882
|
+
throw new JsonlDecodeError("schema", `has unknown entry type ${type}`);
|
|
124883
|
+
}
|
|
124884
|
+
const parentId = requireNullableId(value2.parentId, "parentId");
|
|
124885
|
+
const timestamp = requireTimestamp(value2.timestamp);
|
|
124886
|
+
if (type === "custom")
|
|
124887
|
+
requireString(value2.customType, "customType");
|
|
124888
|
+
const { kind: _kind, lane: _lane, ...entryFields } = value2;
|
|
124889
|
+
const entry = { ...entryFields, id, type, parentId, seq, timestamp };
|
|
124890
|
+
return lane === undefined ? { kind: "entry", entry } : { kind: "entry", lane, entry };
|
|
124891
|
+
}
|
|
124892
|
+
function parseRecordMutation(value2, seq) {
|
|
124893
|
+
const id = requireString(value2.id, "id");
|
|
124894
|
+
const lane = requireString(value2.lane, "lane");
|
|
124895
|
+
const type = requireString(value2.type, "record type");
|
|
124896
|
+
if (!RECORD_TYPES.has(type)) {
|
|
124897
|
+
throw new JsonlDecodeError("schema", `has unknown record type ${type}`);
|
|
124898
|
+
}
|
|
124899
|
+
const timestamp = requireTimestamp(value2.timestamp);
|
|
124900
|
+
if (type === "operation_started") {
|
|
124901
|
+
if (!isObject(value2.intent))
|
|
124902
|
+
throw new JsonlDecodeError("schema", "has invalid intent");
|
|
124903
|
+
const operationKind = requireString(value2.intent.kind, "operation kind");
|
|
124904
|
+
if (!OPERATION_KINDS.has(operationKind)) {
|
|
124905
|
+
throw new JsonlDecodeError("schema", `has unknown operation kind ${operationKind}`);
|
|
124906
|
+
}
|
|
124907
|
+
}
|
|
124908
|
+
if (type === "operation_finished")
|
|
124909
|
+
requireString(value2.runId, "runId");
|
|
124910
|
+
const { kind: _kind, ...recordFields } = value2;
|
|
124911
|
+
return {
|
|
124912
|
+
kind: "record",
|
|
124913
|
+
record: { ...recordFields, id, lane, type, seq, timestamp }
|
|
124914
|
+
};
|
|
124915
|
+
}
|
|
124916
|
+
function parseLaneMutation(value2, seq) {
|
|
124917
|
+
return {
|
|
124918
|
+
kind: "lane",
|
|
124919
|
+
seq,
|
|
124920
|
+
lane: requireString(value2.lane, "lane"),
|
|
124921
|
+
leafId: requireNullableId(value2.leafId, "leafId")
|
|
124922
|
+
};
|
|
124923
|
+
}
|
|
124924
|
+
function parseFactMutation(value2, seq) {
|
|
124925
|
+
if (value2.fact === "name") {
|
|
124926
|
+
if (value2.name !== undefined && typeof value2.name !== "string") {
|
|
124927
|
+
throw new JsonlDecodeError("schema", "has invalid name");
|
|
124928
|
+
}
|
|
124929
|
+
return { kind: "fact", seq, fact: "name", name: value2.name };
|
|
124930
|
+
}
|
|
124931
|
+
if (value2.fact === "label") {
|
|
124932
|
+
if (value2.label !== undefined && typeof value2.label !== "string") {
|
|
124933
|
+
throw new JsonlDecodeError("schema", "has invalid label");
|
|
124392
124934
|
}
|
|
124935
|
+
return {
|
|
124936
|
+
kind: "fact",
|
|
124937
|
+
seq,
|
|
124938
|
+
fact: "label",
|
|
124939
|
+
targetId: requireString(value2.targetId, "targetId"),
|
|
124940
|
+
label: value2.label
|
|
124941
|
+
};
|
|
124942
|
+
}
|
|
124943
|
+
throw new JsonlDecodeError("schema", "has unknown fact type");
|
|
124944
|
+
}
|
|
124945
|
+
function decodeMutation(line) {
|
|
124946
|
+
const value2 = parseObject(line);
|
|
124947
|
+
const seq = requireSequence(value2.seq);
|
|
124948
|
+
switch (value2.kind) {
|
|
124949
|
+
case "entry":
|
|
124950
|
+
return parseEntryMutation(value2, seq);
|
|
124951
|
+
case "record":
|
|
124952
|
+
return parseRecordMutation(value2, seq);
|
|
124393
124953
|
case "lane":
|
|
124394
|
-
return
|
|
124395
|
-
kind: "lane",
|
|
124396
|
-
seq,
|
|
124397
|
-
lane: requireString(value2.lane, path7, lineNumber, "lane"),
|
|
124398
|
-
leafId: requireNullableId(value2.leafId, path7, lineNumber, "leafId")
|
|
124399
|
-
};
|
|
124954
|
+
return parseLaneMutation(value2, seq);
|
|
124400
124955
|
case "fact":
|
|
124401
|
-
|
|
124402
|
-
return { kind: "fact", seq, fact: "name", name: requireString(value2.name, path7, lineNumber, "name") };
|
|
124403
|
-
}
|
|
124404
|
-
if (value2.fact === "label") {
|
|
124405
|
-
if (value2.label !== undefined && typeof value2.label !== "string") {
|
|
124406
|
-
throw invalidFile(path7, lineNumber, "has invalid label");
|
|
124407
|
-
}
|
|
124408
|
-
return {
|
|
124409
|
-
kind: "fact",
|
|
124410
|
-
seq,
|
|
124411
|
-
fact: "label",
|
|
124412
|
-
targetId: requireString(value2.targetId, path7, lineNumber, "targetId"),
|
|
124413
|
-
label: value2.label
|
|
124414
|
-
};
|
|
124415
|
-
}
|
|
124416
|
-
throw invalidFile(path7, lineNumber, "has unknown fact type");
|
|
124956
|
+
return parseFactMutation(value2, seq);
|
|
124417
124957
|
default:
|
|
124418
|
-
throw
|
|
124958
|
+
throw new JsonlDecodeError("schema", "has unknown mutation kind");
|
|
124959
|
+
}
|
|
124960
|
+
}
|
|
124961
|
+
function parseMutation(line) {
|
|
124962
|
+
try {
|
|
124963
|
+
return ok(decodeMutation(line));
|
|
124964
|
+
} catch (error) {
|
|
124965
|
+
if (error instanceof JsonlDecodeError)
|
|
124966
|
+
return err(error);
|
|
124967
|
+
throw error;
|
|
124419
124968
|
}
|
|
124420
124969
|
}
|
|
124421
124970
|
function encodeMutation(mutation) {
|
|
@@ -124768,28 +125317,38 @@ class JsonlSessionStorage {
|
|
|
124768
125317
|
`);
|
|
124769
125318
|
if (physicalLines.at(-1) === "")
|
|
124770
125319
|
physicalLines.pop();
|
|
124771
|
-
if (physicalLines.length === 0 || !physicalLines[0])
|
|
124772
|
-
throw invalidFile(path7, 1, "is missing a header");
|
|
124773
|
-
|
|
125320
|
+
if (physicalLines.length === 0 || !physicalLines[0]) {
|
|
125321
|
+
throw invalidFile(path7, 1, new JsonlDecodeError("schema", "is missing a header"));
|
|
125322
|
+
}
|
|
125323
|
+
const headerResult = parseHeader(physicalLines[0]);
|
|
125324
|
+
if (!headerResult.ok)
|
|
125325
|
+
throw invalidFile(path7, 1, headerResult.error);
|
|
124774
125326
|
const fileInfo = fileResult(await fs5.fileInfo(path7), `Failed to read session metadata ${path7}`);
|
|
124775
|
-
const storage = new JsonlSessionStorage(fs5, metadataFromHeader(
|
|
125327
|
+
const storage = new JsonlSessionStorage(fs5, metadataFromHeader(headerResult.value, path7, fileInfo.mtimeMs));
|
|
124776
125328
|
for (let index = 1;index < physicalLines.length; index++) {
|
|
124777
125329
|
const line = physicalLines[index];
|
|
124778
|
-
|
|
124779
|
-
|
|
124780
|
-
|
|
124781
|
-
|
|
124782
|
-
|
|
124783
|
-
throw error;
|
|
124784
|
-
const validPrefix = `${physicalLines.slice(0, index).join(`
|
|
125330
|
+
const mutationResult = parseMutation(line);
|
|
125331
|
+
if (!mutationResult.ok) {
|
|
125332
|
+
const isTornTail = index === physicalLines.length - 1 && mutationResult.error.kind === "syntax";
|
|
125333
|
+
if (isTornTail) {
|
|
125334
|
+
const validPrefix = `${physicalLines.slice(0, index).join(`
|
|
124785
125335
|
`)}
|
|
124786
125336
|
`;
|
|
124787
|
-
|
|
124788
|
-
|
|
124789
|
-
|
|
124790
|
-
|
|
125337
|
+
await publishFileAtomically(fs5, path7, async (tempPath) => {
|
|
125338
|
+
fileResult(await fs5.writeFile(tempPath, validPrefix), `Failed to stage torn-tail repair ${path7}`);
|
|
125339
|
+
});
|
|
125340
|
+
return storage;
|
|
125341
|
+
}
|
|
125342
|
+
throw invalidFile(path7, index + 1, mutationResult.error);
|
|
125343
|
+
}
|
|
125344
|
+
try {
|
|
125345
|
+
storage.applyMutation(mutationResult.value);
|
|
125346
|
+
} catch (error) {
|
|
125347
|
+
if (error instanceof SessionError && error.code === "invalid_entry") {
|
|
125348
|
+
throw invalidFile(path7, index + 1, error);
|
|
125349
|
+
}
|
|
125350
|
+
throw error;
|
|
124791
125351
|
}
|
|
124792
|
-
storage.applyMutation(mutation, path7, index + 1);
|
|
124793
125352
|
}
|
|
124794
125353
|
if (!content.endsWith(`
|
|
124795
125354
|
`)) {
|
|
@@ -124932,10 +125491,8 @@ class JsonlSessionStorage {
|
|
|
124932
125491
|
async appendMutation(mutation) {
|
|
124933
125492
|
fileResult(await this.fs.appendFile(this.metadata.path, encodeMutation(mutation)), `Failed to append session ${this.metadata.path}`);
|
|
124934
125493
|
}
|
|
124935
|
-
applyMutation(mutation
|
|
124936
|
-
this.state.applyMutation(mutation
|
|
124937
|
-
throw invalidFile(path7, line, message);
|
|
124938
|
-
});
|
|
125494
|
+
applyMutation(mutation) {
|
|
125495
|
+
this.state.applyMutation(mutation);
|
|
124939
125496
|
}
|
|
124940
125497
|
}
|
|
124941
125498
|
|
|
@@ -124946,9 +125503,53 @@ function validateSessionId(id) {
|
|
|
124946
125503
|
throw new SessionError("invalid_payload", "Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character");
|
|
124947
125504
|
}
|
|
124948
125505
|
}
|
|
124949
|
-
function
|
|
125506
|
+
function jsonlSessionDirectoryName(cwd) {
|
|
124950
125507
|
return `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
124951
125508
|
}
|
|
125509
|
+
async function jsonlSessionsRoot(options) {
|
|
125510
|
+
return fileResult(await options.fs.absolutePath(options.sessionsRoot), `Failed to resolve sessions root ${options.sessionsRoot}`);
|
|
125511
|
+
}
|
|
125512
|
+
async function jsonlSessionDirectory(fs5, sessionsRoot, cwd) {
|
|
125513
|
+
return fileResult(await fs5.joinPath([sessionsRoot, jsonlSessionDirectoryName(cwd)]), `Failed to resolve sessions directory for ${cwd}`);
|
|
125514
|
+
}
|
|
125515
|
+
async function jsonlSessionDirectories(options, cwd) {
|
|
125516
|
+
const sessionsRoot = await jsonlSessionsRoot(options);
|
|
125517
|
+
if (cwd !== undefined) {
|
|
125518
|
+
const resolvedCwd = fileResult(await options.fs.absolutePath(cwd), `Failed to resolve session cwd ${cwd}`);
|
|
125519
|
+
const directory = await jsonlSessionDirectory(options.fs, sessionsRoot, resolvedCwd);
|
|
125520
|
+
return fileResult(await options.fs.exists(directory), `Failed to check sessions directory ${directory}`) ? [directory] : [];
|
|
125521
|
+
}
|
|
125522
|
+
if (!fileResult(await options.fs.exists(sessionsRoot), `Failed to check sessions directory ${sessionsRoot}`))
|
|
125523
|
+
return [];
|
|
125524
|
+
return fileResult(await options.fs.listDir(sessionsRoot), `Failed to list sessions directory ${sessionsRoot}`).filter((entry) => entry.kind === "directory" || entry.kind === "symlink").map((entry) => entry.path);
|
|
125525
|
+
}
|
|
125526
|
+
async function listJsonlSessionMetadata(options, query = {}) {
|
|
125527
|
+
const metadata = [];
|
|
125528
|
+
for (const directory of await jsonlSessionDirectories(options, query.cwd)) {
|
|
125529
|
+
const files = fileResult(await options.fs.listDir(directory), `Failed to list sessions directory ${directory}`).filter((entry) => entry.kind !== "directory" && entry.name.endsWith(".jsonl"));
|
|
125530
|
+
for (const file of files) {
|
|
125531
|
+
const [firstLine] = fileResult(await options.fs.readTextLines(file.path, { maxLines: 1 }), `Failed to read session header ${file.path}`);
|
|
125532
|
+
if (!firstLine)
|
|
125533
|
+
continue;
|
|
125534
|
+
const headerResult = parseHeader(firstLine);
|
|
125535
|
+
if (!headerResult.ok)
|
|
125536
|
+
continue;
|
|
125537
|
+
metadata.push(metadataFromHeader(headerResult.value, file.path, file.mtimeMs));
|
|
125538
|
+
}
|
|
125539
|
+
}
|
|
125540
|
+
return metadata.sort((left, right) => right.modifiedAt - left.modifiedAt);
|
|
125541
|
+
}
|
|
125542
|
+
async function loadJsonlSessionStorage(options, metadata) {
|
|
125543
|
+
if (!fileResult(await options.fs.exists(metadata.path), `Failed to check session ${metadata.path}`)) {
|
|
125544
|
+
throw new SessionError("not_found", `Session not found: ${metadata.id}`);
|
|
125545
|
+
}
|
|
125546
|
+
const storage = await JsonlSessionStorage.load(options.fs, metadata.path);
|
|
125547
|
+
const loadedMetadata = await storage.getMetadata();
|
|
125548
|
+
if (loadedMetadata.id !== metadata.id) {
|
|
125549
|
+
throw new SessionError("invalid_entry", `Session id does not match header: ${metadata.id}`);
|
|
125550
|
+
}
|
|
125551
|
+
return storage;
|
|
125552
|
+
}
|
|
124952
125553
|
function sessionFileName(createdAt, id) {
|
|
124953
125554
|
const timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, "-");
|
|
124954
125555
|
return `${timestamp}_${id}.jsonl`;
|
|
@@ -124957,14 +125558,18 @@ function sessionFileName(createdAt, id) {
|
|
|
124957
125558
|
class JsonlSessionRepo {
|
|
124958
125559
|
fs;
|
|
124959
125560
|
sessionsRootInput;
|
|
125561
|
+
activeCreateDestinations = new Set;
|
|
124960
125562
|
rootPromise;
|
|
124961
125563
|
constructor(options) {
|
|
124962
125564
|
this.fs = options.fs;
|
|
124963
125565
|
this.sessionsRootInput = options.sessionsRoot;
|
|
124964
125566
|
}
|
|
124965
125567
|
async create(options) {
|
|
124966
|
-
const
|
|
124967
|
-
return
|
|
125568
|
+
const destination = await this.resolveCreateDestination(options);
|
|
125569
|
+
return this.claimCreateDestination(destination, async () => {
|
|
125570
|
+
const { header, path: path7 } = await this.prepareCreate(destination, options);
|
|
125571
|
+
return new Session(await JsonlSessionStorage.create(this.fs, path7, header));
|
|
125572
|
+
});
|
|
124968
125573
|
}
|
|
124969
125574
|
async open(metadata) {
|
|
124970
125575
|
return new Session(await this.loadStorage(metadata));
|
|
@@ -124977,27 +125582,39 @@ class JsonlSessionRepo {
|
|
|
124977
125582
|
}
|
|
124978
125583
|
async fork(source, options) {
|
|
124979
125584
|
const sourceStorage = await this.loadStorage(source);
|
|
124980
|
-
const
|
|
125585
|
+
const createOptions = {
|
|
124981
125586
|
...options,
|
|
124982
125587
|
parentSessionId: options.parentSessionId ?? source.id
|
|
125588
|
+
};
|
|
125589
|
+
const destination = await this.resolveCreateDestination(createOptions);
|
|
125590
|
+
return this.claimCreateDestination(destination, async () => {
|
|
125591
|
+
const { header, path: path7 } = await this.prepareCreate(destination, createOptions);
|
|
125592
|
+
return new Session(await sourceStorage.fork(path7, header, options));
|
|
124983
125593
|
});
|
|
124984
|
-
return new Session(await sourceStorage.fork(path7, header, options));
|
|
124985
125594
|
}
|
|
124986
125595
|
async loadStorage(metadata) {
|
|
124987
|
-
|
|
124988
|
-
throw new SessionError("not_found", `Session not found: ${metadata.id}`);
|
|
124989
|
-
}
|
|
124990
|
-
const storage = await JsonlSessionStorage.load(this.fs, metadata.path);
|
|
124991
|
-
const loadedMetadata = await storage.getMetadata();
|
|
124992
|
-
if (loadedMetadata.id !== metadata.id) {
|
|
124993
|
-
throw new SessionError("invalid_entry", `Session id does not match header: ${metadata.id}`);
|
|
124994
|
-
}
|
|
124995
|
-
return storage;
|
|
125596
|
+
return loadJsonlSessionStorage({ fs: this.fs, sessionsRoot: this.sessionsRootInput }, metadata);
|
|
124996
125597
|
}
|
|
124997
|
-
async
|
|
125598
|
+
async resolveCreateDestination(options) {
|
|
124998
125599
|
const id = options.id ?? uuidv7();
|
|
124999
125600
|
validateSessionId(id);
|
|
125000
125601
|
const cwd = fileResult(await this.fs.absolutePath(options.cwd), `Failed to resolve session cwd ${options.cwd}`);
|
|
125602
|
+
return { id, cwd };
|
|
125603
|
+
}
|
|
125604
|
+
async claimCreateDestination(destination, operation) {
|
|
125605
|
+
const key = `${destination.cwd}\x00${destination.id}`;
|
|
125606
|
+
if (this.activeCreateDestinations.has(key)) {
|
|
125607
|
+
throw new SessionError("already_exists", `Session already exists: ${destination.id}`);
|
|
125608
|
+
}
|
|
125609
|
+
this.activeCreateDestinations.add(key);
|
|
125610
|
+
try {
|
|
125611
|
+
return await operation();
|
|
125612
|
+
} finally {
|
|
125613
|
+
this.activeCreateDestinations.delete(key);
|
|
125614
|
+
}
|
|
125615
|
+
}
|
|
125616
|
+
async prepareCreate(destination, options) {
|
|
125617
|
+
const { id, cwd } = destination;
|
|
125001
125618
|
if (await this.sessionIdExists(id, cwd)) {
|
|
125002
125619
|
throw new SessionError("already_exists", `Session already exists: ${id}`);
|
|
125003
125620
|
}
|
|
@@ -125019,20 +125636,7 @@ class JsonlSessionRepo {
|
|
|
125019
125636
|
return { header, path: path7 };
|
|
125020
125637
|
}
|
|
125021
125638
|
async listDirect(options) {
|
|
125022
|
-
|
|
125023
|
-
const metadata = [];
|
|
125024
|
-
for (const directory of directories) {
|
|
125025
|
-
const files = fileResult(await this.fs.listDir(directory), `Failed to list sessions directory ${directory}`).filter((entry) => entry.kind !== "directory" && entry.name.endsWith(".jsonl"));
|
|
125026
|
-
for (const file of files) {
|
|
125027
|
-
const content = fileResult(await this.fs.readTextFile(file.path), `Failed to read session header ${file.path}`);
|
|
125028
|
-
const firstLine = content.split(`
|
|
125029
|
-
`, 1)[0];
|
|
125030
|
-
if (!firstLine)
|
|
125031
|
-
throw invalidFile(file.path, 1, "is missing a header");
|
|
125032
|
-
metadata.push(metadataFromHeader(parseHeader(firstLine, file.path), file.path, file.mtimeMs));
|
|
125033
|
-
}
|
|
125034
|
-
}
|
|
125035
|
-
return metadata.sort((left, right) => right.modifiedAt - left.modifiedAt);
|
|
125639
|
+
return listJsonlSessionMetadata({ fs: this.fs, sessionsRoot: this.sessionsRootInput }, options);
|
|
125036
125640
|
}
|
|
125037
125641
|
async sessionIdExists(id, cwd) {
|
|
125038
125642
|
const suffix = `_${id}.jsonl`;
|
|
@@ -125042,19 +125646,8 @@ class JsonlSessionRepo {
|
|
|
125042
125646
|
const files = fileResult(await this.fs.listDir(directory), `Failed to list sessions directory ${directory}`);
|
|
125043
125647
|
return files.some((entry) => entry.kind !== "directory" && entry.name.endsWith(suffix));
|
|
125044
125648
|
}
|
|
125045
|
-
async sessionDirectories(cwd) {
|
|
125046
|
-
const root = await this.root();
|
|
125047
|
-
if (cwd !== undefined) {
|
|
125048
|
-
const resolvedCwd = fileResult(await this.fs.absolutePath(cwd), `Failed to resolve session cwd ${cwd}`);
|
|
125049
|
-
const directory = await this.sessionDirectory(resolvedCwd);
|
|
125050
|
-
return fileResult(await this.fs.exists(directory), `Failed to check sessions directory ${directory}`) ? [directory] : [];
|
|
125051
|
-
}
|
|
125052
|
-
if (!fileResult(await this.fs.exists(root), `Failed to check sessions directory ${root}`))
|
|
125053
|
-
return [];
|
|
125054
|
-
return fileResult(await this.fs.listDir(root), `Failed to list sessions directory ${root}`).filter((entry) => entry.kind === "directory" || entry.kind === "symlink").map((entry) => entry.path);
|
|
125055
|
-
}
|
|
125056
125649
|
async sessionDirectory(cwd) {
|
|
125057
|
-
return fileResult(await this.fs.joinPath([await this.root(),
|
|
125650
|
+
return fileResult(await this.fs.joinPath([await this.root(), jsonlSessionDirectoryName(cwd)]), `Failed to resolve sessions directory for ${cwd}`);
|
|
125058
125651
|
}
|
|
125059
125652
|
root() {
|
|
125060
125653
|
this.rootPromise ??= this.fs.absolutePath(this.sessionsRootInput).then((result) => fileResult(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));
|
|
@@ -125199,71 +125792,6 @@ class InMemorySessionRepo {
|
|
|
125199
125792
|
return storage;
|
|
125200
125793
|
}
|
|
125201
125794
|
}
|
|
125202
|
-
// node_modules/@earendil-works/pi-agent-core/dist/harness/types.js
|
|
125203
|
-
function ok(value2) {
|
|
125204
|
-
return { ok: true, value: value2 };
|
|
125205
|
-
}
|
|
125206
|
-
function err(error) {
|
|
125207
|
-
return { ok: false, error };
|
|
125208
|
-
}
|
|
125209
|
-
function getOrThrow(result) {
|
|
125210
|
-
if (!result.ok)
|
|
125211
|
-
throw result.error;
|
|
125212
|
-
return result.value;
|
|
125213
|
-
}
|
|
125214
|
-
function getOrUndefined(result) {
|
|
125215
|
-
return result.ok ? result.value : undefined;
|
|
125216
|
-
}
|
|
125217
|
-
function toError(error) {
|
|
125218
|
-
if (error instanceof Error)
|
|
125219
|
-
return error;
|
|
125220
|
-
if (typeof error === "string")
|
|
125221
|
-
return new Error(error);
|
|
125222
|
-
try {
|
|
125223
|
-
return new Error(JSON.stringify(error));
|
|
125224
|
-
} catch {
|
|
125225
|
-
return new Error(String(error));
|
|
125226
|
-
}
|
|
125227
|
-
}
|
|
125228
|
-
|
|
125229
|
-
class FileError extends Error {
|
|
125230
|
-
code;
|
|
125231
|
-
path;
|
|
125232
|
-
constructor(code, message, path7, cause) {
|
|
125233
|
-
super(message, cause === undefined ? undefined : { cause });
|
|
125234
|
-
this.name = "FileError";
|
|
125235
|
-
this.code = code;
|
|
125236
|
-
this.path = path7;
|
|
125237
|
-
}
|
|
125238
|
-
}
|
|
125239
|
-
|
|
125240
|
-
class ExecutionError extends Error {
|
|
125241
|
-
code;
|
|
125242
|
-
constructor(code, message, cause) {
|
|
125243
|
-
super(message, cause === undefined ? undefined : { cause });
|
|
125244
|
-
this.name = "ExecutionError";
|
|
125245
|
-
this.code = code;
|
|
125246
|
-
}
|
|
125247
|
-
}
|
|
125248
|
-
|
|
125249
|
-
class CompactionError extends Error {
|
|
125250
|
-
code;
|
|
125251
|
-
constructor(code, message, cause) {
|
|
125252
|
-
super(message, cause === undefined ? undefined : { cause });
|
|
125253
|
-
this.name = "CompactionError";
|
|
125254
|
-
this.code = code;
|
|
125255
|
-
}
|
|
125256
|
-
}
|
|
125257
|
-
|
|
125258
|
-
class BranchSummaryError extends Error {
|
|
125259
|
-
code;
|
|
125260
|
-
constructor(code, message, cause) {
|
|
125261
|
-
super(message, cause === undefined ? undefined : { cause });
|
|
125262
|
-
this.name = "BranchSummaryError";
|
|
125263
|
-
this.code = code;
|
|
125264
|
-
}
|
|
125265
|
-
}
|
|
125266
|
-
|
|
125267
125795
|
// node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/utils.js
|
|
125268
125796
|
function createFileOps2() {
|
|
125269
125797
|
return {
|
|
@@ -126311,48 +126839,6 @@ function substituteArgs(content, args) {
|
|
|
126311
126839
|
function formatPromptTemplateInvocation(template, args = []) {
|
|
126312
126840
|
return substituteArgs(template.content, args);
|
|
126313
126841
|
}
|
|
126314
|
-
// node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.js
|
|
126315
|
-
function getFileSystemResultOrThrow(result, message) {
|
|
126316
|
-
if (!result.ok) {
|
|
126317
|
-
const code = result.error.code === "not_found" ? "not_found" : "storage";
|
|
126318
|
-
throw new SessionError(code, `${message}: ${result.error.message}`, result.error);
|
|
126319
|
-
}
|
|
126320
|
-
return result.value;
|
|
126321
|
-
}
|
|
126322
|
-
|
|
126323
|
-
class ScanningSessionSearch {
|
|
126324
|
-
source;
|
|
126325
|
-
constructor(source) {
|
|
126326
|
-
this.source = source;
|
|
126327
|
-
}
|
|
126328
|
-
async search(options) {
|
|
126329
|
-
const normalizedText = options.text.trim().toLowerCase();
|
|
126330
|
-
if (!normalizedText)
|
|
126331
|
-
return [];
|
|
126332
|
-
const hits = [];
|
|
126333
|
-
for (const metadata of await this.source.list()) {
|
|
126334
|
-
const cwd = metadata.cwd;
|
|
126335
|
-
if (options.cwd !== undefined && cwd !== options.cwd)
|
|
126336
|
-
continue;
|
|
126337
|
-
const session2 = await this.source.open(metadata);
|
|
126338
|
-
for (const entry of await session2.findEntries({ order: "oldestFirst" })) {
|
|
126339
|
-
const payload = JSON.stringify(entry);
|
|
126340
|
-
if (!payload.toLowerCase().includes(normalizedText))
|
|
126341
|
-
continue;
|
|
126342
|
-
hits.push({
|
|
126343
|
-
metadata,
|
|
126344
|
-
entryId: entry.id,
|
|
126345
|
-
timestamp: new Date(entry.timestamp).toISOString(),
|
|
126346
|
-
snippet: payload
|
|
126347
|
-
});
|
|
126348
|
-
}
|
|
126349
|
-
}
|
|
126350
|
-
return hits;
|
|
126351
|
-
}
|
|
126352
|
-
}
|
|
126353
|
-
function createScanningSessionSearch(source) {
|
|
126354
|
-
return new ScanningSessionSearch(source);
|
|
126355
|
-
}
|
|
126356
126842
|
// node_modules/@earendil-works/pi-agent-core/dist/harness/skills.js
|
|
126357
126843
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
126358
126844
|
var MAX_NAME_LENGTH = 64;
|
|
@@ -128028,9 +128514,9 @@ function overlapCount(a, b2) {
|
|
|
128028
128514
|
}
|
|
128029
128515
|
return k;
|
|
128030
128516
|
}
|
|
128031
|
-
function segment(string,
|
|
128517
|
+
function segment(string, segmenter3) {
|
|
128032
128518
|
const parts = [];
|
|
128033
|
-
for (const segmentObj of Array.from(
|
|
128519
|
+
for (const segmentObj of Array.from(segmenter3.segment(string))) {
|
|
128034
128520
|
const segment2 = segmentObj.segment;
|
|
128035
128521
|
if (parts.length && /\s/.test(parts[parts.length - 1]) && /\s/.test(segment2)) {
|
|
128036
128522
|
parts[parts.length - 1] += segment2;
|
|
@@ -128040,9 +128526,9 @@ function segment(string, segmenter2) {
|
|
|
128040
128526
|
}
|
|
128041
128527
|
return parts;
|
|
128042
128528
|
}
|
|
128043
|
-
function trailingWs(string,
|
|
128044
|
-
if (
|
|
128045
|
-
return leadingAndTrailingWs(string,
|
|
128529
|
+
function trailingWs(string, segmenter3) {
|
|
128530
|
+
if (segmenter3) {
|
|
128531
|
+
return leadingAndTrailingWs(string, segmenter3)[1];
|
|
128046
128532
|
}
|
|
128047
128533
|
let i;
|
|
128048
128534
|
for (i = string.length - 1;i >= 0; i--) {
|
|
@@ -128052,21 +128538,21 @@ function trailingWs(string, segmenter2) {
|
|
|
128052
128538
|
}
|
|
128053
128539
|
return string.substring(i + 1);
|
|
128054
128540
|
}
|
|
128055
|
-
function leadingWs(string,
|
|
128056
|
-
if (
|
|
128057
|
-
return leadingAndTrailingWs(string,
|
|
128541
|
+
function leadingWs(string, segmenter3) {
|
|
128542
|
+
if (segmenter3) {
|
|
128543
|
+
return leadingAndTrailingWs(string, segmenter3)[0];
|
|
128058
128544
|
}
|
|
128059
128545
|
const match = string.match(/^\s*/);
|
|
128060
128546
|
return match ? match[0] : "";
|
|
128061
128547
|
}
|
|
128062
|
-
function leadingAndTrailingWs(string,
|
|
128063
|
-
if (!
|
|
128548
|
+
function leadingAndTrailingWs(string, segmenter3) {
|
|
128549
|
+
if (!segmenter3) {
|
|
128064
128550
|
return [leadingWs(string), trailingWs(string)];
|
|
128065
128551
|
}
|
|
128066
|
-
if (
|
|
128552
|
+
if (segmenter3.resolvedOptions().granularity != "word") {
|
|
128067
128553
|
throw new Error('The segmenter passed must have a granularity of "word"');
|
|
128068
128554
|
}
|
|
128069
|
-
const segments = segment(string,
|
|
128555
|
+
const segments = segment(string, segmenter3);
|
|
128070
128556
|
const firstSeg = segments[0];
|
|
128071
128557
|
const lastSeg = segments[segments.length - 1];
|
|
128072
128558
|
const head = /\s/.test(firstSeg) ? firstSeg : "";
|
|
@@ -128089,11 +128575,11 @@ class WordDiff extends Diff {
|
|
|
128089
128575
|
tokenize(value2, options = {}) {
|
|
128090
128576
|
let parts;
|
|
128091
128577
|
if (options.intlSegmenter) {
|
|
128092
|
-
const
|
|
128093
|
-
if (
|
|
128578
|
+
const segmenter3 = options.intlSegmenter;
|
|
128579
|
+
if (segmenter3.resolvedOptions().granularity != "word") {
|
|
128094
128580
|
throw new Error('The segmenter passed must have a granularity of "word"');
|
|
128095
128581
|
}
|
|
128096
|
-
parts = segment(value2,
|
|
128582
|
+
parts = segment(value2, segmenter3);
|
|
128097
128583
|
} else {
|
|
128098
128584
|
parts = value2.match(tokenizeIncludingWhitespace) || [];
|
|
128099
128585
|
}
|
|
@@ -128162,10 +128648,10 @@ function diffWords(oldStr, newStr, options) {
|
|
|
128162
128648
|
}
|
|
128163
128649
|
return wordDiff.diff(oldStr, newStr, options);
|
|
128164
128650
|
}
|
|
128165
|
-
function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep,
|
|
128651
|
+
function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep, segmenter3) {
|
|
128166
128652
|
if (deletion && insertion) {
|
|
128167
|
-
const [oldWsPrefix, oldWsSuffix] = leadingAndTrailingWs(deletion.value,
|
|
128168
|
-
const [newWsPrefix, newWsSuffix] = leadingAndTrailingWs(insertion.value,
|
|
128653
|
+
const [oldWsPrefix, oldWsSuffix] = leadingAndTrailingWs(deletion.value, segmenter3);
|
|
128654
|
+
const [newWsPrefix, newWsSuffix] = leadingAndTrailingWs(insertion.value, segmenter3);
|
|
128169
128655
|
if (startKeep) {
|
|
128170
128656
|
const commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix);
|
|
128171
128657
|
startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix);
|
|
@@ -128180,15 +128666,15 @@ function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep
|
|
|
128180
128666
|
}
|
|
128181
128667
|
} else if (insertion) {
|
|
128182
128668
|
if (startKeep) {
|
|
128183
|
-
const ws = leadingWs(insertion.value,
|
|
128669
|
+
const ws = leadingWs(insertion.value, segmenter3);
|
|
128184
128670
|
insertion.value = insertion.value.substring(ws.length);
|
|
128185
128671
|
}
|
|
128186
128672
|
if (endKeep) {
|
|
128187
|
-
const ws = leadingWs(endKeep.value,
|
|
128673
|
+
const ws = leadingWs(endKeep.value, segmenter3);
|
|
128188
128674
|
endKeep.value = endKeep.value.substring(ws.length);
|
|
128189
128675
|
}
|
|
128190
128676
|
} else if (startKeep && endKeep) {
|
|
128191
|
-
const newWsFull = leadingWs(endKeep.value,
|
|
128677
|
+
const newWsFull = leadingWs(endKeep.value, segmenter3), [delWsStart, delWsEnd] = leadingAndTrailingWs(deletion.value, segmenter3);
|
|
128192
128678
|
const newWsStart = longestCommonPrefix(newWsFull, delWsStart);
|
|
128193
128679
|
deletion.value = removePrefix(deletion.value, newWsStart);
|
|
128194
128680
|
const newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd);
|
|
@@ -128196,13 +128682,13 @@ function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep
|
|
|
128196
128682
|
endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd);
|
|
128197
128683
|
startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length));
|
|
128198
128684
|
} else if (endKeep) {
|
|
128199
|
-
const endKeepWsPrefix = leadingWs(endKeep.value,
|
|
128200
|
-
const deletionWsSuffix = trailingWs(deletion.value,
|
|
128685
|
+
const endKeepWsPrefix = leadingWs(endKeep.value, segmenter3);
|
|
128686
|
+
const deletionWsSuffix = trailingWs(deletion.value, segmenter3);
|
|
128201
128687
|
const overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix);
|
|
128202
128688
|
deletion.value = removeSuffix(deletion.value, overlap);
|
|
128203
128689
|
} else if (startKeep) {
|
|
128204
|
-
const startKeepWsSuffix = trailingWs(startKeep.value,
|
|
128205
|
-
const deletionWsPrefix = leadingWs(deletion.value,
|
|
128690
|
+
const startKeepWsSuffix = trailingWs(startKeep.value, segmenter3);
|
|
128691
|
+
const deletionWsPrefix = leadingWs(deletion.value, segmenter3);
|
|
128206
128692
|
const overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix);
|
|
128207
128693
|
deletion.value = removePrefix(deletion.value, overlap);
|
|
128208
128694
|
}
|
|
@@ -129532,6 +130018,7 @@ function processProxyEvent(proxyEvent, partial) {
|
|
|
129532
130018
|
case "toolcall_end": {
|
|
129533
130019
|
const content = partial.content[proxyEvent.contentIndex];
|
|
129534
130020
|
if (content?.type === "toolCall") {
|
|
130021
|
+
Object.assign(content, proxyEvent.toolCall);
|
|
129535
130022
|
delete content.partialJson;
|
|
129536
130023
|
return {
|
|
129537
130024
|
type: "toolcall_end",
|
|
@@ -129558,6 +130045,108 @@ function processProxyEvent(proxyEvent, partial) {
|
|
|
129558
130045
|
}
|
|
129559
130046
|
}
|
|
129560
130047
|
}
|
|
130048
|
+
// node_modules/@earendil-works/pi-agent-core/dist/search/scanning.js
|
|
130049
|
+
function defaultSearchText(_metadata, entry, label) {
|
|
130050
|
+
return label === undefined ? JSON.stringify(entry) : `${JSON.stringify(entry)} ${label}`;
|
|
130051
|
+
}
|
|
130052
|
+
async function* scanReadableEntries(readable, metadata, options, query = {}) {
|
|
130053
|
+
const projectText = options.projectText ?? defaultSearchText;
|
|
130054
|
+
const pageSize = query.limit ?? options.pageSize ?? 100;
|
|
130055
|
+
let afterSeq = query.afterSeq ?? 0;
|
|
130056
|
+
const entryTypes = query.entryTypes === undefined ? undefined : new Set(query.entryTypes);
|
|
130057
|
+
while (true) {
|
|
130058
|
+
const entries = await readable.findEntries({
|
|
130059
|
+
order: "oldestFirst",
|
|
130060
|
+
limit: pageSize,
|
|
130061
|
+
cursor: { afterSeq },
|
|
130062
|
+
type: query.entryTypes?.length === 1 ? query.entryTypes[0] : undefined
|
|
130063
|
+
});
|
|
130064
|
+
if (entries.length === 0)
|
|
130065
|
+
break;
|
|
130066
|
+
for (const entry of entries) {
|
|
130067
|
+
if (entryTypes !== undefined && !entryTypes.has(entry.type))
|
|
130068
|
+
continue;
|
|
130069
|
+
const label = await readable.getLabel(entry.id);
|
|
130070
|
+
yield {
|
|
130071
|
+
entryId: entry.id,
|
|
130072
|
+
seq: entry.seq,
|
|
130073
|
+
type: entry.type,
|
|
130074
|
+
timestamp: entry.timestamp,
|
|
130075
|
+
text: projectText(metadata, entry, label),
|
|
130076
|
+
fields: label === undefined ? undefined : { label }
|
|
130077
|
+
};
|
|
130078
|
+
}
|
|
130079
|
+
afterSeq = entries[entries.length - 1]?.seq ?? afterSeq;
|
|
130080
|
+
if (entries.length < pageSize)
|
|
130081
|
+
break;
|
|
130082
|
+
}
|
|
130083
|
+
}
|
|
130084
|
+
async function* scanningEntries(readable, options = {}) {
|
|
130085
|
+
yield* scanReadableEntries(readable, await readable.getMetadata(), options);
|
|
130086
|
+
}
|
|
130087
|
+
async function* arraySource(readables) {
|
|
130088
|
+
yield* readables;
|
|
130089
|
+
}
|
|
130090
|
+
function readablesFor(source, options) {
|
|
130091
|
+
return typeof source === "function" ? source(options) : arraySource(source);
|
|
130092
|
+
}
|
|
130093
|
+
function defaultMatch(queryText, candidate) {
|
|
130094
|
+
return candidate.text.toLowerCase().includes(queryText);
|
|
130095
|
+
}
|
|
130096
|
+
function throwIfAborted(signal) {
|
|
130097
|
+
if (!signal?.aborted)
|
|
130098
|
+
return;
|
|
130099
|
+
if (signal.reason instanceof Error)
|
|
130100
|
+
throw signal.reason;
|
|
130101
|
+
const error = new Error("The operation was aborted");
|
|
130102
|
+
error.name = "AbortError";
|
|
130103
|
+
throw error;
|
|
130104
|
+
}
|
|
130105
|
+
function createDefaultScanningHit(metadata, candidate) {
|
|
130106
|
+
return {
|
|
130107
|
+
sessionId: metadata.id,
|
|
130108
|
+
entryId: candidate.entryId,
|
|
130109
|
+
timestamp: candidate.timestamp,
|
|
130110
|
+
snippet: candidate.text
|
|
130111
|
+
};
|
|
130112
|
+
}
|
|
130113
|
+
function createScanningSessionSearch(source, options = {}) {
|
|
130114
|
+
const createHit = options.createHit ?? ((metadata, candidate) => createDefaultScanningHit(metadata, candidate));
|
|
130115
|
+
return {
|
|
130116
|
+
async* search(text, searchOptions = {}) {
|
|
130117
|
+
const normalizedText = text.trim().toLowerCase();
|
|
130118
|
+
if (!normalizedText || searchOptions.limit !== undefined && searchOptions.limit <= 0)
|
|
130119
|
+
return;
|
|
130120
|
+
if (searchOptions.entryTypes?.length === 0)
|
|
130121
|
+
return;
|
|
130122
|
+
let hitCount = 0;
|
|
130123
|
+
const seenSessionIds = new Set;
|
|
130124
|
+
const entryTypes = searchOptions.entryTypes === undefined ? undefined : new Set(searchOptions.entryTypes);
|
|
130125
|
+
const sourceOptions = options.sourceOptions?.(normalizedText, searchOptions);
|
|
130126
|
+
for await (const readable of readablesFor(source, sourceOptions)) {
|
|
130127
|
+
throwIfAborted(searchOptions.signal);
|
|
130128
|
+
const metadata = await readable.getMetadata();
|
|
130129
|
+
if (seenSessionIds.has(metadata.id))
|
|
130130
|
+
throw new Error(`Duplicate sessionId: ${metadata.id}`);
|
|
130131
|
+
seenSessionIds.add(metadata.id);
|
|
130132
|
+
for await (const candidate of scanReadableEntries(readable, metadata, options, {
|
|
130133
|
+
entryTypes: searchOptions.entryTypes
|
|
130134
|
+
})) {
|
|
130135
|
+
throwIfAborted(searchOptions.signal);
|
|
130136
|
+
if (entryTypes !== undefined && !entryTypes.has(candidate.type))
|
|
130137
|
+
continue;
|
|
130138
|
+
const matches = options.match?.(normalizedText, candidate, metadata) ?? defaultMatch(normalizedText, candidate);
|
|
130139
|
+
if (!matches)
|
|
130140
|
+
continue;
|
|
130141
|
+
yield createHit(metadata, candidate);
|
|
130142
|
+
hitCount += 1;
|
|
130143
|
+
if (searchOptions.limit !== undefined && hitCount >= searchOptions.limit)
|
|
130144
|
+
return;
|
|
130145
|
+
}
|
|
130146
|
+
}
|
|
130147
|
+
}
|
|
130148
|
+
};
|
|
130149
|
+
}
|
|
129561
130150
|
// node_modules/@earendil-works/pi-ai/dist/oauth.js
|
|
129562
130151
|
var exports_oauth = {};
|
|
129563
130152
|
|
|
@@ -132440,7 +133029,8 @@ ${content}
|
|
|
132440
133029
|
prompt2 += formatSkillsForPrompt(skills2);
|
|
132441
133030
|
}
|
|
132442
133031
|
prompt2 += `
|
|
132443
|
-
Current working directory: ${promptCwd}
|
|
133032
|
+
Current working directory: ${promptCwd}
|
|
133033
|
+
`;
|
|
132444
133034
|
return prompt2;
|
|
132445
133035
|
}
|
|
132446
133036
|
const readmePath = getReadmePath();
|
|
@@ -132571,6 +133161,15 @@ function truncateToVisualLines(text, maxVisualLines, width, paddingX = 0) {
|
|
|
132571
133161
|
return { visualLines: truncatedLines, skippedCount };
|
|
132572
133162
|
}
|
|
132573
133163
|
|
|
133164
|
+
// node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js
|
|
133165
|
+
var PREFER_STRICT_TOOL_SAMPLING = { type: "json_schema", strict: "prefer" };
|
|
133166
|
+
function areExperimentalFeaturesEnabled() {
|
|
133167
|
+
return process.env.PI_EXPERIMENTAL === "1";
|
|
133168
|
+
}
|
|
133169
|
+
function getExperimentalToolSampling() {
|
|
133170
|
+
return areExperimentalFeaturesEnabled() ? PREFER_STRICT_TOOL_SAMPLING : undefined;
|
|
133171
|
+
}
|
|
133172
|
+
|
|
132574
133173
|
// node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js
|
|
132575
133174
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
132576
133175
|
import { createWriteStream as createWriteStream2 } from "node:fs";
|
|
@@ -133024,6 +133623,7 @@ function createBashToolDefinition(cwd, options) {
|
|
|
133024
133623
|
promptSnippet: bashToolSystemPromptContribution.snippet,
|
|
133025
133624
|
promptGuidelines: exposeSessionEnvironment ? [...bashToolSystemPromptContribution.guidelines] : undefined,
|
|
133026
133625
|
parameters: bashSchema2,
|
|
133626
|
+
constrainedSampling: getExperimentalToolSampling(),
|
|
133027
133627
|
async execute(_toolCallId, { command, timeout }, signal, onUpdate, ctx) {
|
|
133028
133628
|
const resolvedCommand = commandPrefix ? `${commandPrefix}
|
|
133029
133629
|
${command}` : command;
|
|
@@ -133918,36 +134518,37 @@ function createEditToolDefinition(cwd, options) {
|
|
|
133918
134518
|
promptSnippet: editToolSystemPromptContribution.snippet,
|
|
133919
134519
|
promptGuidelines: [...editToolSystemPromptContribution.guidelines],
|
|
133920
134520
|
parameters: editSchema2,
|
|
134521
|
+
constrainedSampling: getExperimentalToolSampling(),
|
|
133921
134522
|
renderShell: "self",
|
|
133922
134523
|
prepareArguments: prepareEditArguments2,
|
|
133923
134524
|
async execute(_toolCallId, input, signal, _onUpdate, _ctx) {
|
|
133924
134525
|
const { path: path8, edits } = validateEditInput2(input);
|
|
133925
134526
|
const absolutePath = resolveToCwd(path8, cwd);
|
|
133926
134527
|
return withFileMutationQueue2(absolutePath, async () => {
|
|
133927
|
-
const
|
|
134528
|
+
const throwIfAborted2 = () => {
|
|
133928
134529
|
if (signal?.aborted)
|
|
133929
134530
|
throw new Error("Operation aborted");
|
|
133930
134531
|
};
|
|
133931
|
-
|
|
134532
|
+
throwIfAborted2();
|
|
133932
134533
|
try {
|
|
133933
134534
|
await ops.access(absolutePath);
|
|
133934
134535
|
} catch (error) {
|
|
133935
|
-
|
|
134536
|
+
throwIfAborted2();
|
|
133936
134537
|
const errorMessage = error instanceof Error && "code" in error ? `Error code: ${error.code}` : String(error);
|
|
133937
134538
|
throw new Error(`Could not edit file: ${path8}. ${errorMessage}.`);
|
|
133938
134539
|
}
|
|
133939
|
-
|
|
134540
|
+
throwIfAborted2();
|
|
133940
134541
|
const buffer = await ops.readFile(absolutePath);
|
|
133941
134542
|
const rawContent = buffer.toString("utf-8");
|
|
133942
|
-
|
|
134543
|
+
throwIfAborted2();
|
|
133943
134544
|
const { bom, text: content } = stripBom2(rawContent);
|
|
133944
134545
|
const originalEnding = detectLineEnding2(content);
|
|
133945
134546
|
const normalizedContent = normalizeToLF2(content);
|
|
133946
134547
|
const { baseContent, newContent } = applyEditsToNormalizedContent2(normalizedContent, edits, path8);
|
|
133947
|
-
|
|
134548
|
+
throwIfAborted2();
|
|
133948
134549
|
const finalContent = bom + restoreLineEndings2(newContent, originalEnding);
|
|
133949
134550
|
await ops.writeFile(absolutePath, finalContent);
|
|
133950
|
-
|
|
134551
|
+
throwIfAborted2();
|
|
133951
134552
|
const diffResult = generateDiffString2(baseContent, newContent);
|
|
133952
134553
|
const patch = generateUnifiedPatch2(path8, baseContent, newContent);
|
|
133953
134554
|
return {
|
|
@@ -134023,7 +134624,6 @@ import { spawn as spawn5 } from "child_process";
|
|
|
134023
134624
|
import path8 from "path";
|
|
134024
134625
|
|
|
134025
134626
|
// node_modules/@earendil-works/pi-coding-agent/dist/utils/tools-manager.js
|
|
134026
|
-
init_source();
|
|
134027
134627
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
134028
134628
|
import { chmodSync, createWriteStream as createWriteStream3, existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync as readdirSync7, renameSync, rmSync } from "fs";
|
|
134029
134629
|
import { arch, platform } from "os";
|
|
@@ -134300,7 +134900,7 @@ var TERMUX_PACKAGES = {
|
|
|
134300
134900
|
fd: "fd",
|
|
134301
134901
|
rg: "ripgrep"
|
|
134302
134902
|
};
|
|
134303
|
-
async function ensureTool(tool,
|
|
134903
|
+
async function ensureTool(tool, onStatus) {
|
|
134304
134904
|
const existingPath = getToolPath(tool);
|
|
134305
134905
|
if (existingPath) {
|
|
134306
134906
|
return existingPath;
|
|
@@ -134309,31 +134909,24 @@ async function ensureTool(tool, silent = false) {
|
|
|
134309
134909
|
if (!config)
|
|
134310
134910
|
return;
|
|
134311
134911
|
if (isOfflineModeEnabled()) {
|
|
134312
|
-
|
|
134313
|
-
console.log(source_default.yellow(`${config.name} not found. Offline mode enabled, skipping download.`));
|
|
134314
|
-
}
|
|
134912
|
+
onStatus?.({ type: "warning", message: `${config.name} not found. Offline mode enabled, skipping download.` });
|
|
134315
134913
|
return;
|
|
134316
134914
|
}
|
|
134317
134915
|
if (platform() === "android") {
|
|
134318
134916
|
const pkgName = TERMUX_PACKAGES[tool] ?? tool;
|
|
134319
|
-
|
|
134320
|
-
console.log(source_default.yellow(`${config.name} not found. Install with: pkg install ${pkgName}`));
|
|
134321
|
-
}
|
|
134917
|
+
onStatus?.({ type: "warning", message: `${config.name} not found. Install with: pkg install ${pkgName}` });
|
|
134322
134918
|
return;
|
|
134323
134919
|
}
|
|
134324
|
-
|
|
134325
|
-
console.log(source_default.dim(`${config.name} not found. Downloading...`));
|
|
134326
|
-
}
|
|
134920
|
+
onStatus?.({ type: "info", message: `${config.name} not found. Downloading...` });
|
|
134327
134921
|
try {
|
|
134328
134922
|
const path8 = await downloadTool(tool);
|
|
134329
|
-
|
|
134330
|
-
console.log(source_default.dim(`${config.name} installed to ${path8}`));
|
|
134331
|
-
}
|
|
134923
|
+
onStatus?.({ type: "info", message: `${config.name} installed to ${path8}` });
|
|
134332
134924
|
return path8;
|
|
134333
134925
|
} catch (e) {
|
|
134334
|
-
|
|
134335
|
-
|
|
134336
|
-
|
|
134926
|
+
onStatus?.({
|
|
134927
|
+
type: "warning",
|
|
134928
|
+
message: `Failed to download ${config.name}: ${e instanceof Error ? e.message : e}`
|
|
134929
|
+
});
|
|
134337
134930
|
return;
|
|
134338
134931
|
}
|
|
134339
134932
|
}
|
|
@@ -134488,7 +135081,7 @@ function createFindToolDefinition(cwd, options) {
|
|
|
134488
135081
|
}));
|
|
134489
135082
|
return;
|
|
134490
135083
|
}
|
|
134491
|
-
const fdPath = await ensureTool("fd"
|
|
135084
|
+
const fdPath = await ensureTool("fd");
|
|
134492
135085
|
if (signal?.aborted) {
|
|
134493
135086
|
settle(() => reject(new Error("Operation aborted")));
|
|
134494
135087
|
return;
|
|
@@ -134717,7 +135310,7 @@ function createGrepToolDefinition(cwd, options) {
|
|
|
134717
135310
|
};
|
|
134718
135311
|
(async () => {
|
|
134719
135312
|
try {
|
|
134720
|
-
const rgPath = await ensureTool("rg"
|
|
135313
|
+
const rgPath = await ensureTool("rg");
|
|
134721
135314
|
if (!rgPath) {
|
|
134722
135315
|
settle(() => reject(new Error("ripgrep (rg) is not available and could not be downloaded")));
|
|
134723
135316
|
return;
|
|
@@ -135312,6 +135905,7 @@ function createReadToolDefinition(cwd, options) {
|
|
|
135312
135905
|
promptSnippet: readToolSystemPromptContribution.snippet,
|
|
135313
135906
|
promptGuidelines: [...readToolSystemPromptContribution.guidelines],
|
|
135314
135907
|
parameters: readSchema2,
|
|
135908
|
+
constrainedSampling: getExperimentalToolSampling(),
|
|
135315
135909
|
async execute(_toolCallId, { path: path10, offset, limit }, signal, _onUpdate, ctx) {
|
|
135316
135910
|
return new Promise((resolve7, reject) => {
|
|
135317
135911
|
if (signal?.aborted) {
|
|
@@ -135583,19 +136177,20 @@ function createWriteToolDefinition(cwd, options) {
|
|
|
135583
136177
|
promptSnippet: writeToolSystemPromptContribution.snippet,
|
|
135584
136178
|
promptGuidelines: [...writeToolSystemPromptContribution.guidelines],
|
|
135585
136179
|
parameters: writeSchema2,
|
|
136180
|
+
constrainedSampling: getExperimentalToolSampling(),
|
|
135586
136181
|
async execute(_toolCallId, { path: path10, content }, signal, _onUpdate, _ctx) {
|
|
135587
136182
|
const absolutePath = resolveToCwd(path10, cwd);
|
|
135588
136183
|
const dir = dirname11(absolutePath);
|
|
135589
136184
|
return withFileMutationQueue2(absolutePath, async () => {
|
|
135590
|
-
const
|
|
136185
|
+
const throwIfAborted2 = () => {
|
|
135591
136186
|
if (signal?.aborted)
|
|
135592
136187
|
throw new Error("Operation aborted");
|
|
135593
136188
|
};
|
|
135594
|
-
|
|
136189
|
+
throwIfAborted2();
|
|
135595
136190
|
await ops.mkdir(dir);
|
|
135596
|
-
|
|
136191
|
+
throwIfAborted2();
|
|
135597
136192
|
await ops.writeFile(absolutePath, content);
|
|
135598
|
-
|
|
136193
|
+
throwIfAborted2();
|
|
135599
136194
|
return {
|
|
135600
136195
|
content: [{ type: "text", text: `Successfully wrote ${content.length} bytes to ${path10}` }],
|
|
135601
136196
|
details: undefined
|
|
@@ -136515,7 +137110,7 @@ ${args}` : skillBlock;
|
|
|
136515
137110
|
};
|
|
136516
137111
|
if (options?.deliverAs === "nextTurn") {
|
|
136517
137112
|
this._pendingNextTurnMessages.push(appMessage);
|
|
136518
|
-
} else if (this.isStreaming) {
|
|
137113
|
+
} else if (this.isStreaming && options?.triggerTurn !== false) {
|
|
136519
137114
|
if (options?.deliverAs === "followUp") {
|
|
136520
137115
|
this.agent.followUp(appMessage);
|
|
136521
137116
|
} else {
|
|
@@ -136551,7 +137146,7 @@ ${args}` : skillBlock;
|
|
|
136551
137146
|
images = undefined;
|
|
136552
137147
|
}
|
|
136553
137148
|
await this.prompt(text, {
|
|
136554
|
-
expandPromptTemplates: false,
|
|
137149
|
+
expandPromptTemplates: options?.expandPromptTemplates ?? false,
|
|
136555
137150
|
streamingBehavior: options?.deliverAs,
|
|
136556
137151
|
images,
|
|
136557
137152
|
source: "extension"
|
|
@@ -137714,9 +138309,8 @@ ${command}` : command;
|
|
|
137714
138309
|
percent
|
|
137715
138310
|
};
|
|
137716
138311
|
}
|
|
137717
|
-
async exportToHtml(outputPath) {
|
|
137718
|
-
const
|
|
137719
|
-
const themeName = configuredThemeName && getThemeByName(configuredThemeName) ? configuredThemeName : undefined;
|
|
138312
|
+
async exportToHtml(outputPath, options = {}) {
|
|
138313
|
+
const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
|
|
137720
138314
|
const toolRenderer = createToolHtmlRenderer({
|
|
137721
138315
|
getToolDefinition: (name) => this.getToolDefinition(name),
|
|
137722
138316
|
theme,
|
|
@@ -140412,6 +141006,7 @@ var OpenAIResponsesCompatSchema = exports_typebox.Object({
|
|
|
140412
141006
|
supportsLongCacheRetention: exports_typebox.Optional(exports_typebox.Boolean()),
|
|
140413
141007
|
supportsStrictMode: exports_typebox.Optional(exports_typebox.Boolean()),
|
|
140414
141008
|
supportsOpenAIGrammarTools: exports_typebox.Optional(exports_typebox.Boolean()),
|
|
141009
|
+
supportsAdditionalTools: exports_typebox.Optional(exports_typebox.Boolean()),
|
|
140415
141010
|
supportsToolSearch: exports_typebox.Optional(exports_typebox.Boolean())
|
|
140416
141011
|
});
|
|
140417
141012
|
var AnthropicMessagesCompatSchema = exports_typebox.Object({
|
|
@@ -148268,6 +148863,14 @@ class SettingsManager {
|
|
|
148268
148863
|
this.markModified("tuiMode");
|
|
148269
148864
|
this.save();
|
|
148270
148865
|
}
|
|
148866
|
+
getFullscreenExitOutput() {
|
|
148867
|
+
return this.settings.fullscreenExitOutput === "resume-hint" ? "resume-hint" : "transcript";
|
|
148868
|
+
}
|
|
148869
|
+
setFullscreenExitOutput(output) {
|
|
148870
|
+
this.globalSettings.fullscreenExitOutput = output;
|
|
148871
|
+
this.markModified("fullscreenExitOutput");
|
|
148872
|
+
this.save();
|
|
148873
|
+
}
|
|
148271
148874
|
getFullscreenScrollbar() {
|
|
148272
148875
|
const mode = this.settings.fullscreenScrollbar;
|
|
148273
148876
|
return mode === "always" || mode === "hidden" ? mode : "auto";
|
|
@@ -148302,6 +148905,10 @@ class SettingsManager {
|
|
|
148302
148905
|
getEnabledModels() {
|
|
148303
148906
|
return this.settings.enabledModels;
|
|
148304
148907
|
}
|
|
148908
|
+
getDefaultTools() {
|
|
148909
|
+
const tools2 = this.settings.defaultTools;
|
|
148910
|
+
return tools2 ? [...tools2] : undefined;
|
|
148911
|
+
}
|
|
148305
148912
|
setEnabledModels(patterns) {
|
|
148306
148913
|
this.globalSettings.enabledModels = patterns;
|
|
148307
148914
|
this.markModified("enabledModels");
|
|
@@ -149729,10 +150336,11 @@ async function createAgentSession(options = {}) {
|
|
|
149729
150336
|
thinkingLevel = clampThinkingLevel(model, thinkingLevel);
|
|
149730
150337
|
}
|
|
149731
150338
|
const defaultActiveToolNames = ["read", "bash", "edit", "write"];
|
|
150339
|
+
const configuredDefaultToolNames = settingsManager.getDefaultTools();
|
|
149732
150340
|
const allowedToolNames = options.tools ?? (options.noTools === "all" ? [] : undefined);
|
|
149733
150341
|
const excludedToolNames = options.excludeTools;
|
|
149734
150342
|
const excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;
|
|
149735
|
-
const initialActiveToolNames = (options.tools
|
|
150343
|
+
const initialActiveToolNames = (options.tools ?? (options.noTools ? [] : configuredDefaultToolNames ?? defaultActiveToolNames)).filter((name) => !excludedToolNameSet?.has(name));
|
|
149736
150344
|
let agent2;
|
|
149737
150345
|
const convertToLlmWithBlockImages = (messages2) => {
|
|
149738
150346
|
const converted = convertToLlm(messages2);
|
|
@@ -150040,9 +150648,9 @@ init_source();
|
|
|
150040
150648
|
class AuthCommandError extends Error {
|
|
150041
150649
|
}
|
|
150042
150650
|
var AUTH_COMMAND_USAGE = {
|
|
150043
|
-
check:
|
|
150044
|
-
api_key:
|
|
150045
|
-
bearer_token:
|
|
150651
|
+
check: `${APP_NAME} auth check --provider <provider> [--json] [--credentials] [--no-refresh]`,
|
|
150652
|
+
api_key: `${APP_NAME} auth print-api-key --provider <provider> [--model <model>]`,
|
|
150653
|
+
bearer_token: `${APP_NAME} auth print-bearer-token --provider <provider> [--model <model>] [--min-expiry <duration>]`
|
|
150046
150654
|
};
|
|
150047
150655
|
function getAuthCommandName(kind) {
|
|
150048
150656
|
return kind === "check" ? "auth check" : kind === "api_key" ? "auth print-api-key" : "auth print-bearer-token";
|
|
@@ -150066,7 +150674,7 @@ function parseAuthCommand(args) {
|
|
|
150066
150674
|
return;
|
|
150067
150675
|
const kind = args[1] === "check" ? "check" : args[1] === "print-api-key" ? "api_key" : args[1] === "print-bearer-token" ? "bearer_token" : undefined;
|
|
150068
150676
|
if (!kind) {
|
|
150069
|
-
throw new AuthCommandError(`Unknown auth command "${args[1] ?? ""}". Use "
|
|
150677
|
+
throw new AuthCommandError(`Unknown auth command "${args[1] ?? ""}". Use "${APP_NAME} auth print-api-key", "${APP_NAME} auth print-bearer-token", or "${APP_NAME} auth check".`);
|
|
150070
150678
|
}
|
|
150071
150679
|
const commandArgs = [];
|
|
150072
150680
|
let json = false;
|
|
@@ -150410,11 +151018,6 @@ init_source();
|
|
|
150410
151018
|
// node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js
|
|
150411
151019
|
import { existsSync as existsSync20 } from "fs";
|
|
150412
151020
|
|
|
150413
|
-
// node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js
|
|
150414
|
-
function areExperimentalFeaturesEnabled() {
|
|
150415
|
-
return process.env.PI_EXPERIMENTAL === "1";
|
|
150416
|
-
}
|
|
150417
|
-
|
|
150418
151021
|
// node_modules/@earendil-works/pi-coding-agent/dist/core/keybindings.js
|
|
150419
151022
|
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
|
|
150420
151023
|
import { join as join30 } from "path";
|
|
@@ -152124,7 +152727,7 @@ function formatProjectTrustPrompt(cwd) {
|
|
|
152124
152727
|
return `Trust project folder?
|
|
152125
152728
|
${cwd}
|
|
152126
152729
|
|
|
152127
|
-
This allows
|
|
152730
|
+
This allows ${APP_NAME} to load ${CONFIG_DIR_NAME} settings and resources, install missing project packages, and execute project extensions.`;
|
|
152128
152731
|
}
|
|
152129
152732
|
async function selectProjectTrustOption(cwd, ctx) {
|
|
152130
152733
|
const options = getProjectTrustOptions(cwd, { includeSessionOnly: true });
|
|
@@ -156824,7 +157427,7 @@ var WIDTHS = [
|
|
|
156824
157427
|
];
|
|
156825
157428
|
|
|
156826
157429
|
// node_modules/grok-mermaid/dist/width.js
|
|
156827
|
-
var
|
|
157430
|
+
var segmenter3 = new Intl.Segmenter("en", { granularity: "grapheme" });
|
|
156828
157431
|
var VS16 = 65039;
|
|
156829
157432
|
var isRegionalIndicator = (cp) => cp >= 127462 && cp <= 127487;
|
|
156830
157433
|
function codePointWidth(cp) {
|
|
@@ -156859,12 +157462,12 @@ function clusterWidth(cluster) {
|
|
|
156859
157462
|
return vs16 || regional >= 2 ? 2 : w2;
|
|
156860
157463
|
}
|
|
156861
157464
|
function* measured(s) {
|
|
156862
|
-
for (const { segment: segment2 } of
|
|
157465
|
+
for (const { segment: segment2 } of segmenter3.segment(s))
|
|
156863
157466
|
yield [segment2, clusterWidth(segment2)];
|
|
156864
157467
|
}
|
|
156865
157468
|
function stringWidth(s) {
|
|
156866
157469
|
let w2 = 0;
|
|
156867
|
-
for (const { segment: segment2 } of
|
|
157470
|
+
for (const { segment: segment2 } of segmenter3.segment(s))
|
|
156868
157471
|
w2 += clusterWidth(segment2);
|
|
156869
157472
|
return w2;
|
|
156870
157473
|
}
|
|
@@ -159537,6 +160140,39 @@ ${codeSpan(styledWarning)}
|
|
|
159537
160140
|
};
|
|
159538
160141
|
}
|
|
159539
160142
|
|
|
160143
|
+
// node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/model-catalog-refresh.js
|
|
160144
|
+
class ModelCatalogRefreshCoordinator {
|
|
160145
|
+
activeByRuntime = new WeakMap;
|
|
160146
|
+
refresh(modelRuntime, signal) {
|
|
160147
|
+
signal.throwIfAborted();
|
|
160148
|
+
let active = this.activeByRuntime.get(modelRuntime);
|
|
160149
|
+
if (!active) {
|
|
160150
|
+
const controller = new AbortController;
|
|
160151
|
+
let created;
|
|
160152
|
+
const operation = modelRuntime.refresh({ signal: controller.signal });
|
|
160153
|
+
const promise = raceWithAbortSignal(operation, controller.signal).finally(() => {
|
|
160154
|
+
if (this.activeByRuntime.get(modelRuntime) === created) {
|
|
160155
|
+
this.activeByRuntime.delete(modelRuntime);
|
|
160156
|
+
}
|
|
160157
|
+
});
|
|
160158
|
+
created = { controller, promise, waiters: 0 };
|
|
160159
|
+
active = created;
|
|
160160
|
+
this.activeByRuntime.set(modelRuntime, active);
|
|
160161
|
+
}
|
|
160162
|
+
active.waiters++;
|
|
160163
|
+
return raceWithAbortSignal(active.promise, signal).finally(() => {
|
|
160164
|
+
active.waiters--;
|
|
160165
|
+
if (active.waiters === 0 && this.activeByRuntime.get(modelRuntime) === active) {
|
|
160166
|
+
active.controller.abort();
|
|
160167
|
+
}
|
|
160168
|
+
});
|
|
160169
|
+
}
|
|
160170
|
+
}
|
|
160171
|
+
var modelCatalogRefreshCoordinator = new ModelCatalogRefreshCoordinator;
|
|
160172
|
+
function refreshModelCatalogs(modelRuntime, signal) {
|
|
160173
|
+
return modelCatalogRefreshCoordinator.refresh(modelRuntime, signal);
|
|
160174
|
+
}
|
|
160175
|
+
|
|
159540
160176
|
// node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/model-search.js
|
|
159541
160177
|
function getModelSearchText(item) {
|
|
159542
160178
|
const { id, provider } = item;
|
|
@@ -159656,7 +160292,7 @@ class ModelSelectorComponent extends Container {
|
|
|
159656
160292
|
this.refreshAbortController.abort();
|
|
159657
160293
|
}, timeoutMs);
|
|
159658
160294
|
try {
|
|
159659
|
-
const result2 = await this.modelRuntime
|
|
160295
|
+
const result2 = await refreshModelCatalogs(this.modelRuntime, this.refreshAbortController.signal);
|
|
159660
160296
|
if (this.closed)
|
|
159661
160297
|
return;
|
|
159662
160298
|
this.refreshStatusMessage = "";
|
|
@@ -160635,6 +161271,13 @@ class SettingsSelectorComponent extends Container {
|
|
|
160635
161271
|
currentValue: config.tuiMode,
|
|
160636
161272
|
values: ["regular", "fullscreen"]
|
|
160637
161273
|
},
|
|
161274
|
+
{
|
|
161275
|
+
id: "fullscreen-exit-output",
|
|
161276
|
+
label: "Fullscreen exit output",
|
|
161277
|
+
description: "Print the transcript or only a session resume hint when exiting fullscreen mode",
|
|
161278
|
+
currentValue: config.fullscreenExitOutput,
|
|
161279
|
+
values: ["transcript", "resume-hint"]
|
|
161280
|
+
},
|
|
160638
161281
|
{
|
|
160639
161282
|
id: "fullscreen-scrollbar",
|
|
160640
161283
|
label: "Fullscreen scrollbar",
|
|
@@ -160826,6 +161469,9 @@ class SettingsSelectorComponent extends Container {
|
|
|
160826
161469
|
case "tui-mode":
|
|
160827
161470
|
callbacks.onTuiModeChange(newValue);
|
|
160828
161471
|
break;
|
|
161472
|
+
case "fullscreen-exit-output":
|
|
161473
|
+
callbacks.onFullscreenExitOutputChange(newValue);
|
|
161474
|
+
break;
|
|
160829
161475
|
case "fullscreen-scrollbar":
|
|
160830
161476
|
callbacks.onFullscreenScrollbarChange(newValue);
|
|
160831
161477
|
break;
|
|
@@ -160938,6 +161584,8 @@ class IdleStatus {
|
|
|
160938
161584
|
}
|
|
160939
161585
|
|
|
160940
161586
|
// node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js
|
|
161587
|
+
var FALLBACK_PREVIEW_LINES = 10;
|
|
161588
|
+
|
|
160941
161589
|
class ToolExecutionComponent extends Container {
|
|
160942
161590
|
contentBox;
|
|
160943
161591
|
contentText;
|
|
@@ -161042,7 +161690,17 @@ class ToolExecutionComponent extends Container {
|
|
|
161042
161690
|
if (!output) {
|
|
161043
161691
|
return;
|
|
161044
161692
|
}
|
|
161045
|
-
|
|
161693
|
+
const lines = output.split(`
|
|
161694
|
+
`);
|
|
161695
|
+
const displayLines = this.expanded ? lines : lines.slice(0, FALLBACK_PREVIEW_LINES);
|
|
161696
|
+
const remaining = lines.length - displayLines.length;
|
|
161697
|
+
let text = displayLines.map((line) => theme.fg("toolOutput", line)).join(`
|
|
161698
|
+
`);
|
|
161699
|
+
if (remaining > 0) {
|
|
161700
|
+
text += `${theme.fg("muted", `
|
|
161701
|
+
... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
161702
|
+
}
|
|
161703
|
+
return new Text(text, 0, 0);
|
|
161046
161704
|
}
|
|
161047
161705
|
updateArgs(args) {
|
|
161048
161706
|
this.args = args;
|
|
@@ -162496,19 +163154,21 @@ class UserMessageSelectorComponent extends Container {
|
|
|
162496
163154
|
// node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme-controller.js
|
|
162497
163155
|
class InteractiveThemeController {
|
|
162498
163156
|
ui;
|
|
162499
|
-
|
|
163157
|
+
getSettingsManager;
|
|
162500
163158
|
showError;
|
|
162501
163159
|
onChanged;
|
|
163160
|
+
currentThemeSetting;
|
|
162502
163161
|
terminalTheme = detectTerminalBackgroundFromEnv().theme;
|
|
162503
163162
|
activeThemeName;
|
|
162504
163163
|
autoSyncEnabled = false;
|
|
162505
163164
|
terminalColorSchemeUnsubscribe;
|
|
162506
|
-
constructor(ui2,
|
|
163165
|
+
constructor(ui2, options) {
|
|
162507
163166
|
this.ui = ui2;
|
|
162508
|
-
this.
|
|
162509
|
-
this.showError = showError;
|
|
162510
|
-
this.onChanged = onChanged;
|
|
162511
|
-
this.
|
|
163167
|
+
this.getSettingsManager = options.getSettingsManager;
|
|
163168
|
+
this.showError = options.showError;
|
|
163169
|
+
this.onChanged = options.onChanged;
|
|
163170
|
+
this.currentThemeSetting = options.initialThemeSetting;
|
|
163171
|
+
this.activeThemeName = resolveThemeSetting(this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting(), this.terminalTheme);
|
|
162512
163172
|
initTheme(this.activeThemeName, true);
|
|
162513
163173
|
this.bindTerminalColorSchemeListener();
|
|
162514
163174
|
}
|
|
@@ -162518,7 +163178,8 @@ class InteractiveThemeController {
|
|
|
162518
163178
|
this.ui.setTerminalColorSchemeNotifications(this.autoSyncEnabled);
|
|
162519
163179
|
}
|
|
162520
163180
|
async applyFromSettings() {
|
|
162521
|
-
const
|
|
163181
|
+
const settingsManager = this.getSettingsManager();
|
|
163182
|
+
const themeSetting = this.currentThemeSetting ?? settingsManager.getThemeSetting();
|
|
162522
163183
|
const autoTheme = parseAutoThemeSetting(themeSetting);
|
|
162523
163184
|
if (autoTheme) {
|
|
162524
163185
|
this.terminalTheme = await detectTerminalThemeForAuto({ ui: this.ui, timeoutMs: 100 });
|
|
@@ -162536,13 +163197,24 @@ class InteractiveThemeController {
|
|
|
162536
163197
|
if (!this.applyThemeName(detection.theme).success)
|
|
162537
163198
|
return;
|
|
162538
163199
|
if (detection.confidence === "high") {
|
|
162539
|
-
|
|
162540
|
-
await
|
|
163200
|
+
settingsManager.setTheme(detection.theme);
|
|
163201
|
+
await settingsManager.flush();
|
|
162541
163202
|
}
|
|
162542
163203
|
}
|
|
163204
|
+
getThemeSelection() {
|
|
163205
|
+
return this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting() ?? this.activeThemeName;
|
|
163206
|
+
}
|
|
162543
163207
|
setThemeName(themeName, showError = false) {
|
|
162544
163208
|
this.setAutoSync(false);
|
|
162545
|
-
|
|
163209
|
+
const result2 = this.applyThemeName(themeName, showError);
|
|
163210
|
+
if (result2.success) {
|
|
163211
|
+
this.currentThemeSetting = themeName;
|
|
163212
|
+
}
|
|
163213
|
+
return result2;
|
|
163214
|
+
}
|
|
163215
|
+
async setThemeSetting(themeSetting) {
|
|
163216
|
+
this.currentThemeSetting = themeSetting;
|
|
163217
|
+
await this.applyFromSettings();
|
|
162546
163218
|
}
|
|
162547
163219
|
setThemeInstance(themeInstance) {
|
|
162548
163220
|
this.setAutoSync(false);
|
|
@@ -162593,7 +163265,7 @@ Fell back to dark theme.`);
|
|
|
162593
163265
|
if (!this.autoSyncEnabled)
|
|
162594
163266
|
return;
|
|
162595
163267
|
this.terminalTheme = terminalTheme;
|
|
162596
|
-
const autoTheme = parseAutoThemeSetting(this.
|
|
163268
|
+
const autoTheme = parseAutoThemeSetting(this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting());
|
|
162597
163269
|
if (!autoTheme) {
|
|
162598
163270
|
this.setAutoSync(false);
|
|
162599
163271
|
return;
|
|
@@ -162701,9 +163373,20 @@ function formatLoginProviderCompletionDescription(provider) {
|
|
|
162701
163373
|
function createInteractiveTui(options) {
|
|
162702
163374
|
const terminal = options.terminal ?? new ProcessTerminal;
|
|
162703
163375
|
if (options.tuiMode === "fullscreen") {
|
|
163376
|
+
const styleSearchMatch = (text) => theme.bg("searchMatchBg", theme.fg("searchMatchText", text));
|
|
162704
163377
|
return new TuiAltScreen(terminal, options.showHardwareCursor, options.logDirectory, {
|
|
163378
|
+
searchMatchStyle: (text) => theme.underline(styleSearchMatch(text)),
|
|
163379
|
+
searchCurrentMatchStyle: (text) => theme.bold(theme.inverse(styleSearchMatch(text))),
|
|
162705
163380
|
openUrl: openBrowser,
|
|
162706
|
-
onRightClickPaste: options.onRightClickPaste
|
|
163381
|
+
onRightClickPaste: options.onRightClickPaste,
|
|
163382
|
+
copySelection: async (text) => {
|
|
163383
|
+
try {
|
|
163384
|
+
await copyToClipboard(text);
|
|
163385
|
+
return true;
|
|
163386
|
+
} catch {
|
|
163387
|
+
return false;
|
|
163388
|
+
}
|
|
163389
|
+
}
|
|
162707
163390
|
});
|
|
162708
163391
|
}
|
|
162709
163392
|
return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
|
|
@@ -162783,6 +163466,7 @@ class InteractiveMode {
|
|
|
162783
163466
|
anthropicSubscriptionWarningShown = false;
|
|
162784
163467
|
lastStatusSpacer = undefined;
|
|
162785
163468
|
lastStatusText = undefined;
|
|
163469
|
+
managedToolStatusStarted = false;
|
|
162786
163470
|
streamingComponent = undefined;
|
|
162787
163471
|
streamingMessage = undefined;
|
|
162788
163472
|
pendingTools = new Map;
|
|
@@ -162843,6 +163527,7 @@ class InteractiveMode {
|
|
|
162843
163527
|
});
|
|
162844
163528
|
this.runtimeHost.setRebindSession(async () => {
|
|
162845
163529
|
await this.rebindCurrentSession({ renderBeforeBind: true });
|
|
163530
|
+
await this.themeController.applyFromSettings();
|
|
162846
163531
|
});
|
|
162847
163532
|
this.version = VERSION;
|
|
162848
163533
|
this.renderer = createInteractiveTui({
|
|
@@ -162883,7 +163568,12 @@ class InteractiveMode {
|
|
|
162883
163568
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
162884
163569
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
162885
163570
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
162886
|
-
this.themeController = new InteractiveThemeController(this.ui,
|
|
163571
|
+
this.themeController = new InteractiveThemeController(this.ui, {
|
|
163572
|
+
getSettingsManager: () => this.settingsManager,
|
|
163573
|
+
showError: (message) => this.showError(message),
|
|
163574
|
+
onChanged: () => this.updateEditorBorderColor(),
|
|
163575
|
+
initialThemeSetting: options.initialThemeSetting
|
|
163576
|
+
});
|
|
162887
163577
|
}
|
|
162888
163578
|
getAutocompleteSourceTag(sourceInfo) {
|
|
162889
163579
|
if (!sourceInfo) {
|
|
@@ -163030,14 +163720,14 @@ class InteractiveMode {
|
|
|
163030
163720
|
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
163031
163721
|
}
|
|
163032
163722
|
}
|
|
163033
|
-
stopInteractiveTui() {
|
|
163034
|
-
if (this.renderer.mode === "fullscreen") {
|
|
163723
|
+
stopInteractiveTui(fullscreenExitOutput) {
|
|
163724
|
+
if (this.renderer.mode === "fullscreen" && fullscreenExitOutput === "transcript") {
|
|
163035
163725
|
while (this.renderer.hasOverlayEntries)
|
|
163036
163726
|
this.renderer.hideOverlay();
|
|
163037
163727
|
this.switchTuiMode("regular", false, false);
|
|
163038
163728
|
this.renderer.renderNow();
|
|
163039
163729
|
}
|
|
163040
|
-
this.ui.stop();
|
|
163730
|
+
this.ui.stop({ preserveScreen: this.renderer.mode === "fullscreen" });
|
|
163041
163731
|
}
|
|
163042
163732
|
switchTuiMode(mode, restoreProgress = true, startRenderer = true) {
|
|
163043
163733
|
const previousUi = this.renderer;
|
|
@@ -163091,8 +163781,6 @@ class InteractiveMode {
|
|
|
163091
163781
|
return;
|
|
163092
163782
|
this.registerSignalHandlers();
|
|
163093
163783
|
this.changelogMarkdown = this.getChangelogForDisplay();
|
|
163094
|
-
const [fdPath] = await Promise.all([ensureTool("fd"), ensureTool("rg")]);
|
|
163095
|
-
this.fdPath = fdPath;
|
|
163096
163784
|
if (this.session.scopedModels.length > 0 && (this.options.verbose || !this.settingsManager.getQuietStartup())) {
|
|
163097
163785
|
const modelList = this.session.scopedModels.map((sm) => {
|
|
163098
163786
|
const thinkingStr = sm.thinkingLevel ? `:${sm.thinkingLevel}` : "";
|
|
@@ -163131,9 +163819,10 @@ class InteractiveMode {
|
|
|
163131
163819
|
this.widgetContainerBelow,
|
|
163132
163820
|
this.footerContainer
|
|
163133
163821
|
]);
|
|
163822
|
+
this.defaultEditor.onAction("app.clear", () => this.handleCtrlC());
|
|
163823
|
+
this.defaultEditor.onCtrlD = () => this.handleCtrlD();
|
|
163824
|
+
this.defaultEditor.onSubmit = (text) => this.handleStartupSubmit(text);
|
|
163134
163825
|
this.ui.setFocus(this.editor);
|
|
163135
|
-
this.setupKeyHandlers();
|
|
163136
|
-
this.setupEditorSubmitHandler();
|
|
163137
163826
|
this.ui.start();
|
|
163138
163827
|
this.isInitialized = true;
|
|
163139
163828
|
await this.themeController.applyFromSettings();
|
|
@@ -163187,6 +163876,14 @@ ${onboarding}`, this.getStartupExpansionState(), 1, 0);
|
|
|
163187
163876
|
this.headerContainer.addChild(this.builtInHeader);
|
|
163188
163877
|
}
|
|
163189
163878
|
this.ui.requestRender();
|
|
163879
|
+
const [fdPath] = await Promise.all([
|
|
163880
|
+
ensureTool("fd", (status) => this.showManagedToolStatus(status)),
|
|
163881
|
+
ensureTool("rg", (status) => this.showManagedToolStatus(status))
|
|
163882
|
+
]);
|
|
163883
|
+
this.fdPath = fdPath;
|
|
163884
|
+
this.setupKeyHandlers();
|
|
163885
|
+
this.setupEditorSubmitHandler();
|
|
163886
|
+
this.ui.requestRender();
|
|
163190
163887
|
await this.rebindCurrentSession();
|
|
163191
163888
|
this.renderInitialMessages();
|
|
163192
163889
|
onThemeChange(() => {
|
|
@@ -163213,7 +163910,7 @@ ${onboarding}`, this.getStartupExpansionState(), 1, 0);
|
|
|
163213
163910
|
if (!process.env.PI_OFFLINE) {
|
|
163214
163911
|
const controller = new AbortController;
|
|
163215
163912
|
const timeout = setTimeout(() => controller.abort(), 15000);
|
|
163216
|
-
this.session.modelRuntime
|
|
163913
|
+
refreshModelCatalogs(this.session.modelRuntime, controller.signal).then(() => this.updateAvailableProviderCount()).catch(() => {}).finally(() => clearTimeout(timeout));
|
|
163217
163914
|
}
|
|
163218
163915
|
checkForNewPiVersion(this.version).then((newRelease) => {
|
|
163219
163916
|
if (newRelease) {
|
|
@@ -163923,7 +164620,7 @@ ${warningLines}`, 0, 0));
|
|
|
163923
164620
|
const message = error instanceof Error ? error.message : String(error);
|
|
163924
164621
|
this.showError(`${prefix}: ${message}`);
|
|
163925
164622
|
stopThemeWatcher();
|
|
163926
|
-
this.stop();
|
|
164623
|
+
this.stop("transcript");
|
|
163927
164624
|
process.exit(1);
|
|
163928
164625
|
}
|
|
163929
164626
|
renderCurrentSessionState() {
|
|
@@ -164590,6 +165287,10 @@ ${message}`, ["Yes", "No"], opts);
|
|
|
164590
165287
|
}
|
|
164591
165288
|
} catch {}
|
|
164592
165289
|
}
|
|
165290
|
+
handleStartupSubmit(text) {
|
|
165291
|
+
this.editor.setText(text);
|
|
165292
|
+
this.showStatus("Startup is still in progress");
|
|
165293
|
+
}
|
|
164593
165294
|
setupEditorSubmitHandler() {
|
|
164594
165295
|
this.defaultEditor.onSubmit = async (text) => {
|
|
164595
165296
|
text = text.trim();
|
|
@@ -165032,6 +165733,18 @@ ${message}`, ["Yes", "No"], opts);
|
|
|
165032
165733
|
const textBlocks = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content.filter((c) => c.type === "text");
|
|
165033
165734
|
return textBlocks.map((c) => c.text).join("");
|
|
165034
165735
|
}
|
|
165736
|
+
showManagedToolStatus(status) {
|
|
165737
|
+
if (!this.managedToolStatusStarted) {
|
|
165738
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
165739
|
+
this.managedToolStatusStarted = true;
|
|
165740
|
+
}
|
|
165741
|
+
const message = status.type === "warning" ? `Warning: ${status.message}` : status.message;
|
|
165742
|
+
const color = status.type === "warning" ? "warning" : "dim";
|
|
165743
|
+
this.chatContainer.addChild(new Text(theme.fg(color, message), 1, 0));
|
|
165744
|
+
this.lastStatusSpacer = undefined;
|
|
165745
|
+
this.lastStatusText = undefined;
|
|
165746
|
+
this.ui.requestRender();
|
|
165747
|
+
}
|
|
165035
165748
|
showStatus(message) {
|
|
165036
165749
|
const children = this.chatContainer.children;
|
|
165037
165750
|
const last = children.length > 0 ? children[children.length - 1] : undefined;
|
|
@@ -165324,7 +166037,7 @@ ${message}`, ["Yes", "No"], opts);
|
|
|
165324
166037
|
try {
|
|
165325
166038
|
this.ui.stop();
|
|
165326
166039
|
} catch {}
|
|
165327
|
-
console.error(
|
|
166040
|
+
console.error(`${APP_NAME} exiting due to uncaughtException:`);
|
|
165328
166041
|
console.error(error);
|
|
165329
166042
|
process.exit(1);
|
|
165330
166043
|
}
|
|
@@ -165746,7 +166459,7 @@ ${packageLines}`, 1, 0));
|
|
|
165746
166459
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
165747
166460
|
thinkingLevel: this.session.thinkingLevel,
|
|
165748
166461
|
availableThinkingLevels: this.session.getAvailableThinkingLevels(),
|
|
165749
|
-
currentTheme: this.
|
|
166462
|
+
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
165750
166463
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
165751
166464
|
availableThemes: getAvailableThemes(),
|
|
165752
166465
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
@@ -165765,6 +166478,7 @@ ${packageLines}`, 1, 0));
|
|
|
165765
166478
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
165766
166479
|
showTerminalProgress: this.settingsManager.getShowTerminalProgress(),
|
|
165767
166480
|
tuiMode: this.ui.mode,
|
|
166481
|
+
fullscreenExitOutput: this.settingsManager.getFullscreenExitOutput(),
|
|
165768
166482
|
fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
165769
166483
|
warnings: this.settingsManager.getWarnings()
|
|
165770
166484
|
}, {
|
|
@@ -165820,7 +166534,7 @@ ${packageLines}`, 1, 0));
|
|
|
165820
166534
|
},
|
|
165821
166535
|
onThemeChange: (themeSetting) => {
|
|
165822
166536
|
this.settingsManager.setTheme(themeSetting);
|
|
165823
|
-
this.themeController.
|
|
166537
|
+
this.themeController.setThemeSetting(themeSetting);
|
|
165824
166538
|
},
|
|
165825
166539
|
onThemePreview: (themeName) => this.themeController.preview(themeName),
|
|
165826
166540
|
onHideThinkingBlockChange: (hidden) => {
|
|
@@ -165917,6 +166631,9 @@ ${packageLines}`, 1, 0));
|
|
|
165917
166631
|
this.statusContainer.clear();
|
|
165918
166632
|
this.showStatus(`TUI mode: ${mode}`);
|
|
165919
166633
|
},
|
|
166634
|
+
onFullscreenExitOutputChange: (output) => {
|
|
166635
|
+
this.settingsManager.setFullscreenExitOutput(output);
|
|
166636
|
+
},
|
|
165920
166637
|
onFullscreenScrollbarChange: (mode) => {
|
|
165921
166638
|
this.settingsManager.setFullscreenScrollbar(mode);
|
|
165922
166639
|
this.applyFullscreenScrollbarSetting();
|
|
@@ -165966,7 +166683,7 @@ ${packageLines}`, 1, 0));
|
|
|
165966
166683
|
controller.abort();
|
|
165967
166684
|
}, 15000);
|
|
165968
166685
|
try {
|
|
165969
|
-
const result2 = await this.session.modelRuntime
|
|
166686
|
+
const result2 = await refreshModelCatalogs(this.session.modelRuntime, controller.signal);
|
|
165970
166687
|
if (result2.aborted && timedOut) {
|
|
165971
166688
|
this.showWarning("Model refresh timed out; searching cached models.");
|
|
165972
166689
|
} else if (result2.errors.size > 0) {
|
|
@@ -166042,7 +166759,7 @@ ${packageLines}`, 1, 0));
|
|
|
166042
166759
|
onSelect: (selection) => {
|
|
166043
166760
|
trustStore.setMany(selection.updates);
|
|
166044
166761
|
done();
|
|
166045
|
-
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart
|
|
166762
|
+
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart ${APP_NAME} for this to take effect.`);
|
|
166046
166763
|
},
|
|
166047
166764
|
onCancel: () => {
|
|
166048
166765
|
done();
|
|
@@ -166136,7 +166853,7 @@ ${packageLines}`, 1, 0));
|
|
|
166136
166853
|
this.ui.requestRender();
|
|
166137
166854
|
}
|
|
166138
166855
|
});
|
|
166139
|
-
this.session.modelRuntime
|
|
166856
|
+
refreshModelCatalogs(this.session.modelRuntime, controller.signal).then((result2) => {
|
|
166140
166857
|
if (disposed)
|
|
166141
166858
|
return;
|
|
166142
166859
|
availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
@@ -166630,7 +167347,7 @@ ${packageLines}`, 1, 0));
|
|
|
166630
167347
|
this.ui.requestRender();
|
|
166631
167348
|
};
|
|
166632
167349
|
const dialog = new LoginDialogComponent(this.ui, providerOption.id, () => restoreEditor(), providerOption.name, `${providerOption.name} setup`);
|
|
166633
|
-
dialog.showInfo(`${providerOption.method?.name ?? "Authentication"} is configured outside
|
|
167350
|
+
dialog.showInfo(`${providerOption.method?.name ?? "Authentication"} is configured outside ${APP_NAME}.`, [], true);
|
|
166634
167351
|
this.editorContainer.clear();
|
|
166635
167352
|
this.editorContainer.addChild(dialog);
|
|
166636
167353
|
this.ui.setFocus(dialog);
|
|
@@ -166848,7 +167565,9 @@ ${packageLines}`, 1, 0));
|
|
|
166848
167565
|
const filePath = this.session.exportToJsonl(outputPath);
|
|
166849
167566
|
this.showStatus(`Session exported to: ${filePath}`);
|
|
166850
167567
|
} else {
|
|
166851
|
-
const filePath = await this.session.exportToHtml(outputPath
|
|
167568
|
+
const filePath = await this.session.exportToHtml(outputPath, {
|
|
167569
|
+
themeName: theme.name
|
|
167570
|
+
});
|
|
166852
167571
|
this.showStatus(`Session exported to: ${filePath}`);
|
|
166853
167572
|
}
|
|
166854
167573
|
} catch (error) {
|
|
@@ -166934,7 +167653,7 @@ ${packageLines}`, 1, 0));
|
|
|
166934
167653
|
}
|
|
166935
167654
|
const tmpFile = path12.join(os5.tmpdir(), "session.html");
|
|
166936
167655
|
try {
|
|
166937
|
-
await this.session.exportToHtml(tmpFile);
|
|
167656
|
+
await this.session.exportToHtml(tmpFile, { themeName: theme.name });
|
|
166938
167657
|
} catch (error) {
|
|
166939
167658
|
this.showError(`Failed to export session: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
166940
167659
|
return;
|
|
@@ -167356,7 +168075,7 @@ ${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
|
167356
168075
|
await this.session.compact(customInstructions);
|
|
167357
168076
|
} catch {}
|
|
167358
168077
|
}
|
|
167359
|
-
stop() {
|
|
168078
|
+
stop(fullscreenExitOutput = this.settingsManager.getFullscreenExitOutput()) {
|
|
167360
168079
|
this.disposeActiveSelector();
|
|
167361
168080
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
167362
168081
|
this.ui.terminal.setProgress(false);
|
|
@@ -167370,7 +168089,7 @@ ${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
|
167370
168089
|
this.unsubscribe();
|
|
167371
168090
|
}
|
|
167372
168091
|
if (this.isInitialized) {
|
|
167373
|
-
this.stopInteractiveTui();
|
|
168092
|
+
this.stopInteractiveTui(fullscreenExitOutput);
|
|
167374
168093
|
this.isInitialized = false;
|
|
167375
168094
|
}
|
|
167376
168095
|
this.unregisterSignalHandlers();
|
|
@@ -167381,12 +168100,15 @@ function toJsonEvent(event) {
|
|
|
167381
168100
|
if (event.type !== "message_update") {
|
|
167382
168101
|
return event;
|
|
167383
168102
|
}
|
|
168103
|
+
if (event.message.role !== "assistant") {
|
|
168104
|
+
throw new Error("message_update message is not an assistant message");
|
|
168105
|
+
}
|
|
167384
168106
|
const assistantMessageEvent = event.assistantMessageEvent;
|
|
167385
168107
|
if (!("partial" in assistantMessageEvent)) {
|
|
167386
|
-
return { type: "message_update", assistantMessageEvent };
|
|
168108
|
+
return { type: "message_update", usage: event.message.usage, assistantMessageEvent };
|
|
167387
168109
|
}
|
|
167388
168110
|
const { partial: _partial, ...deltaEvent } = assistantMessageEvent;
|
|
167389
|
-
return { type: "message_update", assistantMessageEvent: deltaEvent };
|
|
168111
|
+
return { type: "message_update", usage: event.message.usage, assistantMessageEvent: deltaEvent };
|
|
167390
168112
|
}
|
|
167391
168113
|
|
|
167392
168114
|
// node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.js
|
|
@@ -169543,7 +170265,7 @@ function updateTargetIncludesSelf(target) {
|
|
|
169543
170265
|
function updateTargetIncludesExtensions(target) {
|
|
169544
170266
|
return target.type === "all" || target.type === "extensions";
|
|
169545
170267
|
}
|
|
169546
|
-
async function
|
|
170268
|
+
async function refreshModelCatalogs2(agentDir) {
|
|
169547
170269
|
const controller = new AbortController;
|
|
169548
170270
|
const timeout = setTimeout(() => controller.abort(), 15000);
|
|
169549
170271
|
try {
|
|
@@ -169576,7 +170298,7 @@ function printSelfUpdateUnavailable(npmCommand, updatePackageTarget = PACKAGE_NA
|
|
|
169576
170298
|
const entrypoint = process.argv[1];
|
|
169577
170299
|
if (entrypoint) {
|
|
169578
170300
|
console.error("");
|
|
169579
|
-
console.error(`Location of
|
|
170301
|
+
console.error(`Location of ${APP_NAME} executable: ${entrypoint}`);
|
|
169580
170302
|
}
|
|
169581
170303
|
}
|
|
169582
170304
|
function printSelfUpdateFallback(command) {
|
|
@@ -169807,7 +170529,7 @@ async function handlePackageCommand(args, runtimeOptions = {}) {
|
|
|
169807
170529
|
}
|
|
169808
170530
|
if (options.command === "update" && options.updateTarget?.type === "models") {
|
|
169809
170531
|
try {
|
|
169810
|
-
await
|
|
170532
|
+
await refreshModelCatalogs2(getAgentDir());
|
|
169811
170533
|
} catch (error) {
|
|
169812
170534
|
const message = error instanceof Error ? error.message : "Unknown model catalog refresh error";
|
|
169813
170535
|
console.error(source_default.red(`Error: ${message}`));
|
|
@@ -169955,7 +170677,7 @@ async function handlePackageCommand(args, runtimeOptions = {}) {
|
|
|
169955
170677
|
}
|
|
169956
170678
|
|
|
169957
170679
|
// node_modules/@earendil-works/pi-coding-agent/dist/main.js
|
|
169958
|
-
var EXTENSION_LOAD_FAILURE_HINT =
|
|
170680
|
+
var EXTENSION_LOAD_FAILURE_HINT = `Hint: Start without extensions using "${APP_NAME} -ne".`;
|
|
169959
170681
|
async function readPipedStdin() {
|
|
169960
170682
|
if (process.stdin.isTTY) {
|
|
169961
170683
|
return;
|
|
@@ -170392,6 +171114,9 @@ async function main(args, options) {
|
|
|
170392
171114
|
await showFirstTimeSetup(startupSettingsManager);
|
|
170393
171115
|
time("firstTimeSetup");
|
|
170394
171116
|
}
|
|
171117
|
+
if (appMode === "interactive" && parsed.useTheme !== undefined) {
|
|
171118
|
+
startupSettingsManager.applyOverrides({ theme: parsed.useTheme });
|
|
171119
|
+
}
|
|
170395
171120
|
const envSessionDir = process.env[ENV_SESSION_DIR];
|
|
170396
171121
|
const sessionDir = (parsed.sessionDir ? normalizePath(parsed.sessionDir) : undefined) ?? (envSessionDir ? expandTildePath(envSessionDir) : undefined) ?? startupSettingsManager.getSessionDir();
|
|
170397
171122
|
let sessionManager = await createSessionManager(parsed, cwd, sessionDir, startupSettingsManager);
|
|
@@ -170592,7 +171317,8 @@ async function main(args, options) {
|
|
|
170592
171317
|
initialImages,
|
|
170593
171318
|
initialMessages: parsed.messages,
|
|
170594
171319
|
verbose: parsed.verbose,
|
|
170595
|
-
tuiMode: parsed.tuiMode
|
|
171320
|
+
tuiMode: parsed.tuiMode,
|
|
171321
|
+
initialThemeSetting: parsed.useTheme
|
|
170596
171322
|
});
|
|
170597
171323
|
if (startupBenchmark) {
|
|
170598
171324
|
await interactiveMode.init();
|
|
@@ -171873,6 +172599,10 @@ class PiMonoAdapter {
|
|
|
171873
172599
|
if (config.apiUrl && config.apiKey) {
|
|
171874
172600
|
try {
|
|
171875
172601
|
const mcpClient = new McpHttpClient(config.apiUrl, config.apiKey, config.agentId, config.taskId);
|
|
172602
|
+
const runtimeInstanceId = swarmRuntimeInstanceId();
|
|
172603
|
+
if (runtimeInstanceId) {
|
|
172604
|
+
mcpClient.customHeaders["X-Runtime-Instance-ID"] = runtimeInstanceId;
|
|
172605
|
+
}
|
|
171876
172606
|
await mcpClient.initialize();
|
|
171877
172607
|
const tools2 = await mcpClient.listTools();
|
|
171878
172608
|
customTools = mcpToolsToDefinitions(mcpClient, tools2);
|