@pi-unipi/unipi 3.0.0-alpha.2 → 3.0.0-alpha.21
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/CHANGELOG.md +292 -0
- package/README.md +8 -11
- package/docs/prefix-cache-architecture.md +14 -0
- package/package.json +22 -24
- package/packages/ask-user/README.md +55 -107
- package/packages/ask-user/ask-ui.ts +306 -732
- package/packages/ask-user/clipboard.ts +50 -0
- package/packages/ask-user/config.ts +74 -78
- package/packages/ask-user/package.json +2 -2
- package/packages/ask-user/questions.ts +151 -0
- package/packages/ask-user/skills/ask-user/SKILL.md +59 -133
- package/packages/ask-user/tools.ts +198 -432
- package/packages/autocomplete/package.json +1 -1
- package/packages/autocomplete/src/constants.ts +38 -43
- package/packages/autocomplete/src/sorting.ts +8 -0
- package/packages/background-tasks/package.json +2 -2
- package/packages/background-tasks/src/config.ts +0 -73
- package/packages/background-tasks/src/index.ts +20 -16
- package/packages/background-tasks/src/registry.ts +1 -171
- package/packages/background-tasks/src/types.ts +0 -32
- package/packages/btw/README.md +13 -56
- package/packages/btw/extensions/btw.ts +403 -1796
- package/packages/btw/package.json +5 -2
- package/packages/btw/skills/btw/SKILL.md +7 -143
- package/packages/compactor/README.md +56 -287
- package/packages/compactor/package.json +5 -9
- package/packages/compactor/skills/compactor/SKILL.md +13 -20
- package/packages/compactor/src/card.ts +90 -0
- package/packages/compactor/src/commands/index.ts +73 -130
- package/packages/compactor/src/compaction/compact-args.ts +5 -3
- package/packages/compactor/src/compaction/filter-noise.ts +1 -1
- package/packages/compactor/src/compaction/hooks.ts +487 -311
- package/packages/compactor/src/compaction/source.ts +178 -0
- package/packages/compactor/src/compaction/summarize.ts +586 -52
- package/packages/compactor/src/config/manager.ts +130 -127
- package/packages/compactor/src/config/schema.ts +32 -48
- package/packages/compactor/src/index.ts +40 -431
- package/packages/compactor/src/info-screen.ts +44 -190
- package/packages/compactor/src/session/recall-blocks.ts +1 -1
- package/packages/compactor/src/stats.ts +76 -0
- package/packages/compactor/src/tools/context-budget.ts +17 -34
- package/packages/compactor/src/tools/ctx-doctor.ts +45 -36
- package/packages/compactor/src/tools/register.ts +29 -269
- package/packages/compactor/src/types.ts +47 -186
- package/packages/core/README.md +25 -0
- package/packages/core/child-agent.ts +1 -0
- package/packages/core/command-echo.ts +63 -0
- package/packages/core/compaction-context.ts +41 -0
- package/packages/core/constants.ts +8 -38
- package/packages/core/events.ts +0 -53
- package/packages/core/fusion-status.ts +4 -0
- package/packages/core/global.d.ts +10 -0
- package/packages/core/harness-messages.ts +392 -0
- package/packages/core/index.ts +14 -0
- package/packages/core/kanboard-status.ts +49 -0
- package/packages/core/long-horizon-owner-status.ts +46 -0
- package/packages/core/model-cache.ts +81 -7
- package/packages/core/package.json +6 -3
- package/packages/core/src/attach/detect.ts +163 -0
- package/packages/core/src/child-agent/child-args.ts +31 -0
- package/packages/core/src/child-agent/delivery.ts +41 -0
- package/packages/core/src/child-agent/index.ts +5 -0
- package/packages/core/src/child-agent/readers.ts +203 -0
- package/packages/core/src/child-agent/runtime.ts +584 -0
- package/packages/core/src/evidence.ts +78 -0
- package/packages/core/src/hints/browser.ts +278 -0
- package/packages/core/src/hints/crab-data.ts +19 -0
- package/packages/core/src/hints/index.ts +865 -0
- package/packages/core/src/hints/lines.ts +607 -0
- package/packages/core/src/hints/store.ts +120 -0
- package/packages/core/src/jev/chatter.ts +24 -0
- package/packages/core/src/jev/settings.ts +177 -14
- package/packages/core/src/package-colors.ts +2 -0
- package/packages/core/src/settings/catalog.ts +39 -15
- package/packages/core/src/settings/engine.ts +48 -2
- package/packages/core/src/settings/hub.ts +83 -20
- package/packages/core/src/settings/open.ts +49 -0
- package/packages/core/src/settings/schema.ts +27 -7
- package/packages/core/src/tui/hub-kit.ts +18 -5
- package/packages/core/src/tui/kit.ts +198 -0
- package/packages/core/src/tui/progress.ts +73 -0
- package/packages/core/src/turn/arbiter.ts +290 -0
- package/packages/footer/README.md +4 -6
- package/packages/footer/package.json +3 -3
- package/packages/footer/src/glance-editor.ts +19 -11
- package/packages/footer/src/help.ts +1 -1
- package/packages/footer/src/index.ts +36 -3
- package/packages/footer/src/presets.ts +3 -4
- package/packages/footer/src/rendering/icons.ts +0 -20
- package/packages/footer/src/segments/compactor.ts +52 -142
- package/packages/footer/src/segments/status-ext.ts +0 -1
- package/packages/fusion/README.md +14 -4
- package/packages/fusion/package.json +4 -3
- package/packages/fusion/src/child-args.ts +1 -0
- package/packages/fusion/src/index.ts +161 -8
- package/packages/fusion/src/pi-settings.ts +57 -0
- package/packages/fusion/src/picker.ts +186 -51
- package/packages/fusion/src/preset.ts +56 -2
- package/packages/fusion/src/prompts.ts +1 -1
- package/packages/fusion/src/sidekick-runtime.ts +1 -420
- package/packages/fusion/src/tools.ts +107 -128
- package/packages/fusion/src/transcript.ts +27 -85
- package/packages/info-screen/package.json +2 -2
- package/packages/input-shortcuts/README.md +18 -30
- package/packages/input-shortcuts/package.json +2 -2
- package/packages/input-shortcuts/src/burst.ts +88 -0
- package/packages/input-shortcuts/src/chord-overlay.ts +20 -70
- package/packages/input-shortcuts/src/cleared-input.ts +97 -0
- package/packages/input-shortcuts/src/index.ts +99 -193
- package/packages/input-shortcuts/src/last-response.ts +40 -0
- package/packages/input-shortcuts/src/registers.ts +8 -23
- package/packages/input-shortcuts/src/types.ts +4 -16
- package/packages/input-shortcuts/src/undo-redo.ts +59 -47
- package/packages/kanboard/README.md +51 -47
- package/packages/kanboard/index.ts +293 -55
- package/packages/kanboard/package.json +8 -8
- package/packages/kanboard/skills/kanboard/SKILL.md +61 -27
- package/packages/kanboard/src/badges.ts +93 -0
- package/packages/kanboard/src/bin.ts +4 -2
- package/packages/kanboard/src/commands.ts +218 -84
- package/packages/kanboard/src/debug.ts +20 -0
- package/packages/kanboard/src/guard.ts +267 -109
- package/packages/kanboard/src/monitor.ts +330 -0
- package/packages/kanboard/src/notice-buffer.ts +74 -0
- package/packages/kanboard/src/progress.ts +27 -0
- package/packages/kanboard/src/reminders.ts +234 -0
- package/packages/kanboard/src/settings.ts +69 -15
- package/packages/kanboard/src/shapes.ts +5 -0
- package/packages/long-horizon/index.ts +190 -13
- package/packages/long-horizon/package.json +3 -3
- package/packages/long-horizon/src/commands.ts +103 -7
- package/packages/long-horizon/src/compaction-brief.ts +35 -0
- package/packages/long-horizon/src/engine/continuation.ts +84 -15
- package/packages/long-horizon/src/engine/goal-state.ts +64 -13
- package/packages/long-horizon/src/engine/nudge-stash.ts +71 -0
- package/packages/long-horizon/src/engine/ralph.ts +3 -2
- package/packages/long-horizon/src/engine/runaway.ts +68 -11
- package/packages/long-horizon/src/engine/verifier.ts +19 -0
- package/packages/long-horizon/src/gate.ts +37 -12
- package/packages/long-horizon/src/judge/resolve.ts +1 -0
- package/packages/long-horizon/src/owner.ts +35 -2
- package/packages/long-horizon/src/progress.ts +87 -0
- package/packages/long-horizon/src/prompts/goal.ts +1 -1
- package/packages/long-horizon/src/runtime.ts +172 -18
- package/packages/long-horizon/src/settings.ts +54 -39
- package/packages/long-horizon/src/tools/goal.ts +6 -0
- package/packages/long-horizon/src/tools/graph.ts +1 -1
- package/packages/long-horizon/src/tools/swarm.ts +3 -3
- package/packages/mcp/package.json +2 -2
- package/packages/memory/commands.ts +7 -2
- package/packages/memory/index.ts +210 -32
- package/packages/memory/package.json +3 -3
- package/packages/memory/save-session.ts +264 -0
- package/packages/memory/settings.ts +17 -0
- package/packages/memory/tools.ts +253 -203
- package/packages/notify/package.json +2 -2
- package/packages/skill-registry/README.md +53 -16
- package/packages/skill-registry/index.ts +230 -0
- package/packages/skill-registry/package.json +19 -8
- package/packages/skill-registry/src/editor.ts +206 -0
- package/packages/skill-registry/src/judge.ts +289 -0
- package/packages/skill-registry/src/registry.ts +87 -0
- package/packages/skill-registry/src/settings.ts +259 -0
- package/packages/skill-registry/src/vault.ts +80 -0
- package/packages/subagents/README.md +39 -119
- package/packages/subagents/package.json +6 -13
- package/packages/subagents/skills/subagents/SKILL.md +18 -42
- package/packages/subagents/src/agents.ts +213 -0
- package/packages/subagents/src/cards.ts +182 -0
- package/packages/subagents/src/index.ts +609 -1084
- package/packages/subagents/src/manager.ts +429 -0
- package/packages/subagents/src/profiles.ts +130 -0
- package/packages/subagents/src/transcript.ts +154 -0
- package/packages/subagents/src/ui.ts +389 -0
- package/packages/unipi/bundled.js +39756 -45569
- package/packages/unipi/index.ts +55 -10
- package/packages/updater/package.json +2 -2
- package/packages/utility/README.md +76 -69
- package/packages/utility/package.json +2 -2
- package/packages/utility/skills/image/SKILL.md +37 -0
- package/packages/utility/skills/utility/SKILL.md +17 -60
- package/packages/utility/src/answer/extract.ts +128 -0
- package/packages/utility/src/answer/index.ts +213 -0
- package/packages/utility/src/answer/reply.ts +133 -0
- package/packages/utility/src/answer/web.ts +167 -0
- package/packages/utility/src/attach/index.ts +205 -0
- package/packages/utility/src/commands.ts +38 -142
- package/packages/utility/src/diagnostics/engine.ts +50 -5
- package/packages/utility/src/image/index.ts +33 -0
- package/packages/utility/src/image/models.ts +221 -0
- package/packages/{image/src → utility/src/image}/recognize.ts +2 -2
- package/packages/utility/src/image/settings.ts +178 -0
- package/packages/{image/src/image-source.ts → utility/src/image/source.ts} +1 -1
- package/packages/utility/src/image/tools.ts +168 -0
- package/packages/utility/src/image/transports.ts +186 -0
- package/packages/utility/src/index.ts +68 -389
- package/packages/utility/src/lifecycle/cleanup.ts +116 -311
- package/packages/utility/src/rename/gate.ts +102 -0
- package/packages/utility/src/rename/index.ts +191 -0
- package/packages/utility/src/rename/session.ts +170 -0
- package/packages/utility/src/render/delegated.ts +285 -0
- package/packages/utility/src/render/harness.ts +683 -0
- package/packages/utility/src/render/parse.ts +156 -0
- package/packages/utility/src/render/pi-settings.ts +38 -0
- package/packages/utility/src/render/reply-bg.ts +307 -0
- package/packages/utility/src/render/simple.ts +724 -0
- package/packages/utility/src/render/spacing.ts +235 -0
- package/packages/utility/src/render/styled.ts +251 -0
- package/packages/utility/src/render/tools.ts +353 -0
- package/packages/utility/src/settings.ts +166 -233
- package/packages/utility/src/types.ts +1 -222
- package/packages/watchdog/index.ts +17 -6
- package/packages/watchdog/package.json +3 -3
- package/packages/watchdog/src/config.ts +3 -2
- package/packages/web-api/package.json +2 -2
- package/packages/workflow/README.md +3 -0
- package/packages/workflow/index.ts +0 -2
- package/packages/workflow/package.json +2 -2
- package/packages/workflow/src/permission/decide.ts +6 -4
- package/packages/workflow/src/permission/index.ts +17 -7
- package/packages/workflow/src/permission/settings.ts +39 -4
- package/packages/workflow/src/plan/index.ts +19 -4
- package/packages/background-tasks/extensions/delegate-child.ts +0 -1
- package/packages/background-tasks/src/context-parent-snapshot.ts +0 -142
- package/packages/background-tasks/src/context-token-budget.ts +0 -903
- package/packages/background-tasks/src/context-visible-conversation-v2.ts +0 -551
- package/packages/background-tasks/src/delegate/artifacts.ts +0 -487
- package/packages/background-tasks/src/delegate/budget.ts +0 -415
- package/packages/background-tasks/src/delegate/hook-contract-evidence.json +0 -18
- package/packages/background-tasks/src/delegate/hook-contract.ts +0 -154
- package/packages/background-tasks/src/delegate/launch.ts +0 -484
- package/packages/background-tasks/src/delegate/result-package.ts +0 -459
- package/packages/background-tasks/src/delegate/runner.ts +0 -430
- package/packages/background-tasks/src/delegate/seed.ts +0 -423
- package/packages/background-tasks/src/delegate/types.ts +0 -323
- package/packages/background-tasks/src/delegate-child-extension.ts +0 -978
- package/packages/background-tasks/src/delegate-extension.ts +0 -654
- package/packages/background-tasks/src/fixtures/delegate-context-incident.json +0 -17
- package/packages/compactor/skills/compactor-detail/SKILL.md +0 -116
- package/packages/compactor/skills/compactor-doctor/SKILL.md +0 -71
- package/packages/compactor/skills/compactor-stats/SKILL.md +0 -51
- package/packages/compactor/src/compaction/build-sections.ts +0 -76
- package/packages/compactor/src/compaction/extract/goals.ts +0 -36
- package/packages/compactor/src/compaction/extract/preferences.ts +0 -40
- package/packages/compactor/src/compaction/format.ts +0 -53
- package/packages/compactor/src/compaction/merge.ts +0 -143
- package/packages/compactor/src/config/presets.ts +0 -160
- package/packages/compactor/src/executor/executor.ts +0 -233
- package/packages/compactor/src/executor/runtime.ts +0 -115
- package/packages/compactor/src/security/evaluator.ts +0 -89
- package/packages/compactor/src/security/policy.ts +0 -96
- package/packages/compactor/src/security/scanner.ts +0 -65
- package/packages/compactor/src/session/auto-inject.ts +0 -60
- package/packages/compactor/src/session/db.ts +0 -325
- package/packages/compactor/src/session/extract.ts +0 -144
- package/packages/compactor/src/session/resume-inject.ts +0 -64
- package/packages/compactor/src/session/snapshot.ts +0 -327
- package/packages/compactor/src/tools/ctx-batch-execute.ts +0 -41
- package/packages/compactor/src/tools/ctx-execute-file.ts +0 -23
- package/packages/compactor/src/tools/ctx-execute.ts +0 -23
- package/packages/compactor/src/tools/ctx-stats.ts +0 -96
- package/packages/image/README.md +0 -99
- package/packages/image/package.json +0 -61
- package/packages/image/skills/image/SKILL.md +0 -76
- package/packages/image/src/generate.ts +0 -256
- package/packages/image/src/index.ts +0 -135
- package/packages/image/src/models.ts +0 -519
- package/packages/image/src/openai-images-api.ts +0 -282
- package/packages/image/src/register-providers.ts +0 -209
- package/packages/image/src/settings.ts +0 -173
- package/packages/image/src/tools.ts +0 -326
- package/packages/input-shortcuts/src/clipboard.ts +0 -119
- package/packages/kanboard/src/runner.ts +0 -817
- package/packages/skill-registry/skills/auto/SKILL.md +0 -465
- package/packages/skill-registry/skills/brainstorm/SKILL.md +0 -219
- package/packages/skill-registry/skills/chore-create/SKILL.md +0 -315
- package/packages/skill-registry/skills/chore-execute/SKILL.md +0 -314
- package/packages/skill-registry/skills/consolidate/SKILL.md +0 -142
- package/packages/skill-registry/skills/consultant/SKILL.md +0 -97
- package/packages/skill-registry/skills/debug/SKILL.md +0 -228
- package/packages/skill-registry/skills/document/SKILL.md +0 -120
- package/packages/skill-registry/skills/fix/SKILL.md +0 -212
- package/packages/skill-registry/skills/gather-context/SKILL.md +0 -145
- package/packages/skill-registry/skills/plan/SKILL.md +0 -231
- package/packages/skill-registry/skills/quick-fix/SKILL.md +0 -135
- package/packages/skill-registry/skills/quick-work/SKILL.md +0 -110
- package/packages/skill-registry/skills/research/SKILL.md +0 -251
- package/packages/skill-registry/skills/review-work/SKILL.md +0 -187
- package/packages/skill-registry/skills/scan-issues/SKILL.md +0 -195
- package/packages/skill-registry/skills/work/SKILL.md +0 -218
- package/packages/skill-registry/skills/worktree-create/SKILL.md +0 -69
- package/packages/skill-registry/skills/worktree-list/SKILL.md +0 -78
- package/packages/skill-registry/skills/worktree-merge/SKILL.md +0 -89
- package/packages/subagents/agents/delegate.md +0 -14
- package/packages/subagents/agents/oracle.md +0 -78
- package/packages/subagents/agents/researcher.md +0 -52
- package/packages/subagents/agents/reviewer.md +0 -80
- package/packages/subagents/agents/scout.md +0 -50
- package/packages/subagents/agents/worker.md +0 -59
- package/packages/subagents/prompts/council.md +0 -48
- package/packages/subagents/prompts/gather-context-and-clarify.md +0 -13
- package/packages/subagents/prompts/parallel-cleanup.md +0 -59
- package/packages/subagents/prompts/parallel-research.md +0 -50
- package/packages/subagents/prompts/parallel-review.md +0 -54
- package/packages/subagents/prompts/review-loop.md +0 -43
- package/packages/subagents/skills/council-mode/SKILL.md +0 -230
- package/packages/subagents/skills/subagents/references/constraints-and-recipes.md +0 -259
- package/packages/subagents/skills/subagents/references/execution-controls.md +0 -454
- package/packages/subagents/skills/subagents/references/management-authoring-rpc.md +0 -161
- package/packages/subagents/skills/subagents/references/multi-lane-orchestration.md +0 -39
- package/packages/subagents/skills/subagents/references/prompting-and-roles.md +0 -267
- package/packages/subagents/src/acceptance.ts +0 -331
- package/packages/subagents/src/agent-manager.ts +0 -405
- package/packages/subagents/src/agent-memory.ts +0 -300
- package/packages/subagents/src/agent-overrides.ts +0 -183
- package/packages/subagents/src/agent-runner.ts +0 -271
- package/packages/subagents/src/async-runner.ts +0 -422
- package/packages/subagents/src/authority-policy.ts +0 -47
- package/packages/subagents/src/budgets.ts +0 -285
- package/packages/subagents/src/child-safety.ts +0 -140
- package/packages/subagents/src/config.ts +0 -249
- package/packages/subagents/src/conversation-viewer.ts +0 -281
- package/packages/subagents/src/core-compat.ts +0 -94
- package/packages/subagents/src/custom-agents.ts +0 -343
- package/packages/subagents/src/file-system-retry.ts +0 -50
- package/packages/subagents/src/fleet-data.ts +0 -105
- package/packages/subagents/src/fleet-view.ts +0 -322
- package/packages/subagents/src/foreground-detach.ts +0 -59
- package/packages/subagents/src/fork-context.ts +0 -285
- package/packages/subagents/src/global.d.ts +0 -7
- package/packages/subagents/src/guide.ts +0 -129
- package/packages/subagents/src/mission-state.ts +0 -133
- package/packages/subagents/src/mission-store.ts +0 -436
- package/packages/subagents/src/output-limits.ts +0 -142
- package/packages/subagents/src/parity-types.ts +0 -315
- package/packages/subagents/src/pi-args.ts +0 -167
- package/packages/subagents/src/result-files.ts +0 -232
- package/packages/subagents/src/result-watcher.ts +0 -221
- package/packages/subagents/src/retained-children.ts +0 -176
- package/packages/subagents/src/run-fanout-budget.ts +0 -356
- package/packages/subagents/src/scheduled-runs.ts +0 -349
- package/packages/subagents/src/schemas.ts +0 -263
- package/packages/subagents/src/slash-commands.ts +0 -80
- package/packages/subagents/src/supervisor-channel.ts +0 -249
- package/packages/subagents/src/tool-handler.ts +0 -1144
- package/packages/subagents/src/types.ts +0 -238
- package/packages/subagents/src/widget.ts +0 -457
- package/packages/subagents/src/workflow-script.ts +0 -737
- package/packages/subagents/src/workflow-worker.ts +0 -384
- package/packages/subagents/src/worktree.ts +0 -614
- package/packages/utility/src/analytics/collector.ts +0 -293
- package/packages/utility/src/info-screen.ts +0 -80
- package/packages/utility/src/lifecycle/process.ts +0 -162
- package/packages/utility/src/prefix-cache.ts +0 -263
- package/packages/utility/src/skill-discovery.ts +0 -542
- package/packages/utility/src/tools/env.ts +0 -113
- package/packages/utility/src/tui/name-badge-state.ts +0 -315
- package/packages/utility/src/tui/name-badge.ts +0 -109
- /package/packages/{subagents/src → core/src/child-agent}/pi-spawn.ts +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typing-burst tracker for the undo history.
|
|
3
|
+
*
|
|
4
|
+
* The terminal-input handler must stay O(1): NO editor read per key except
|
|
5
|
+
* at burst start (which captures the pre-burst state, including programmatic
|
|
6
|
+
* changes like submit clearing the editor). Every input only stamps
|
|
7
|
+
* `lastInputAt`. One timer rides along: when it fires, an active burst that
|
|
8
|
+
* went quiet for BURST_IDLE_MS is flushed (post-burst state recorded) and
|
|
9
|
+
* closed; a burst that keeps going longer than BURST_MAX_MS is split so a
|
|
10
|
+
* long typing session still checkpoints. So a burst costs exactly two editor
|
|
11
|
+
* reads — one at open, one at close.
|
|
12
|
+
*
|
|
13
|
+
* Clock, timer and text access are injectable so tests can fake all of them.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const BURST_IDLE_MS = 600;
|
|
17
|
+
export const BURST_MAX_MS = 2000;
|
|
18
|
+
|
|
19
|
+
export interface BurstDeps {
|
|
20
|
+
/** Read the editor text (called only at burst open and close). */
|
|
21
|
+
getText(): string;
|
|
22
|
+
/** Where the captured states go (EditHistory.record). */
|
|
23
|
+
record(text: string): void;
|
|
24
|
+
now(): number;
|
|
25
|
+
setTimeout(handler: () => void, ms: number): unknown;
|
|
26
|
+
clearTimeout(handle: unknown): void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class BurstTracker {
|
|
30
|
+
private open = false;
|
|
31
|
+
private burstStart = 0;
|
|
32
|
+
private lastInputAt = 0;
|
|
33
|
+
private timer: unknown = null;
|
|
34
|
+
|
|
35
|
+
constructor(private readonly deps: BurstDeps) {}
|
|
36
|
+
|
|
37
|
+
/** A terminal input arrived — O(1), no editor read once a burst is open. */
|
|
38
|
+
onInput(): void {
|
|
39
|
+
const now = this.deps.now();
|
|
40
|
+
if (!this.open) {
|
|
41
|
+
this.open = true;
|
|
42
|
+
this.burstStart = now;
|
|
43
|
+
this.lastInputAt = now;
|
|
44
|
+
this.deps.record(this.deps.getText());
|
|
45
|
+
this.arm(now);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.lastInputAt = now;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Flush and close the burst if one is open: the post-burst text is
|
|
53
|
+
* recorded (a no-op when nothing changed). Undo/redo call this first so
|
|
54
|
+
* un-flushed typing is captured before stepping.
|
|
55
|
+
*/
|
|
56
|
+
close(): void {
|
|
57
|
+
const wasOpen = this.open;
|
|
58
|
+
this.cancel();
|
|
59
|
+
if (wasOpen) {
|
|
60
|
+
this.deps.record(this.deps.getText());
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Drop the timer and forget the burst WITHOUT recording anything. */
|
|
65
|
+
cancel(): void {
|
|
66
|
+
if (this.timer !== null) {
|
|
67
|
+
this.deps.clearTimeout(this.timer);
|
|
68
|
+
this.timer = null;
|
|
69
|
+
}
|
|
70
|
+
this.open = false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private arm(now: number): void {
|
|
74
|
+
const idleRemainder = BURST_IDLE_MS - (now - this.lastInputAt);
|
|
75
|
+
const burstRemainder = BURST_MAX_MS - (now - this.burstStart);
|
|
76
|
+
const wait = Math.max(0, Math.min(idleRemainder, burstRemainder));
|
|
77
|
+
this.timer = this.deps.setTimeout(() => this.onTimer(), wait);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private onTimer(): void {
|
|
81
|
+
const now = this.deps.now();
|
|
82
|
+
if (this.open && now - this.lastInputAt < BURST_IDLE_MS && now - this.burstStart < BURST_MAX_MS) {
|
|
83
|
+
this.arm(now);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.close();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TUI overlay component for ALT+S chord
|
|
2
|
+
* TUI overlay component for the ALT+S chord.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* One state: the root action menu. Uses the ctx.ui.custom() pattern from
|
|
5
|
+
* btw/compactor.
|
|
6
6
|
*
|
|
7
7
|
* IMPORTANT: The overlay ONLY captures the user's action selection.
|
|
8
8
|
* Actions are NOT executed inside the overlay — they are deferred to the
|
|
9
|
-
* caller via callbacks (onStash, onUndo,
|
|
9
|
+
* caller via callbacks (onStash, onUndo, …). The caller closes the
|
|
10
10
|
* overlay via done(), then executes the action outside the overlay context
|
|
11
11
|
* where ctx.ui.getEditorText() / setEditorText() actually work.
|
|
12
12
|
*
|
|
13
|
-
* Closes on ESC or after selecting an action
|
|
13
|
+
* Closes on ESC or after selecting an action; an unknown key closes silently.
|
|
14
|
+
* No timeout.
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
|
-
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
17
17
|
import {
|
|
18
18
|
Container,
|
|
19
19
|
Key,
|
|
@@ -23,8 +23,6 @@ import {
|
|
|
23
23
|
type TUI,
|
|
24
24
|
type KeybindingsManager,
|
|
25
25
|
} from "@earendil-works/pi-tui";
|
|
26
|
-
import type { ChordState } from "./types.ts";
|
|
27
|
-
import { THINKING_CYCLE } from "./types.ts";
|
|
28
26
|
|
|
29
27
|
/** Theme-like interface matching pi-coding-agent's Theme */
|
|
30
28
|
interface ThemeLike {
|
|
@@ -39,11 +37,9 @@ export interface ChordCallbacks {
|
|
|
39
37
|
onStash: () => void;
|
|
40
38
|
onUndo: () => void;
|
|
41
39
|
onRedo: () => void;
|
|
42
|
-
onAppendRegister: (index: number) => void;
|
|
43
40
|
onAppendStash: () => void;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
onToggleThinking: () => void;
|
|
41
|
+
onCopyLastResponse: () => void | Promise<void>;
|
|
42
|
+
onKanboard: () => void | Promise<void>;
|
|
47
43
|
}
|
|
48
44
|
|
|
49
45
|
// ─── Action menu lines ──────────────────────────────────────────────────────
|
|
@@ -52,26 +48,15 @@ const ROOT_ACTIONS: Array<{ key: string; label: string }> = [
|
|
|
52
48
|
{ key: "S", label: "Stash / Restore" },
|
|
53
49
|
{ key: "U", label: "Undo" },
|
|
54
50
|
{ key: "R", label: "Redo" },
|
|
55
|
-
{ key: "A", label: "Append
|
|
56
|
-
{ key: "Y", label: "Copy
|
|
57
|
-
{ key: "
|
|
58
|
-
{ key: "T", label: "Toggle thinking" },
|
|
51
|
+
{ key: "A", label: "Append stash" },
|
|
52
|
+
{ key: "Y", label: "Copy last response" },
|
|
53
|
+
{ key: "K", label: "Add to kanboard backlog" },
|
|
59
54
|
];
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
const actions: Array<{ key: string; label: string }> = [];
|
|
63
|
-
for (let i = 0; i <= 9; i++) {
|
|
64
|
-
actions.push({ key: String(i), label: `Register ${i}` });
|
|
65
|
-
}
|
|
66
|
-
actions.push({ key: "S", label: "Stash register" });
|
|
67
|
-
return actions;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ─── ChordOverlay Component ─────────────────────────────────────────────────
|
|
56
|
+
// ─── ChordOverlay Component ─────────────────────────────────────────────────────────
|
|
71
57
|
|
|
72
58
|
export class ChordOverlay extends Container implements Focusable {
|
|
73
59
|
private _focused = true;
|
|
74
|
-
private state: ChordState = "chord_root";
|
|
75
60
|
private actionLines: Text[] = [];
|
|
76
61
|
private tui: TUI;
|
|
77
62
|
private theme: ThemeLike;
|
|
@@ -103,22 +88,12 @@ export class ChordOverlay extends Container implements Focusable {
|
|
|
103
88
|
}
|
|
104
89
|
|
|
105
90
|
private renderRootMenu(): void {
|
|
106
|
-
this.state = "chord_root";
|
|
107
91
|
this.actionLines = ROOT_ACTIONS.map(
|
|
108
92
|
(a) => new Text(` ${this.theme.fg("accent", `[${a.key}]`)} ${a.label}`, 1, 0),
|
|
109
93
|
);
|
|
110
94
|
this.requestRender();
|
|
111
95
|
}
|
|
112
96
|
|
|
113
|
-
private renderRegisterMenu(): void {
|
|
114
|
-
this.state = "chord_reg";
|
|
115
|
-
const regActions = buildRegisterActions();
|
|
116
|
-
this.actionLines = regActions.map(
|
|
117
|
-
(a) => new Text(` ${this.theme.fg("accent", `[${a.key}]`)} ${a.label}`, 1, 0),
|
|
118
|
-
);
|
|
119
|
-
this.requestRender();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
97
|
private requestRender(): void {
|
|
123
98
|
this.tui.requestRender();
|
|
124
99
|
}
|
|
@@ -129,13 +104,7 @@ export class ChordOverlay extends Container implements Focusable {
|
|
|
129
104
|
return;
|
|
130
105
|
}
|
|
131
106
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (this.state === "chord_root") {
|
|
135
|
-
this.handleRootKey(key);
|
|
136
|
-
} else if (this.state === "chord_reg") {
|
|
137
|
-
this.handleRegKey(key);
|
|
138
|
-
}
|
|
107
|
+
this.handleRootKey(data.toLowerCase());
|
|
139
108
|
}
|
|
140
109
|
|
|
141
110
|
private handleRootKey(key: string): void {
|
|
@@ -150,16 +119,13 @@ export class ChordOverlay extends Container implements Focusable {
|
|
|
150
119
|
this.closeThenExecute(() => this.callbacks.onRedo());
|
|
151
120
|
break;
|
|
152
121
|
case "a":
|
|
153
|
-
this.
|
|
154
|
-
return; // don't close — show register sub-menu
|
|
155
|
-
case "y":
|
|
156
|
-
this.closeThenExecute(() => this.callbacks.onCopy());
|
|
122
|
+
this.closeThenExecute(() => this.callbacks.onAppendStash());
|
|
157
123
|
break;
|
|
158
|
-
case "
|
|
159
|
-
this.closeThenExecute(() => this.callbacks.
|
|
124
|
+
case "y":
|
|
125
|
+
this.closeThenExecute(() => this.callbacks.onCopyLastResponse());
|
|
160
126
|
break;
|
|
161
|
-
case "
|
|
162
|
-
this.closeThenExecute(() => this.callbacks.
|
|
127
|
+
case "k":
|
|
128
|
+
this.closeThenExecute(() => this.callbacks.onKanboard());
|
|
163
129
|
break;
|
|
164
130
|
default:
|
|
165
131
|
// Unknown key — silent close
|
|
@@ -168,28 +134,12 @@ export class ChordOverlay extends Container implements Focusable {
|
|
|
168
134
|
}
|
|
169
135
|
}
|
|
170
136
|
|
|
171
|
-
private handleRegKey(key: string): void {
|
|
172
|
-
if (key === "s") {
|
|
173
|
-
this.closeThenExecute(() => this.callbacks.onAppendStash());
|
|
174
|
-
} else if (/^[0-9]$/.test(key)) {
|
|
175
|
-
const index = parseInt(key, 10);
|
|
176
|
-
this.closeThenExecute(() => this.callbacks.onAppendRegister(index));
|
|
177
|
-
} else {
|
|
178
|
-
// Unknown key — silent close
|
|
179
|
-
this.close();
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private enterRegChord(): void {
|
|
184
|
-
this.renderRegisterMenu();
|
|
185
|
-
}
|
|
186
|
-
|
|
187
137
|
/**
|
|
188
138
|
* Close the overlay, then execute the action.
|
|
189
139
|
* The action runs AFTER the overlay is dismissed, so ctx.ui.getEditorText()
|
|
190
140
|
* and setEditorText() work correctly (they don't work while overlay is open).
|
|
191
141
|
*/
|
|
192
|
-
private closeThenExecute(action: () => void): void {
|
|
142
|
+
private closeThenExecute(action: () => void | Promise<void>): void {
|
|
193
143
|
this.done(); // close the overlay
|
|
194
144
|
// Use setTimeout(0) to defer action to next tick — overlay will be dismissed by then
|
|
195
145
|
setTimeout(action, 0);
|
|
@@ -213,7 +163,7 @@ export class ChordOverlay extends Container implements Focusable {
|
|
|
213
163
|
lines.push(this.theme.fg("borderMuted", `┌${"─".repeat(innerWidth)}┐`));
|
|
214
164
|
|
|
215
165
|
// Title
|
|
216
|
-
const title =
|
|
166
|
+
const title = "Input Shortcuts";
|
|
217
167
|
const titlePadded = title.padEnd(innerWidth);
|
|
218
168
|
lines.push(`${this.theme.fg("borderMuted", "│")}${this.theme.fg("accent", titlePadded)}${this.theme.fg("borderMuted", "│")}`);
|
|
219
169
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ctrl+C keeps what it cleared (Devin-style):
|
|
3
|
+
* - the text stays in the transcript, struck through (UI-only entry — custom
|
|
4
|
+
* entries never reach the model, so no tokens and no prefix-cache churn);
|
|
5
|
+
* - it is pushed onto the editor's ↑ history, so ↑ brings it back.
|
|
6
|
+
*
|
|
7
|
+
* pi still does the clearing (and double Ctrl+C still exits). We only look at
|
|
8
|
+
* the key first via onTerminalInput and never consume it.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
12
|
+
import { matchesKey, truncateToWidth, type Component, type TUI } from "@earendil-works/pi-tui";
|
|
13
|
+
import type { KitTheme } from "@pi-unipi/core";
|
|
14
|
+
|
|
15
|
+
export const CLEARED_ENTRY = "unipi-cleared-input";
|
|
16
|
+
const PROBE_WIDGET = "unipi-cleared-input-probe";
|
|
17
|
+
const MAX_LINES = 3;
|
|
18
|
+
|
|
19
|
+
interface EditorLike {
|
|
20
|
+
getText(): string;
|
|
21
|
+
addToHistory(text: string): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isEditor(c: unknown): c is EditorLike {
|
|
25
|
+
const e = c as Partial<EditorLike> | null | undefined;
|
|
26
|
+
return typeof e?.getText === "function" && typeof e.addToHistory === "function";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const strike = (s: string) => `\x1b[9m${s}\x1b[29m`;
|
|
30
|
+
|
|
31
|
+
/** `⌫ ~~fix the flaky test~~ ↑ restores` (+ up to two more struck lines). */
|
|
32
|
+
export function clearedLines(t: KitTheme, text: string, width: number): string[] {
|
|
33
|
+
const all = text.replace(/\s+$/u, "").split("\n");
|
|
34
|
+
const shown = all.slice(0, MAX_LINES);
|
|
35
|
+
const out = shown.map((l, i) => truncateToWidth(`${i === 0 ? t.fg("dim", "⌫ ") : " "}${t.fg("dim", strike(l))}`, width));
|
|
36
|
+
if (all.length > shown.length) out.push(t.fg("dim", ` … ${String(all.length - shown.length)} more line${all.length - shown.length === 1 ? "" : "s"}`));
|
|
37
|
+
out[0] = truncateToWidth(`${out[0]!}${t.fg("dim", " ↑ restores")}`, width);
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Decide what to record for a key press. Returns the text to keep, or
|
|
43
|
+
* undefined when the key isn't Ctrl+C / the focus isn't a non-empty editor.
|
|
44
|
+
*/
|
|
45
|
+
export function clearedText(data: string, focused: unknown): string | undefined {
|
|
46
|
+
if (!matchesKey(data, "ctrl+c") || !isEditor(focused)) return undefined;
|
|
47
|
+
const text = focused.getText();
|
|
48
|
+
return text.trim() ? text : undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function installClearedInput(pi: ExtensionAPI): void {
|
|
52
|
+
let tui: TUI | undefined;
|
|
53
|
+
let unsub: (() => void) | undefined;
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
pi.registerEntryRenderer<{ text: string }>(CLEARED_ENTRY, (entry, _opts, theme): Component | undefined => {
|
|
57
|
+
const text = entry.data?.text;
|
|
58
|
+
if (!text) return undefined;
|
|
59
|
+
return { invalidate() {}, render: (w: number) => clearedLines(theme as KitTheme, text, w) };
|
|
60
|
+
});
|
|
61
|
+
} catch {
|
|
62
|
+
/* UI-dependent */
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
pi.on("session_start", (_e, ctx: ExtensionContext) => {
|
|
66
|
+
unsub?.();
|
|
67
|
+
unsub = undefined;
|
|
68
|
+
if (!ctx.hasUI) return;
|
|
69
|
+
try {
|
|
70
|
+
// An empty widget, only to get hold of the TUI (for the focused editor).
|
|
71
|
+
ctx.ui.setWidget(PROBE_WIDGET, (t) => {
|
|
72
|
+
tui = t;
|
|
73
|
+
return { invalidate() {}, render: () => [] };
|
|
74
|
+
}, { placement: "belowEditor" });
|
|
75
|
+
unsub = ctx.ui.onTerminalInput((data) => {
|
|
76
|
+
try {
|
|
77
|
+
const focused = (tui as { getFocusedComponent?: () => unknown } | undefined)?.getFocusedComponent?.();
|
|
78
|
+
const text = clearedText(data, focused);
|
|
79
|
+
if (text === undefined) return undefined;
|
|
80
|
+
(focused as EditorLike).addToHistory(text);
|
|
81
|
+
pi.appendEntry(CLEARED_ENTRY, { text });
|
|
82
|
+
} catch {
|
|
83
|
+
/* never block the key */
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
});
|
|
87
|
+
} catch {
|
|
88
|
+
/* UI-dependent */
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
pi.on("session_shutdown", () => {
|
|
93
|
+
unsub?.();
|
|
94
|
+
unsub = undefined;
|
|
95
|
+
tui = undefined;
|
|
96
|
+
});
|
|
97
|
+
}
|