@mgiles/perk 1.0.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 +105 -0
- package/extension/adapters/planAdapterPlannotator.ts +269 -0
- package/extension/adapters/planAdapterTombell.ts +147 -0
- package/extension/adapters/todoAdapterJuicesharp.ts +105 -0
- package/extension/checkpoints/checkpoints.ts +542 -0
- package/extension/checkpoints/planSteps.ts +108 -0
- package/extension/doors/address.ts +360 -0
- package/extension/doors/askUser.ts +194 -0
- package/extension/doors/ciExecutor.ts +583 -0
- package/extension/doors/land.ts +222 -0
- package/extension/doors/learn.ts +235 -0
- package/extension/doors/learnDocs.ts +99 -0
- package/extension/doors/lifecycleGates.ts +171 -0
- package/extension/doors/prReview.ts +339 -0
- package/extension/doors/ready.ts +86 -0
- package/extension/doors/selfcheck.ts +155 -0
- package/extension/doors/submit.ts +253 -0
- package/extension/factories/objective.ts +240 -0
- package/extension/factories/objectiveAuthor.ts +114 -0
- package/extension/factories/objectiveDraft.ts +343 -0
- package/extension/factories/objectivePlan.ts +838 -0
- package/extension/factories/objectiveSave.ts +285 -0
- package/extension/factories/planDraft.ts +140 -0
- package/extension/factories/planMode.ts +214 -0
- package/extension/factories/planReview.ts +644 -0
- package/extension/factories/planSave.ts +589 -0
- package/extension/factories/planTitle.ts +123 -0
- package/extension/index.ts +459 -0
- package/extension/substrate/bindingDelivery.ts +199 -0
- package/extension/substrate/bindings.ts +180 -0
- package/extension/substrate/cache.ts +163 -0
- package/extension/substrate/coldDoor.ts +226 -0
- package/extension/substrate/config.ts +339 -0
- package/extension/substrate/miniYaml.ts +262 -0
- package/extension/substrate/prompts.ts +35 -0
- package/extension/substrate/providers.ts +177 -0
- package/extension/substrate/registry.ts +62 -0
- package/extension/substrate/resources.ts +41 -0
- package/extension/substrate/result.ts +72 -0
- package/extension/substrate/runId.ts +49 -0
- package/extension/substrate/sessionData.ts +229 -0
- package/extension/substrate/structuredOutput.ts +141 -0
- package/extension/substrate/toolGating.ts +400 -0
- package/extension/substrate/toolParams.ts +106 -0
- package/extension/substrate/workflowState.ts +233 -0
- package/extension/surfaces/footerProvider.ts +43 -0
- package/extension/surfaces/report.ts +34 -0
- package/extension/surfaces/surfaces.ts +460 -0
- package/extension/vendor/btw/btw.ts +964 -0
- package/extension/vendor/btw/core.ts +153 -0
- package/extension/vendor/whimsical/whimsical.ts +485 -0
- package/extension/worker/readOnlySession.ts +282 -0
- package/extension/worker/worker.ts +765 -0
- package/extension/workerMain.ts +150 -0
- package/package.json +55 -0
- package/prompts/README.md +15 -0
- package/prompts/_fixtures/cases.yaml +140 -0
- package/prompts/_fixtures/golden/address-action-model.txt +10 -0
- package/prompts/_fixtures/golden/address-action.txt +10 -0
- package/prompts/_fixtures/golden/address-preview-model.txt +6 -0
- package/prompts/_fixtures/golden/address-preview.txt +6 -0
- package/prompts/_fixtures/golden/hello.txt +1 -0
- package/prompts/_fixtures/golden/implement-github.txt +8 -0
- package/prompts/_fixtures/golden/learn-docs.txt +8 -0
- package/prompts/_fixtures/golden/learn-github.txt +11 -0
- package/prompts/_fixtures/golden/learn-linear.txt +11 -0
- package/prompts/_fixtures/golden/learn-no-ref.txt +8 -0
- package/prompts/_fixtures/golden/learn-other.txt +8 -0
- package/prompts/_fixtures/golden/objective-plan-guidance-linear.txt +8 -0
- package/prompts/_fixtures/golden/objective-plan-guidance.txt +8 -0
- package/prompts/_fixtures/golden/objective-plan-seed-linear.txt +20 -0
- package/prompts/_fixtures/golden/objective-plan-seed.txt +15 -0
- package/prompts/_fixtures/golden/objective-read-linear-nourl.txt +1 -0
- package/prompts/_fixtures/golden/objective-read-linear.txt +1 -0
- package/prompts/_fixtures/golden/plan-read-github.txt +1 -0
- package/prompts/_fixtures/golden/plan-read-linear.txt +1 -0
- package/prompts/_fixtures/golden/plan-read-other.txt +1 -0
- package/prompts/_fixtures/golden/with_include.txt +4 -0
- package/prompts/_fixtures/templates/_greeting.md +1 -0
- package/prompts/_fixtures/templates/hello.md +1 -0
- package/prompts/_fixtures/templates/with_include.md +4 -0
- package/prompts/common/objective-read/linear.md +1 -0
- package/prompts/common/plan-read/github.md +1 -0
- package/prompts/common/plan-read/linear.md +1 -0
- package/prompts/common/plan-read/other.md +1 -0
- package/prompts/stages/address/action.md +10 -0
- package/prompts/stages/address/preview.md +6 -0
- package/prompts/stages/implement.md +8 -0
- package/prompts/stages/learn-docs.md +8 -0
- package/prompts/stages/learn.md +21 -0
- package/prompts/stages/objective-plan/guidance.md +12 -0
- package/prompts/stages/objective-plan/seed.md +20 -0
- package/shared/README.md +29 -0
- package/shared/bindings.yaml +64 -0
- package/shared/contracts-history.md +403 -0
- package/shared/contracts.md +4172 -0
- package/shared/providers.yaml +221 -0
- package/shared/registry.yaml +199 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// btw — extracted pure core (the perk extracted-core pattern: pure helpers split out so they are
|
|
2
|
+
// unit-testable offline, without constructing a live pi session/overlay).
|
|
3
|
+
//
|
|
4
|
+
// Vendored from `mitsuhiko/agent-stuff` `extensions/btw.ts` (MIT) and adapted for perk: the helpers
|
|
5
|
+
// below were lifted verbatim except for the conformance changes called out inline (the extended
|
|
6
|
+
// `stripDynamicSystemPromptFooter` regex; `sideSessionTools`, the perk gate-mirror; and the §5
|
|
7
|
+
// themed-glyph conformance in `renderToolCallLines`/`renderErrorLine` — `❌`→`✗`, running `⚙`→`▸`).
|
|
8
|
+
|
|
9
|
+
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
10
|
+
|
|
11
|
+
/** The minimal theme surface the pure renderers need (pi's real `Theme` satisfies it). */
|
|
12
|
+
export interface ThemeLike {
|
|
13
|
+
fg(color: string, text: string): string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ToolCallStatus = "running" | "done" | "error";
|
|
17
|
+
|
|
18
|
+
export interface ToolCallInfo {
|
|
19
|
+
toolCallId: string;
|
|
20
|
+
toolName: string;
|
|
21
|
+
args: string;
|
|
22
|
+
status: ToolCallStatus;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** A thread item as `formatThread` consumes it (the question/answer subset of `BtwDetails`). */
|
|
26
|
+
export interface ThreadItemLike {
|
|
27
|
+
question: string;
|
|
28
|
+
answer: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Strip pi's dynamic system-prompt footer (the trailing `Current date…` / `Current working
|
|
33
|
+
* directory:` lines) so the side session's seeded system prompt is stable.
|
|
34
|
+
*
|
|
35
|
+
* perk conformance: the live perk/pi prompt footer reads `Current date:` (not `Current date and
|
|
36
|
+
* time:`), so this also strips the `Current date:` form. The original only matched
|
|
37
|
+
* `Current date and time:`.
|
|
38
|
+
*/
|
|
39
|
+
export function stripDynamicSystemPromptFooter(systemPrompt: string): string {
|
|
40
|
+
return systemPrompt
|
|
41
|
+
.replace(/\nCurrent date(?: and time)?:[^\n]*(?:\nCurrent working directory:[^\n]*)?$/u, "")
|
|
42
|
+
.replace(/\nCurrent working directory:[^\n]*$/u, "")
|
|
43
|
+
.trim();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Join the text parts of an assistant message's content into a trimmed string. */
|
|
47
|
+
export function extractText(parts: readonly { type: string; text?: string }[]): string {
|
|
48
|
+
return parts
|
|
49
|
+
.filter((part) => part.type === "text")
|
|
50
|
+
.map((part) => part.text ?? "")
|
|
51
|
+
.join("\n")
|
|
52
|
+
.trim();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Extract the assistant text from a raw stream event message (defensive, untyped input). */
|
|
56
|
+
export function extractEventAssistantText(message: unknown): string {
|
|
57
|
+
if (!message || typeof message !== "object") {
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const maybeMessage = message as { role?: unknown; content?: unknown };
|
|
62
|
+
if (maybeMessage.role !== "assistant" || !Array.isArray(maybeMessage.content)) {
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return maybeMessage.content
|
|
67
|
+
.filter((part): part is { type: "text"; text: string } => {
|
|
68
|
+
return !!part && typeof part === "object" && (part as { type?: unknown }).type === "text";
|
|
69
|
+
})
|
|
70
|
+
.map((part) => part.text)
|
|
71
|
+
.join("\n")
|
|
72
|
+
.trim();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The pure core of `getLastAssistantMessage`: the last `role === "assistant"` message in an array,
|
|
77
|
+
* or null. `btw.ts` calls it with `session.state.messages`.
|
|
78
|
+
*/
|
|
79
|
+
export function lastAssistantMessage<T extends { role: string }>(messages: readonly T[]): T | null {
|
|
80
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
81
|
+
const message = messages[i];
|
|
82
|
+
if (message && message.role === "assistant") {
|
|
83
|
+
return message;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Format a side thread for summary handoff (`User: …\nAssistant: …`, `---`-separated). */
|
|
90
|
+
export function formatThread(thread: readonly ThreadItemLike[]): string {
|
|
91
|
+
return thread
|
|
92
|
+
.map((item) => `User: ${item.question.trim()}\nAssistant: ${item.answer.trim()}`)
|
|
93
|
+
.join("\n\n---\n\n");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Render the first argument of a tool call to a short label (truncated for the transcript). */
|
|
97
|
+
export function formatToolArgs(toolName: string, args: unknown): string {
|
|
98
|
+
if (!args || typeof args !== "object") return "";
|
|
99
|
+
const a = args as Record<string, unknown>;
|
|
100
|
+
switch (toolName) {
|
|
101
|
+
case "bash":
|
|
102
|
+
return typeof a.command === "string"
|
|
103
|
+
? truncateToWidth(a.command.split("\n")[0] ?? "", 50, "…")
|
|
104
|
+
: "";
|
|
105
|
+
case "read":
|
|
106
|
+
case "write":
|
|
107
|
+
case "edit":
|
|
108
|
+
return typeof a.path === "string" ? a.path : "";
|
|
109
|
+
default: {
|
|
110
|
+
const first = Object.values(a)[0];
|
|
111
|
+
return typeof first === "string" ? truncateToWidth(first.split("\n")[0] ?? "", 40, "…") : "";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The gate-mirror decision (plan decision 1): the side session's toolset mirrors perk's read-only
|
|
118
|
+
* gate. When read-only it gets `["read"]` only — a foreign session's `bash` cannot be sandboxed by
|
|
119
|
+
* perk's `isReadOnlyBashCommand`, so `bash` is excluded under read-only — preserving perk's
|
|
120
|
+
* structural read-only guarantee; when read-write it gets the full set.
|
|
121
|
+
*/
|
|
122
|
+
export function sideSessionTools(readOnly: boolean): string[] {
|
|
123
|
+
return readOnly ? ["read"] : ["read", "bash", "edit", "write"];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The themed tool-call transcript lines (§5-conformed glyphs): running `▸` (`accent`), error `✗`
|
|
128
|
+
* (`error`), done `✓` (`success`). Every line is width-truncated (the §4 D9 never-exceed-`width`
|
|
129
|
+
* law). The charter-time `⚙` running glyph is conformed to `▸`.
|
|
130
|
+
*/
|
|
131
|
+
export function renderToolCallLines(
|
|
132
|
+
toolCalls: readonly ToolCallInfo[],
|
|
133
|
+
theme: ThemeLike,
|
|
134
|
+
width: number,
|
|
135
|
+
): string[] {
|
|
136
|
+
const lines: string[] = [];
|
|
137
|
+
for (const tc of toolCalls) {
|
|
138
|
+
const icon = tc.status === "running" ? "▸" : tc.status === "error" ? "✗" : "✓";
|
|
139
|
+
const color = tc.status === "running" ? "accent" : tc.status === "error" ? "error" : "success";
|
|
140
|
+
const label = theme.fg(color, `${icon} `) + theme.fg("toolTitle", tc.toolName);
|
|
141
|
+
const argsText = tc.args ? theme.fg("dim", ` ${tc.args}`) : "";
|
|
142
|
+
lines.push(truncateToWidth(` ${label}${argsText}`, width, ""));
|
|
143
|
+
}
|
|
144
|
+
return lines;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The themed pending-error transcript line (§5-conformed): the charter-time `❌` error glyph is
|
|
149
|
+
* conformed to the themed `✗` (`error`).
|
|
150
|
+
*/
|
|
151
|
+
export function renderErrorLine(theme: ThemeLike, message: string): string {
|
|
152
|
+
return theme.fg("error", `✗ ${message}`);
|
|
153
|
+
}
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
// whimsical — replaces pi's "Working…" streaming message with a random whimsical phrase each turn.
|
|
2
|
+
//
|
|
3
|
+
// Vendored from `mitsuhiko/agent-stuff` `extensions/whimsical.ts` (MIT). Adapted for perk:
|
|
4
|
+
// - `registerWhimsical(pi)` wrapper (the perk registerX pattern) over the original default export;
|
|
5
|
+
// - the per-turn `ctx.ui.setWorkingMessage(...)` calls route through the headless-safe
|
|
6
|
+
// `setWorkingMessage` surfaces seam (charter §6: text-only, permitted, headless-no-op — distinct
|
|
7
|
+
// from the declined `setWorkingIndicator`).
|
|
8
|
+
//
|
|
9
|
+
// Ships always on — no config toggle (plan decision 3).
|
|
10
|
+
|
|
11
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
12
|
+
import { setWorkingMessage } from "../../surfaces/surfaces.ts";
|
|
13
|
+
|
|
14
|
+
export const messages = [
|
|
15
|
+
// Short
|
|
16
|
+
"Schlepping...",
|
|
17
|
+
"Combobulating...",
|
|
18
|
+
"Doing...",
|
|
19
|
+
"Channelling...",
|
|
20
|
+
"Vibing...",
|
|
21
|
+
"Concocting...",
|
|
22
|
+
"Spelunking...",
|
|
23
|
+
"Transmuting...",
|
|
24
|
+
"Imagining...",
|
|
25
|
+
"Pontificating...",
|
|
26
|
+
"Whirring...",
|
|
27
|
+
"Cogitating...",
|
|
28
|
+
"Honking...",
|
|
29
|
+
"Flibbertigibbeting...",
|
|
30
|
+
"Noodling...",
|
|
31
|
+
"Percolating...",
|
|
32
|
+
"Ruminating...",
|
|
33
|
+
"Simmering...",
|
|
34
|
+
"Marinating...",
|
|
35
|
+
"Fermenting...",
|
|
36
|
+
"Gestating...",
|
|
37
|
+
"Hatching...",
|
|
38
|
+
"Brewing...",
|
|
39
|
+
"Steeping...",
|
|
40
|
+
"Contemplating...",
|
|
41
|
+
"Musing...",
|
|
42
|
+
"Pondering...",
|
|
43
|
+
"Mulling...",
|
|
44
|
+
"Daydreaming...",
|
|
45
|
+
"Woolgathering...",
|
|
46
|
+
"Dithering...",
|
|
47
|
+
"Faffing...",
|
|
48
|
+
"Puttering...",
|
|
49
|
+
"Tinkering...",
|
|
50
|
+
"Fiddling...",
|
|
51
|
+
"Noodging...",
|
|
52
|
+
"Finagling...",
|
|
53
|
+
"Wrangling...",
|
|
54
|
+
"Jiggling...",
|
|
55
|
+
"Wiggling...",
|
|
56
|
+
"Shimmying...",
|
|
57
|
+
"Galumphing...",
|
|
58
|
+
"Perambulating...",
|
|
59
|
+
"Meandering...",
|
|
60
|
+
"Traipsing...",
|
|
61
|
+
"Moseying...",
|
|
62
|
+
"Sauntering...",
|
|
63
|
+
"Ambling...",
|
|
64
|
+
"Pottering...",
|
|
65
|
+
"Bumbling...",
|
|
66
|
+
"Futzing...",
|
|
67
|
+
"Schmalzing...",
|
|
68
|
+
"Kerfuffling...",
|
|
69
|
+
"Bamboozling...",
|
|
70
|
+
"Discombobulating...",
|
|
71
|
+
"Recombobulating...",
|
|
72
|
+
"Unbefuddling...",
|
|
73
|
+
"Defenestrating...",
|
|
74
|
+
"Confabulating...",
|
|
75
|
+
"Persnicketing...",
|
|
76
|
+
"Flummoxing...",
|
|
77
|
+
"Befuddling...",
|
|
78
|
+
"Snorkeling...",
|
|
79
|
+
"Yodeling...",
|
|
80
|
+
"Zigzagging...",
|
|
81
|
+
"Ricocheting...",
|
|
82
|
+
"Somersaulting...",
|
|
83
|
+
"Pirouetting...",
|
|
84
|
+
"Canoodling...",
|
|
85
|
+
"Schmoozing...",
|
|
86
|
+
"Kibbitzing...",
|
|
87
|
+
"Skedaddling...",
|
|
88
|
+
"Scampering...",
|
|
89
|
+
"Skittering...",
|
|
90
|
+
"Sashaying...",
|
|
91
|
+
"Swashbuckling...",
|
|
92
|
+
"Oscillating...",
|
|
93
|
+
"Undulating...",
|
|
94
|
+
"Pulsating...",
|
|
95
|
+
"Effervescing...",
|
|
96
|
+
"Fizzing...",
|
|
97
|
+
"Bubbling...",
|
|
98
|
+
"Perplexing...",
|
|
99
|
+
"Mystifying...",
|
|
100
|
+
"Enchanting...",
|
|
101
|
+
"Bewitching...",
|
|
102
|
+
"Beguiling...",
|
|
103
|
+
"Mesmerizing...",
|
|
104
|
+
"Bedazzling...",
|
|
105
|
+
"Sparkling...",
|
|
106
|
+
"Glittering...",
|
|
107
|
+
"Scintillating...",
|
|
108
|
+
"Coruscating...",
|
|
109
|
+
"Phosphorescing...",
|
|
110
|
+
"Luminescing...",
|
|
111
|
+
"Sublimating...",
|
|
112
|
+
"Synthesizing...",
|
|
113
|
+
"Amalgamating...",
|
|
114
|
+
"Procrastinating...",
|
|
115
|
+
"Dillydallying...",
|
|
116
|
+
"Lollygagging...",
|
|
117
|
+
"Dawdling...",
|
|
118
|
+
"Malingering...",
|
|
119
|
+
"Skulking...",
|
|
120
|
+
"Lurking...",
|
|
121
|
+
"Sleuthing...",
|
|
122
|
+
"Rummaging...",
|
|
123
|
+
"Fossicking...",
|
|
124
|
+
"Foraging...",
|
|
125
|
+
"Scavenging...",
|
|
126
|
+
"Absquatulating...",
|
|
127
|
+
"Vamoosing...",
|
|
128
|
+
"Absconding...",
|
|
129
|
+
"Grooving...",
|
|
130
|
+
"Jamming...",
|
|
131
|
+
"Improvising...",
|
|
132
|
+
"Extemporizing...",
|
|
133
|
+
"Freestyling...",
|
|
134
|
+
"Frolicking...",
|
|
135
|
+
"Gamboling...",
|
|
136
|
+
"Blorping...",
|
|
137
|
+
"Flonking...",
|
|
138
|
+
"Snurfling...",
|
|
139
|
+
"Whomping...",
|
|
140
|
+
"Zorping...",
|
|
141
|
+
"Biffing...",
|
|
142
|
+
"Splunging...",
|
|
143
|
+
"Thwacking...",
|
|
144
|
+
"Gonkulating...",
|
|
145
|
+
"Splorfing...",
|
|
146
|
+
"Wibbling...",
|
|
147
|
+
"Wobbling...",
|
|
148
|
+
"Squonking...",
|
|
149
|
+
"Plonking...",
|
|
150
|
+
"Bonking...",
|
|
151
|
+
"Zonking...",
|
|
152
|
+
"Flumping...",
|
|
153
|
+
"Clomping...",
|
|
154
|
+
"Squelching...",
|
|
155
|
+
"Schlurping...",
|
|
156
|
+
"Glurping...",
|
|
157
|
+
"Burbling...",
|
|
158
|
+
"Gurgling...",
|
|
159
|
+
"Splooshing...",
|
|
160
|
+
"Whooshing...",
|
|
161
|
+
"Swooshing...",
|
|
162
|
+
"Kerplunking...",
|
|
163
|
+
"Thunking...",
|
|
164
|
+
"Clunking...",
|
|
165
|
+
"Clanking...",
|
|
166
|
+
"Rattling...",
|
|
167
|
+
"Jostling...",
|
|
168
|
+
"Rustling...",
|
|
169
|
+
"Bustling...",
|
|
170
|
+
"Hustling...",
|
|
171
|
+
"Miffing...",
|
|
172
|
+
"Boffing...",
|
|
173
|
+
"Snazzifying...",
|
|
174
|
+
"Pizzazzing...",
|
|
175
|
+
"Razzmatazzing...",
|
|
176
|
+
"Bedoodling...",
|
|
177
|
+
"Doodling...",
|
|
178
|
+
"Scribbling...",
|
|
179
|
+
"Squiggling...",
|
|
180
|
+
"Wriggling...",
|
|
181
|
+
"Niggling...",
|
|
182
|
+
"Higgling...",
|
|
183
|
+
"Piggling...",
|
|
184
|
+
"Figgling...",
|
|
185
|
+
"Gibbering...",
|
|
186
|
+
"Jabbering...",
|
|
187
|
+
"Blathering...",
|
|
188
|
+
"Blithering...",
|
|
189
|
+
"Withering...",
|
|
190
|
+
"Slithering...",
|
|
191
|
+
"Tethering...",
|
|
192
|
+
"Feathering...",
|
|
193
|
+
"Weathering...",
|
|
194
|
+
"Leathering...",
|
|
195
|
+
"Heathering...",
|
|
196
|
+
"Smoldering...",
|
|
197
|
+
"Moldering...",
|
|
198
|
+
"Shouldering...",
|
|
199
|
+
"Bouldering...",
|
|
200
|
+
"Tottering...",
|
|
201
|
+
"Teetering...",
|
|
202
|
+
"Tittering...",
|
|
203
|
+
"Flittering...",
|
|
204
|
+
"Jittering...",
|
|
205
|
+
"Frittering...",
|
|
206
|
+
"Twittering...",
|
|
207
|
+
"Nattering...",
|
|
208
|
+
"Chattering...",
|
|
209
|
+
"Clattering...",
|
|
210
|
+
"Splattering...",
|
|
211
|
+
"Battering...",
|
|
212
|
+
"Scattering...",
|
|
213
|
+
"Shattering...",
|
|
214
|
+
"Flattering...",
|
|
215
|
+
"Pattering...",
|
|
216
|
+
"Tattering...",
|
|
217
|
+
"Mattering...",
|
|
218
|
+
"Yammering...",
|
|
219
|
+
"Hammering...",
|
|
220
|
+
"Stammering...",
|
|
221
|
+
"Clamoring...",
|
|
222
|
+
"Glamoring...",
|
|
223
|
+
"Enamoring...",
|
|
224
|
+
"Shimmering...",
|
|
225
|
+
"Glimmering...",
|
|
226
|
+
"Brimming...",
|
|
227
|
+
"Skimming...",
|
|
228
|
+
"Trimming...",
|
|
229
|
+
"Primming...",
|
|
230
|
+
"Whimming...",
|
|
231
|
+
"Humming...",
|
|
232
|
+
"Strumming...",
|
|
233
|
+
"Thrumming...",
|
|
234
|
+
"Drumming...",
|
|
235
|
+
"Plumbing...",
|
|
236
|
+
"Thumbing...",
|
|
237
|
+
"Numbing...",
|
|
238
|
+
"Fumbling...",
|
|
239
|
+
"Grumbling...",
|
|
240
|
+
"Mumbling...",
|
|
241
|
+
"Rumbling...",
|
|
242
|
+
"Stumbling...",
|
|
243
|
+
"Tumbling...",
|
|
244
|
+
"Crumbling...",
|
|
245
|
+
"Jumbling...",
|
|
246
|
+
"Humbling...",
|
|
247
|
+
"Bungling...",
|
|
248
|
+
"Jungling...",
|
|
249
|
+
"Mangling...",
|
|
250
|
+
"Wangling...",
|
|
251
|
+
"Dangling...",
|
|
252
|
+
"Tangling...",
|
|
253
|
+
"Jangling...",
|
|
254
|
+
"Angling...",
|
|
255
|
+
"Struggling...",
|
|
256
|
+
"Mingling...",
|
|
257
|
+
"Tingling...",
|
|
258
|
+
"Jingling...",
|
|
259
|
+
"Singling...",
|
|
260
|
+
"Ringling...",
|
|
261
|
+
"Kingling...",
|
|
262
|
+
|
|
263
|
+
// Long
|
|
264
|
+
"Consulting the void...",
|
|
265
|
+
"Asking the electrons...",
|
|
266
|
+
"Bribing the compiler...",
|
|
267
|
+
"Negotiating with entropy...",
|
|
268
|
+
"Whispering to the bits...",
|
|
269
|
+
"Tickling the stack...",
|
|
270
|
+
"Massaging the heap...",
|
|
271
|
+
"Appeasing the garbage collector...",
|
|
272
|
+
"Summoning semicolons...",
|
|
273
|
+
"Herding pointers...",
|
|
274
|
+
"Untangling spaghetti...",
|
|
275
|
+
"Polishing the algorithms...",
|
|
276
|
+
"Waxing philosophical...",
|
|
277
|
+
"Consulting ancient scrolls...",
|
|
278
|
+
"Reading tea leaves...",
|
|
279
|
+
"Shaking the magic 8-ball...",
|
|
280
|
+
"Sacrificing to the demo gods...",
|
|
281
|
+
"Warming up the hamsters...",
|
|
282
|
+
"Spinning up the squirrels...",
|
|
283
|
+
"Caffeinating...",
|
|
284
|
+
"Existentially questioning...",
|
|
285
|
+
"Having a little think...",
|
|
286
|
+
"Stroking chin thoughtfully...",
|
|
287
|
+
"Squinting at the problem...",
|
|
288
|
+
"Staring into the abyss...",
|
|
289
|
+
"Abyss staring back...",
|
|
290
|
+
"Achieving enlightenment...",
|
|
291
|
+
"Transcending mere computation...",
|
|
292
|
+
"Ascending to a higher plane...",
|
|
293
|
+
"Communing with the machine spirit...",
|
|
294
|
+
"Performing arcane rituals...",
|
|
295
|
+
"Invoking elder functions...",
|
|
296
|
+
"Consulting the oracle...",
|
|
297
|
+
"Divining the answer...",
|
|
298
|
+
"Scrying the codebase...",
|
|
299
|
+
"Dowsing for bugs...",
|
|
300
|
+
"Rearranging deck chairs...",
|
|
301
|
+
"Shuffling bits around...",
|
|
302
|
+
"Aligning the chakras...",
|
|
303
|
+
"Reticulating splines...",
|
|
304
|
+
"Reversing the polarity...",
|
|
305
|
+
"Calibrating the flux capacitor...",
|
|
306
|
+
"Charging the crystals...",
|
|
307
|
+
"Tuning the vibrations...",
|
|
308
|
+
"Adjusting the cosmic frequency...",
|
|
309
|
+
"Waiting for a sign...",
|
|
310
|
+
"Hoping for the best...",
|
|
311
|
+
"Manifesting solutions...",
|
|
312
|
+
"Willing it into existence...",
|
|
313
|
+
"Believing really hard...",
|
|
314
|
+
"Politely asking the CPU...",
|
|
315
|
+
"Bribing the runtime...",
|
|
316
|
+
"Flirting with the database...",
|
|
317
|
+
"Sweet-talking the API...",
|
|
318
|
+
"Negotiating with deadlines...",
|
|
319
|
+
"Having words with the cache...",
|
|
320
|
+
"Reasoning with the memory...",
|
|
321
|
+
"Pleading with the logs...",
|
|
322
|
+
"Bargaining with fate...",
|
|
323
|
+
"Making offerings to the CI...",
|
|
324
|
+
"Praying to the uptime gods...",
|
|
325
|
+
"Consulting the rubber duck...",
|
|
326
|
+
"Interrogating the stack trace...",
|
|
327
|
+
"Cross-examining the debugger...",
|
|
328
|
+
"Petitioning the kernel...",
|
|
329
|
+
"Lobbying the scheduler...",
|
|
330
|
+
"Schmoozing the network...",
|
|
331
|
+
"Buttering up the firewall...",
|
|
332
|
+
"Wining and dining the servers...",
|
|
333
|
+
"Taking the bytes out for lunch...",
|
|
334
|
+
"Giving the code a pep talk...",
|
|
335
|
+
"Reading the room...",
|
|
336
|
+
"Checking under the hood...",
|
|
337
|
+
"Kicking the tires...",
|
|
338
|
+
"Shaking loose the cobwebs...",
|
|
339
|
+
"Dusting off the neurons...",
|
|
340
|
+
"Greasing the gears...",
|
|
341
|
+
"Oiling the cogs...",
|
|
342
|
+
"Winding up the clockwork...",
|
|
343
|
+
"Stoking the furnace...",
|
|
344
|
+
"Feeding the machine...",
|
|
345
|
+
"Watering the logic tree...",
|
|
346
|
+
"Pruning the decision branches...",
|
|
347
|
+
"Harvesting the outputs...",
|
|
348
|
+
"Planting computational seeds...",
|
|
349
|
+
"Nurturing the algorithm...",
|
|
350
|
+
"Raising the exceptions...",
|
|
351
|
+
"Taming wild pointers...",
|
|
352
|
+
"Herding cats in memory...",
|
|
353
|
+
"Teaching old code new tricks...",
|
|
354
|
+
"Whispering sweet nothings to the compiler...",
|
|
355
|
+
"Serenading the syntax...",
|
|
356
|
+
"Dancing with dependencies...",
|
|
357
|
+
"Waltzing through the codebase...",
|
|
358
|
+
"Tangoing with type errors...",
|
|
359
|
+
"Doing the deployment dance...",
|
|
360
|
+
"Having a moment of clarity...",
|
|
361
|
+
"Experiencing a flash of insight...",
|
|
362
|
+
"Channeling the ancient developers...",
|
|
363
|
+
"Receiving transmissions from the cloud...",
|
|
364
|
+
"Asking the hamsters to run faster...",
|
|
365
|
+
"Convincing the pixels to cooperate...",
|
|
366
|
+
"Teaching electrons new tricks...",
|
|
367
|
+
"Bribing the byte fairies...",
|
|
368
|
+
"Whispering passwords to the void...",
|
|
369
|
+
"Negotiating with cosmic rays...",
|
|
370
|
+
"Flattering the floating points...",
|
|
371
|
+
"Seducing the semicolons...",
|
|
372
|
+
"Wooing the while loops...",
|
|
373
|
+
"Charming the curly braces...",
|
|
374
|
+
"Hypnotizing the hash tables...",
|
|
375
|
+
"Mesmerizing the memory banks...",
|
|
376
|
+
"Enchanting the error handlers...",
|
|
377
|
+
"Bewitching the boolean logic...",
|
|
378
|
+
"Spellbinding the stack frames...",
|
|
379
|
+
"Hexing the hexadecimals...",
|
|
380
|
+
"Jinxing the JSON parsers...",
|
|
381
|
+
"Cursing the cache misses...",
|
|
382
|
+
"Blessing the build process...",
|
|
383
|
+
"Anointing the algorithms...",
|
|
384
|
+
"Consecrating the callbacks...",
|
|
385
|
+
"Sanctifying the source code...",
|
|
386
|
+
"Exorcising the exceptions...",
|
|
387
|
+
"Purifying the parameters...",
|
|
388
|
+
"Cleansing the closures...",
|
|
389
|
+
"Baptizing the binary...",
|
|
390
|
+
"Absolving the abstractions...",
|
|
391
|
+
"Redeeming the recursion...",
|
|
392
|
+
"Forgiving the for loops...",
|
|
393
|
+
"Pardoning the pointers...",
|
|
394
|
+
"Liberating the lambdas...",
|
|
395
|
+
"Emancipating the enums...",
|
|
396
|
+
"Freeing the functions...",
|
|
397
|
+
"Releasing the references...",
|
|
398
|
+
"Unbinding the variables...",
|
|
399
|
+
"Untying the type knots...",
|
|
400
|
+
"Unraveling the regex...",
|
|
401
|
+
"Decoding the mysteries...",
|
|
402
|
+
"Cracking the conundrums...",
|
|
403
|
+
"Solving the riddles of RAM...",
|
|
404
|
+
"Unlocking the secrets of silicon...",
|
|
405
|
+
"Discovering hidden semicolons...",
|
|
406
|
+
"Unearthing buried bugs...",
|
|
407
|
+
"Excavating ancient APIs...",
|
|
408
|
+
"Archeologically analyzing the architecture...",
|
|
409
|
+
"Fossil hunting in the functions...",
|
|
410
|
+
"Spelunking through the stack...",
|
|
411
|
+
"Scuba diving in the data...",
|
|
412
|
+
"Snorkeling through the streams...",
|
|
413
|
+
"Parasailing past the parameters...",
|
|
414
|
+
"Hang gliding through the heap...",
|
|
415
|
+
"Bungee jumping into the backend...",
|
|
416
|
+
"Skydiving through the source...",
|
|
417
|
+
"Surfing the syntax waves...",
|
|
418
|
+
"Skateboarding down the stack trace...",
|
|
419
|
+
"Snowboarding through the schemas...",
|
|
420
|
+
"Mountain climbing the modules...",
|
|
421
|
+
"Hiking through the headers...",
|
|
422
|
+
"Trekking through the trees...",
|
|
423
|
+
"Backpacking through the binaries...",
|
|
424
|
+
"Camping in the codebase...",
|
|
425
|
+
"Glamping in the globals...",
|
|
426
|
+
"Picnicking with the processes...",
|
|
427
|
+
"Barbecuing the bugs...",
|
|
428
|
+
"Roasting the race conditions...",
|
|
429
|
+
"Grilling the glitches...",
|
|
430
|
+
"Sautéing the syntax errors...",
|
|
431
|
+
"Flambéing the failures...",
|
|
432
|
+
"Caramelizing the callbacks...",
|
|
433
|
+
"Braising the breakpoints...",
|
|
434
|
+
"Poaching the pointers...",
|
|
435
|
+
"Blanching the branches...",
|
|
436
|
+
"Searing the segments...",
|
|
437
|
+
"Smoking the subroutines...",
|
|
438
|
+
"Curing the code smells...",
|
|
439
|
+
"Pickling the packages...",
|
|
440
|
+
"Preserving the protocols...",
|
|
441
|
+
"Canning the constants...",
|
|
442
|
+
"Bottling the buffers...",
|
|
443
|
+
"Jarring the JavaScript...",
|
|
444
|
+
"Decanting the data structures...",
|
|
445
|
+
"Aerating the arrays...",
|
|
446
|
+
"Letting the logic breathe...",
|
|
447
|
+
"Aging the algorithms gracefully...",
|
|
448
|
+
"Maturing the methods...",
|
|
449
|
+
"Ripening the results...",
|
|
450
|
+
"Seasoning the solutions...",
|
|
451
|
+
"Spicing up the specs...",
|
|
452
|
+
"Garnishing the getters...",
|
|
453
|
+
"Plating the output nicely...",
|
|
454
|
+
"Presenting with pizzazz...",
|
|
455
|
+
"Adding a dash of elegance...",
|
|
456
|
+
"Sprinkling some magic dust...",
|
|
457
|
+
"Drizzling debug sauce...",
|
|
458
|
+
"Folding in the features...",
|
|
459
|
+
"Whisking the widgets...",
|
|
460
|
+
"Kneading the namespaces...",
|
|
461
|
+
"Rolling out the runtime...",
|
|
462
|
+
"Proofing the promises...",
|
|
463
|
+
"Letting the dough rise...",
|
|
464
|
+
"Baking at 350 kilobytes...",
|
|
465
|
+
"Frosting the functions...",
|
|
466
|
+
"Decorating the deployment...",
|
|
467
|
+
"Icing the interfaces...",
|
|
468
|
+
"Glazing the graphics...",
|
|
469
|
+
"Topping with tests...",
|
|
470
|
+
"Cherry-picking the commits...",
|
|
471
|
+
];
|
|
472
|
+
|
|
473
|
+
export function pickRandom(): string {
|
|
474
|
+
return messages[Math.floor(Math.random() * messages.length)] ?? messages[0] ?? "Working...";
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
export function registerWhimsical(pi: ExtensionAPI): void {
|
|
478
|
+
pi.on("turn_start", async (_event, ctx) => {
|
|
479
|
+
setWorkingMessage(ctx, pickRandom());
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
pi.on("turn_end", async (_event, ctx) => {
|
|
483
|
+
setWorkingMessage(ctx); // Reset for next time (undefined restores pi's default)
|
|
484
|
+
});
|
|
485
|
+
}
|