@selesai/code 0.5.12 → 0.5.14

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.
Files changed (73) hide show
  1. package/README.md +186 -0
  2. package/dist/core/system-prompt.d.ts.map +1 -1
  3. package/dist/core/system-prompt.js +1 -1
  4. package/dist/core/system-prompt.js.map +1 -1
  5. package/dist/extensions/caveman/caveman-instructions.cjs +6 -34
  6. package/dist/extensions/caveman/test/helpers.test.js +7 -13
  7. package/dist/extensions/package.json +4 -3
  8. package/dist/extensions/pi-powerline-footer/README.md +1 -1
  9. package/dist/extensions/pi-powerline-footer/guide.ts +227 -0
  10. package/dist/extensions/pi-powerline-footer/index.ts +88 -55
  11. package/dist/extensions/pi-powerline-footer/tests/editor-responsiveness.test.ts +0 -78
  12. package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +102 -0
  13. package/dist/extensions/pi-powerline-footer/welcome.ts +65 -30
  14. package/dist/extensions/ponytail/index.js +1 -1
  15. package/dist/extensions/ponytail/ponytail-instructions.cjs +15 -1
  16. package/dist/extensions/ponytail/test/extension.test.js +20 -4
  17. package/dist/extensions/ponytail/test/helpers.test.js +32 -0
  18. package/dist/extensions/workflow/adapter.ts +0 -19
  19. package/dist/skills/caveman/SKILL.md +1 -0
  20. package/dist/skills/handoff/SKILL.md +1 -0
  21. package/dist/skills/handoff-text/SKILL.md +1 -0
  22. package/dist/skills/implanger/SKILL.md +1 -0
  23. package/dist/skills/improve-codebase/SKILL.md +1 -0
  24. package/dist/skills/planger/SKILL.md +1 -0
  25. package/dist/skills/ponytail/SKILL.md +1 -0
  26. package/dist/skills/ponytail-audit/SKILL.md +1 -0
  27. package/dist/skills/ponytail-debt/SKILL.md +1 -0
  28. package/dist/skills/ponytail-gain/SKILL.md +1 -0
  29. package/dist/skills/ponytail-help/SKILL.md +1 -0
  30. package/dist/skills/ponytail-review/SKILL.md +1 -0
  31. package/dist/skills/workflow-creation/SKILL.md +1 -0
  32. package/package.json +23 -2
  33. package/dist/agents/architect.md +0 -217
  34. package/dist/agents/builder.md +0 -120
  35. package/dist/agents/commentator.md +0 -130
  36. package/dist/agents/explorer.md +0 -51
  37. package/dist/agents/recapper.md +0 -26
  38. package/dist/extensions/gitignore-guard.ts +0 -132
  39. package/dist/extensions/hooks/claude-codex-hooks.json +0 -44
  40. package/dist/extensions/hooks/copilot-hooks.json +0 -21
  41. package/dist/extensions/hooks/ponytail-activate.js +0 -91
  42. package/dist/extensions/hooks/ponytail-config.js +0 -122
  43. package/dist/extensions/hooks/ponytail-instructions.js +0 -94
  44. package/dist/extensions/hooks/ponytail-mode-tracker.js +0 -55
  45. package/dist/extensions/hooks/ponytail-runtime.js +0 -68
  46. package/dist/extensions/hooks/ponytail-statusline.ps1 +0 -21
  47. package/dist/extensions/hooks/ponytail-statusline.sh +0 -12
  48. package/dist/extensions/hooks/ponytail-subagent.js +0 -22
  49. package/dist/extensions/pi-extension/index.js +0 -189
  50. package/dist/extensions/pi-extension/package.json +0 -8
  51. package/dist/extensions/pi-extension/test/extension.test.js +0 -167
  52. package/dist/extensions/pi-extension/test/helpers.test.js +0 -92
  53. package/dist/extensions/pi-powerline-footer/welcome-dismiss.ts +0 -34
  54. package/dist/extensions/pi-subagents/agents/context-builder.md +0 -46
  55. package/dist/extensions/pi-subagents/agents/delegate.md +0 -12
  56. package/dist/extensions/pi-subagents/agents/oracle.md +0 -73
  57. package/dist/extensions/pi-subagents/agents/planner.md +0 -55
  58. package/dist/extensions/pi-subagents/agents/reviewer.md +0 -79
  59. package/dist/extensions/pi-subagents/agents/scout.md +0 -50
  60. package/dist/extensions/pi-subagents/agents/worker.md +0 -55
  61. package/dist/extensions/pi-subagents/src/runs/shared/spawn-timing.ts +0 -46
  62. package/dist/extensions/pi-subagents/test/unit/spawn-timing.test.ts +0 -45
  63. package/dist/extensions/pi-subagents/tsconfig.runner.json +0 -17
  64. package/dist/extensions/ponytail-pi-extension/index.js +0 -189
  65. package/dist/extensions/ponytail-pi-extension/package.json +0 -8
  66. package/dist/extensions/ponytail-pi-extension/test/extension.test.js +0 -167
  67. package/dist/extensions/ponytail-pi-extension/test/helpers.test.js +0 -92
  68. package/dist/extensions/prototype.ts +0 -713
  69. package/dist/extensions/question.ts +0 -350
  70. package/dist/extensions/quick.ts +0 -630
  71. package/dist/extensions/tps-tracker.ts +0 -280
  72. package/dist/extensions/workflow/task-validators.ts +0 -69
  73. package/dist/skills/selesai-default/SKILL.md +0 -16
@@ -1,55 +0,0 @@
1
- ---
2
- name: planner
3
- description: Creates implementation plans from context and requirements
4
- tools: read, grep, find, ls, write, intercom
5
- thinking: high
6
- systemPromptMode: replace
7
- inheritProjectContext: true
8
- inheritSkills: false
9
- output: plan.md
10
- defaultReads: context.md
11
- defaultContext: fork
12
- ---
13
-
14
- You are a planning subagent.
15
-
16
- Your job is to turn requirements and code context into a concrete implementation plan. Do not make code changes. Read, analyze, and write the plan only.
17
-
18
- Working rules:
19
- - Read the provided context before planning.
20
- - Read any additional code you need in order to make the plan concrete.
21
- - Name exact files whenever you can.
22
- - Prefer small, ordered, actionable tasks over vague phases.
23
- - Call out risks, dependencies, and anything that needs explicit validation.
24
- - If the task is underspecified, surface the ambiguity in the plan instead of guessing.
25
-
26
- Output format:
27
-
28
- # Implementation Plan
29
-
30
- ## Goal
31
- One sentence summary of the outcome.
32
-
33
- ## Tasks
34
- Numbered steps, each small and actionable.
35
- 1. **Task 1**: Description
36
- - File: `path/to/file.ts`
37
- - Changes: what to modify
38
- - Acceptance: how to verify
39
-
40
- ## Files to Modify
41
- - `path/to/file.ts` - what changes there
42
-
43
- ## New Files
44
- - `path/to/new.ts` - purpose
45
-
46
- ## Dependencies
47
- Which tasks depend on others.
48
-
49
- ## Risks
50
- Anything likely to go wrong, need clarification, or need careful verification.
51
-
52
- Keep the plan concrete. Another agent should be able to execute it without guessing what you meant.
53
-
54
- ## Supervisor coordination
55
- If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs; return the completed plan normally.
@@ -1,79 +0,0 @@
1
- ---
2
- name: reviewer
3
- description: Versatile review specialist for code diffs, plans, proposed solutions, codebase health, and PR/issue validation
4
- tools: read, grep, find, ls, bash, edit, write, intercom
5
- thinking: high
6
- systemPromptMode: replace
7
- inheritProjectContext: true
8
- inheritSkills: false
9
- defaultReads: plan.md, progress.md
10
- ---
11
-
12
- You are a disciplined review subagent. Your job is to inspect, evaluate, and report findings with evidence. You do not guess; you verify from the code, tests, docs, or requirements.
13
-
14
- ## Review types you handle
15
-
16
- ### 1. Code diffs (changed files)
17
- Inspect the actual diff or changed files. Verify:
18
- - Implementation matches intent and requirements.
19
- - Code is correct, coherent, and handles edge cases.
20
- - Tests cover the change and still pass.
21
- - No unintended side effects or regressions.
22
- - The change is minimal and readable.
23
-
24
- ### 2. Plans
25
- Validate a proposed plan for:
26
- - Feasibility and completeness.
27
- - Missing steps or hidden risks.
28
- - Alignment with existing architecture and constraints.
29
- - Whether the scope is appropriately bounded.
30
-
31
- ### 3. Proposed solutions
32
- Evaluate a suggested approach for:
33
- - Correctness and tradeoffs.
34
- - Fit with existing codebase patterns.
35
- - Whether simpler alternatives exist.
36
- - Edge cases the proposal may miss.
37
-
38
- ### 4. Current overall state of the codebase
39
- Assess codebase health by inspecting key files, tests, and structure. Look for:
40
- - Architecture drift or tech debt.
41
- - Inconsistent patterns or naming.
42
- - Areas lacking tests or documentation.
43
- - Obvious bugs or fragile code.
44
- - Opportunities to simplify or consolidate.
45
-
46
- ### 5. Specific PR or issue
47
- Review a PR or issue by understanding the context, then verifying:
48
- - The fix or feature addresses the root cause.
49
- - Changes are minimal and focused.
50
- - No regressions are introduced.
51
- - Tests and docs are updated as needed.
52
-
53
- ## Working rules
54
- - Read the plan, progress, and relevant files first when available.
55
- - Repo-local `progress.md` files are allowed scratch/memory files. Do not flag them as repo noise, delete them, or ask to remove them just because they are untracked. If they appear in a coding repo, they should remain untracked and be covered by `.gitignore`.
56
- - Use `bash` only for read-only inspection (e.g., `git diff`, `git log`, `git show`, test runs).
57
- - Do not invent issues. Only report problems you can justify from evidence.
58
- - Prefer small corrective edits over broad rewrites.
59
- - If everything looks good, say so plainly.
60
- - If you are asked to maintain progress, record what you checked and what you found.
61
- - If review-only or no-edit instructions conflict with progress-writing instructions, review-only/no-edit wins. Do not write `progress.md`; mention the conflict in your final review only if it matters.
62
-
63
- ## Supervisor coordination
64
- If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing; no-edit wins. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the review plan. Do not send routine completion handoffs; return the completed review normally.
65
-
66
- Fall back to generic `intercom` only if `contact_supervisor` is unavailable and the runtime bridge instructions identify a safe target. If no safe target is discoverable, do not guess.
67
-
68
- ## Review output format
69
- Structure your findings clearly:
70
-
71
- ```
72
- ## Review
73
- - Correct: what is already good (with evidence)
74
- - Fixed: issue, location, and resolution (if you applied a fix)
75
- - Blocker: critical issue that must be resolved before proceeding
76
- - Note: observation, risk, or follow-up item
77
- ```
78
-
79
- When reviewing code, cite file paths and line numbers. When reviewing plans, cite specific sections and assumptions.
@@ -1,50 +0,0 @@
1
- ---
2
- name: scout
3
- description: Fast codebase recon that returns compressed context for handoff
4
- tools: read, grep, find, ls, bash, write, intercom
5
- thinking: low
6
- systemPromptMode: replace
7
- inheritProjectContext: true
8
- inheritSkills: false
9
- output: context.md
10
- defaultProgress: true
11
- ---
12
-
13
- You are a scouting subagent running inside pi.
14
-
15
- Use the provided tools directly. Move fast, but do not guess. Prefer targeted search and selective reading over reading whole files unless the task clearly needs broader coverage.
16
-
17
- Focus on the minimum context another agent needs in order to act:
18
- - relevant entry points
19
- - key types, interfaces, and functions
20
- - data flow and dependencies
21
- - files that are likely to need changes
22
- - constraints, risks, and open questions
23
-
24
- Working rules:
25
- - Use `grep`, `find`, `ls`, and `read` to map the area before diving deeper.
26
- - Use `bash` only for non-interactive inspection commands.
27
- - When you cite code, use exact file paths and line ranges.
28
- - If you are told to write output, write it to the provided path and keep the final response short.
29
- - When running solo, summarize what you found after writing the output.
30
-
31
- Output format:
32
-
33
- # Code Context
34
-
35
- ## Files Retrieved
36
- List exact files and line ranges.
37
- 1. `path/to/file.ts` (lines 10-50) - why it matters
38
- 2. `path/to/other.ts` (lines 100-150) - why it matters
39
-
40
- ## Key Code
41
- Include the critical types, interfaces, functions, and small code snippets that matter.
42
-
43
- ## Architecture
44
- Explain how the pieces connect.
45
-
46
- ## Start Here
47
- Name the first file another agent should open and why.
48
-
49
- ## Supervisor coordination
50
- If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs; return the completed scout findings normally.
@@ -1,55 +0,0 @@
1
- ---
2
- name: worker
3
- description: Implementation agent for normal tasks and approved oracle handoffs
4
- thinking: high
5
- systemPromptMode: replace
6
- inheritProjectContext: true
7
- inheritSkills: false
8
- tools: read, grep, find, ls, bash, edit, write, contact_supervisor
9
- defaultContext: fork
10
- defaultReads: context.md, plan.md
11
- defaultProgress: true
12
- ---
13
-
14
- You are `worker`: the implementation subagent.
15
-
16
- You are the single writer thread. Your job is to execute the assigned task or approved direction with narrow, coherent edits. The main agent and user remain the decision authority.
17
-
18
- Use the provided tools directly. First understand the inherited context, supplied files, plan, and explicit task. Then implement carefully and minimally.
19
-
20
- If the task is framed as an approved direction, oracle handoff, or execution plan, treat that direction as the contract. Validate it against the actual code, but do not silently make new product, architecture, or scope decisions.
21
-
22
- If the implementation reveals a decision that was not approved and is required to continue safely, pause and escalate through the live coordination channel. If runtime bridge instructions are present, use them as the source of truth for which supervisor session to contact and how to coordinate. Use `contact_supervisor` with `reason: "need_decision"` when a new decision is needed, and stay alive to receive the reply before continuing. Use `reason: "progress_update"` only for concise non-blocking progress updates when that extra coordination is helpful or explicitly requested. Fall back to generic `intercom` only if `contact_supervisor` is unavailable. Do not finish your final response with a question that requires the supervisor to choose before you can continue.
23
-
24
- Default responsibilities:
25
- - validate the task or approved direction against the actual code
26
- - implement the smallest correct change
27
- - follow existing patterns in the codebase
28
- - verify the result with appropriate checks when possible
29
- - keep `progress.md` accurate when asked to maintain it
30
- - report back clearly with changes, validation, risks, and next steps
31
-
32
- Working rules:
33
- - Prefer narrow, correct changes over broad rewrites.
34
- - Do not add speculative scaffolding or future-proofing unless explicitly required.
35
- - Do not leave placeholder code, TODOs, or silent scope changes.
36
- - Use `bash` for inspection, validation, and relevant tests.
37
- - If there is supplied context or a plan, read it first.
38
- - If implementation reveals a gap in the approved direction, pause and escalate with `contact_supervisor` and `reason: "need_decision"` instead of silently patching around it with an implicit decision.
39
- - If implementation reveals an unapproved product or architecture choice, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply instead of deciding it yourself or returning a final choose-one answer.
40
- - If your delegated task expects code or file edits and you have not made those edits, do not return a success summary. Make the edits, contact the supervisor if blocked, or explicitly report that no edits were made.
41
- - If you send a blocked/progress update through `contact_supervisor`, keep it short and still return the full structured task result normally.
42
- - Do not send routine completion handoffs. Return the completed implementation summary normally when no coordination is needed.
43
-
44
- When running in a chain, expect instructions about:
45
- - which files to read first
46
- - where to maintain progress tracking
47
- - where to write output if a file target is provided
48
-
49
- Your final response should follow this shape:
50
-
51
- Implemented X.
52
- Changed files: Y.
53
- Validation: Z.
54
- Open risks/questions: R.
55
- Recommended next step: N.
@@ -1,46 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import { performance } from "node:perf_hooks";
4
- import { appendJsonl } from "../../shared/artifacts.ts";
5
-
6
- export type SpawnTimingMarker =
7
- | "spawn_start"
8
- | "spawn_command_resolved"
9
- | "child_first_event"
10
- | "child_first_jsonl_event";
11
-
12
- export interface SpawnTimingMarkers {
13
- spawnStart: number;
14
- }
15
-
16
- export function createSpawnTimingMarkers(): SpawnTimingMarkers {
17
- return { spawnStart: performance.now() };
18
- }
19
-
20
- export function emitSpawnTiming(options: {
21
- eventsPath: string | undefined;
22
- marker: SpawnTimingMarker;
23
- markers: SpawnTimingMarkers;
24
- runId?: string;
25
- stepIndex?: number;
26
- agent?: string;
27
- }): void {
28
- if (!options.eventsPath) return;
29
- try {
30
- fs.mkdirSync(path.dirname(options.eventsPath), { recursive: true });
31
- appendJsonl(
32
- options.eventsPath,
33
- JSON.stringify({
34
- type: "subagent.spawn.timing",
35
- ts: Date.now(),
36
- runId: options.runId ?? "",
37
- stepIndex: options.stepIndex ?? 0,
38
- agent: options.agent ?? "runner",
39
- marker: options.marker,
40
- elapsedMs: Math.round(performance.now() - options.markers.spawnStart),
41
- }),
42
- );
43
- } catch {
44
- // Timing diagnostics must never fail the run.
45
- }
46
- }
@@ -1,45 +0,0 @@
1
- import { describe, it } from "node:test";
2
- import * as assert from "node:assert";
3
- import * as fs from "node:fs";
4
- import * as os from "node:os";
5
- import * as path from "node:path";
6
- import { createSpawnTimingMarkers, emitSpawnTiming } from "../../src/runs/shared/spawn-timing.ts";
7
-
8
- describe("spawn-timing", () => {
9
- it("creates markers with a start time", () => {
10
- const markers = createSpawnTimingMarkers();
11
- assert.ok(markers.spawnStart > 0);
12
- });
13
-
14
- it("emits a timing line when an eventsPath is provided", () => {
15
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-timing-"));
16
- const eventsPath = path.join(dir, "events.jsonl");
17
- const markers = createSpawnTimingMarkers();
18
- emitSpawnTiming({
19
- eventsPath,
20
- marker: "spawn_start",
21
- markers,
22
- runId: "run-1",
23
- stepIndex: 2,
24
- agent: "scout",
25
- });
26
- const lines = fs.readFileSync(eventsPath, "utf-8").trim().split("\n");
27
- assert.equal(lines.length, 1);
28
- const event = JSON.parse(lines[0]!);
29
- assert.equal(event.type, "subagent.spawn.timing");
30
- assert.equal(event.runId, "run-1");
31
- assert.equal(event.stepIndex, 2);
32
- assert.equal(event.agent, "scout");
33
- assert.equal(event.marker, "spawn_start");
34
- assert.ok(typeof event.elapsedMs === "number");
35
- assert.ok(event.ts > 0);
36
- fs.rmSync(dir, { recursive: true, force: true });
37
- });
38
-
39
- it("skips emission when eventsPath is missing", () => {
40
- const markers = createSpawnTimingMarkers();
41
- assert.doesNotThrow(() => {
42
- emitSpawnTiming({ eventsPath: undefined, marker: "spawn_start", markers });
43
- });
44
- });
45
- });
@@ -1,17 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist/runner",
5
- "module": "NodeNext",
6
- "moduleResolution": "NodeNext",
7
- "target": "ES2022",
8
- "sourceMap": true,
9
- "noCheck": true,
10
- "noEmitOnError": false,
11
- "declaration": false,
12
- "declarationMap": false,
13
- "inlineSources": false
14
- },
15
- "include": ["src/**/*"],
16
- "exclude": ["test", "**/*.test.ts"]
17
- }
@@ -1,189 +0,0 @@
1
- import { createRequire } from "node:module";
2
-
3
- const require = createRequire(import.meta.url);
4
- const {
5
- DEFAULT_MODE,
6
- getDefaultMode,
7
- normalizeMode,
8
- normalizeConfigMode,
9
- normalizePersistedMode,
10
- isDeactivationCommand,
11
- writeDefaultMode,
12
- } = require("../hooks/ponytail-config.js");
13
- const { getPonytailInstructions, filterSkillBodyForMode } = require("../hooks/ponytail-instructions.js");
14
-
15
- export { filterSkillBodyForMode };
16
- export const readDefaultMode = getDefaultMode;
17
-
18
- export function resolveSessionMode(entries, fallbackMode = DEFAULT_MODE) {
19
- const fallback = normalizePersistedMode(fallbackMode) || DEFAULT_MODE;
20
- if (!Array.isArray(entries)) return fallback;
21
-
22
- for (let i = entries.length - 1; i >= 0; i -= 1) {
23
- const entry = entries[i];
24
- if (entry?.type !== "custom" || entry?.customType !== "ponytail-mode") continue;
25
-
26
- const mode = normalizePersistedMode(entry?.data?.mode);
27
- if (mode) return mode;
28
- }
29
-
30
- return fallback;
31
- }
32
-
33
- export function parsePonytailCommand(text, defaultMode = DEFAULT_MODE) {
34
- const fallback = normalizePersistedMode(defaultMode) || DEFAULT_MODE;
35
- const normalizedText = String(text || "").trim().toLowerCase();
36
-
37
- if (!normalizedText) {
38
- return { type: "set-mode", mode: fallback === "off" ? "full" : fallback };
39
- }
40
-
41
- const [primary, secondary] = normalizedText.split(/\s+/);
42
-
43
- if (primary === "status") return { type: "status" };
44
-
45
- if (primary === "default") {
46
- const mode = normalizeConfigMode(secondary);
47
- return mode ? { type: "set-default", mode } : { type: "invalid", reason: "invalid-default-mode" };
48
- }
49
-
50
- const mode = normalizeMode(primary);
51
- return mode ? { type: "set-mode", mode } : { type: "invalid", reason: "invalid-mode", mode: primary };
52
- }
53
-
54
- export { writeDefaultMode };
55
-
56
- export default function ponytailExtension(pi) {
57
- let currentMode = DEFAULT_MODE;
58
- let configuredDefaultMode = getDefaultMode();
59
- let isActive = false;
60
- let lastCtx = null;
61
-
62
- // -- Status bar --
63
- function syncStatus(ctx) {
64
- if (ctx) lastCtx = ctx;
65
- const c = ctx || lastCtx;
66
- if (!c?.ui?.setStatus || !c.ui.theme?.fg) return;
67
- const theme = c.ui.theme;
68
- if (currentMode === "off") {
69
- c.ui.setStatus("ponytail", "");
70
- return;
71
- }
72
- const levelIcons = { lite: "🌿", full: "⚡", ultra: "🔥" };
73
- const icon = levelIcons[currentMode] || "";
74
- const label = currentMode.toUpperCase();
75
- const indicator = isActive ? theme.fg("accent", "●") : theme.fg("dim", "○");
76
- c.ui.setStatus("ponytail", indicator + " 🐴 " + theme.fg("muted", "ponytail: ") + theme.fg("text", icon + " " + label));
77
- }
78
-
79
- const setMode = (mode, ctx) => {
80
- const normalized = normalizePersistedMode(mode);
81
- if (!normalized) return;
82
-
83
- currentMode = normalized;
84
- pi.appendEntry("ponytail-mode", { mode: normalized });
85
- syncStatus(ctx);
86
- ctx?.ui?.notify?.(`Ponytail mode set to ${normalized}.`, "info");
87
- };
88
-
89
- const sendAlias = (skillName, args, ctx) => {
90
- const normalized = String(args || "").trim();
91
- const message = normalized ? `${skillName} ${normalized}` : skillName;
92
-
93
- if (ctx?.isIdle?.() === false) {
94
- pi.sendUserMessage(message, { deliverAs: "followUp" });
95
- ctx?.ui?.notify?.(`${skillName} queued as follow-up.`, "info");
96
- return;
97
- }
98
-
99
- pi.sendUserMessage(message);
100
- };
101
-
102
- pi.registerCommand("ponytail", {
103
- description: "Set or report Ponytail mode",
104
- handler: async (args, ctx) => {
105
- const parsed = parsePonytailCommand(args, configuredDefaultMode);
106
-
107
- if (parsed.type === "status") {
108
- ctx?.ui?.notify?.(`Ponytail: current ${currentMode} • default ${configuredDefaultMode}`, "info");
109
- return;
110
- }
111
-
112
- if (parsed.type === "set-default") {
113
- const written = writeDefaultMode(parsed.mode);
114
- if (written) {
115
- configuredDefaultMode = getDefaultMode();
116
- const message = configuredDefaultMode === written
117
- ? `Default Ponytail mode set to ${written}.`
118
- : `Saved default ${written}, but env override keeps default at ${configuredDefaultMode}.`;
119
- ctx?.ui?.notify?.(message, "info");
120
- }
121
- return;
122
- }
123
-
124
- if (parsed.type === "set-mode") {
125
- setMode(parsed.mode, ctx);
126
- return;
127
- }
128
-
129
- ctx?.ui?.notify?.("Unknown or unsupported /ponytail mode.", "warning");
130
- },
131
- });
132
-
133
- pi.registerCommand("ponytail-review", {
134
- description: "Run /skill:ponytail-review",
135
- handler: (_args, ctx) => sendAlias("/skill:ponytail-review", "", ctx),
136
- });
137
-
138
- pi.registerCommand("ponytail-audit", {
139
- description: "Run /skill:ponytail-audit",
140
- handler: (_args, ctx) => sendAlias("/skill:ponytail-audit", "", ctx),
141
- });
142
-
143
- pi.registerCommand("ponytail-gain", {
144
- description: "Run /skill:ponytail-gain",
145
- handler: (_args, ctx) => sendAlias("/skill:ponytail-gain", "", ctx),
146
- });
147
-
148
- pi.registerCommand("ponytail-debt", {
149
- description: "Run /skill:ponytail-debt",
150
- handler: (_args, ctx) => sendAlias("/skill:ponytail-debt", "", ctx),
151
- });
152
-
153
- pi.registerCommand("ponytail-help", {
154
- description: "Run /skill:ponytail-help",
155
- handler: (_args, ctx) => sendAlias("/skill:ponytail-help", "", ctx),
156
- });
157
-
158
- pi.on("input", async (event) => {
159
- if (event?.source === "extension") return;
160
-
161
- const text = String(event?.text || "");
162
- if (currentMode !== "off" && isDeactivationCommand(text)) {
163
- setMode("off");
164
- }
165
- });
166
-
167
- pi.on("session_start", async (_event, ctx) => {
168
- const entries = ctx?.sessionManager?.getBranch?.() || ctx?.sessionManager?.getEntries?.() || [];
169
- configuredDefaultMode = getDefaultMode();
170
- currentMode = resolveSessionMode(entries, configuredDefaultMode);
171
- syncStatus(ctx);
172
- ctx?.ui?.notify?.(`Ponytail loaded: ${currentMode}`, "info");
173
- });
174
-
175
- pi.on("agent_start", async (_event, ctx) => {
176
- isActive = true;
177
- syncStatus(ctx);
178
- });
179
-
180
- pi.on("agent_end", async (_event, ctx) => {
181
- isActive = false;
182
- syncStatus(ctx);
183
- });
184
-
185
- pi.on("before_agent_start", async (event) => {
186
- if (!currentMode || currentMode === "off") return;
187
- return { systemPrompt: `${event.systemPrompt}\n\n${getPonytailInstructions(currentMode)}` };
188
- });
189
- }
@@ -1,8 +0,0 @@
1
- {
2
- "name": "ponytail-pi-extension-dev",
3
- "private": true,
4
- "type": "module",
5
- "scripts": {
6
- "test": "node --test ./test/*.test.js"
7
- }
8
- }