Commit e3762c04833e
Changed files (56)
.pi
extensions
dots
pi
agent
extensions
ai-storage
defaults
filter-output
git
guardrails
jira
org-todos
search
threads
.pi/extensions/deployment-guard.ts
@@ -12,8 +12,8 @@
* - Suggests dry-build first if not already run
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
// Production hosts that require extra confirmation
const PRODUCTION_HOSTS = [
.pi/extensions/secrets-validator.ts
@@ -12,8 +12,8 @@
* - Integrates with existing validate-git-push extension
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
// Patterns that might indicate secrets
const SECRET_PATTERNS = [
dots/pi/agent/extensions/ai-storage/index.ts
@@ -24,9 +24,9 @@
* Compatible with Claude Code, pi, opencode, cursor, and other AI coding tools.
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { getMarkdownTheme } from "@mariozechner/pi-coding-agent";
-import { Box, Markdown, matchesKey, visibleWidth, truncateToWidth } from "@mariozechner/pi-tui";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
+import { Box, Markdown, matchesKey, visibleWidth, truncateToWidth } from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
import { writeFile, mkdir, appendFile, readFile, readdir, unlink, stat } from "node:fs/promises";
import { existsSync, openSync, readdirSync } from "node:fs";
dots/pi/agent/extensions/ai-storage/package.json
@@ -7,7 +7,7 @@
"chrono-node": "^2.9.0"
},
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*",
+ "@earendil-works/pi-coding-agent": "*",
"bun-types": "^1.0.0"
},
"pi": {
dots/pi/agent/extensions/defaults/index.ts
@@ -9,11 +9,11 @@
* Adapted from: aliou/pi-extensions defaults
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "@sinclair/typebox";
import { lstat } from "node:fs/promises";
import { resolve } from "node:path";
-import { createReadTool, createLsTool } from "@mariozechner/pi-coding-agent";
+import { createReadTool, createLsTool } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// ── Directory-aware read ──────────────────────────────────
dots/pi/agent/extensions/defaults/package.json
@@ -4,6 +4,6 @@
"type": "module",
"main": "index.ts",
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*"
+ "@earendil-works/pi-coding-agent": "*"
}
}
dots/pi/agent/extensions/filter-output/index.ts
@@ -10,7 +10,7 @@
* Source: adapted from michalvavra/agents filter-output.ts
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// ── Sensitive data patterns ───────────────────────────────────
dots/pi/agent/extensions/filter-output/package.json
@@ -4,6 +4,6 @@
"type": "module",
"main": "index.ts",
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*"
+ "@earendil-works/pi-coding-agent": "*"
}
}
dots/pi/agent/extensions/git/index.ts
@@ -2,7 +2,7 @@
// Git Extension for Pi Coding Agent
// =============================================================================
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import {
listWorktrees,
createWorktree,
dots/pi/agent/extensions/github/actions/checks.ts
@@ -2,7 +2,7 @@
* CI/Checks action handlers for GitHub extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { GhDetails } from "../types";
import { parseChecks, parseRunList, getErrorMessage, getCheckIcon, getRunStatusIcon, execGh, approvalGate, buildModifyResult, buildRejectResult } from "../utils";
dots/pi/agent/extensions/github/actions/issue.ts
@@ -2,7 +2,7 @@
* Issue action handlers for GitHub extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { GhDetails } from "../types";
import {
parseIssueList,
dots/pi/agent/extensions/github/actions/pr.ts
@@ -2,7 +2,7 @@
* Pull Request action handlers for GitHub extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { GhDetails, GhLineComment } from "../types";
import {
parsePRList,
dots/pi/agent/extensions/github/actions/repo.ts
@@ -2,7 +2,7 @@
* Repository action handlers for GitHub extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { GhDetails } from "../types";
import { parseRepo, parseReleaseList, getErrorMessage, formatRelativeDate, execGh } from "../utils";
dots/pi/agent/extensions/github/index.ts
@@ -14,16 +14,16 @@
* - Authenticated: gh auth login
*/
-import type { ExtensionAPI, ExtensionContext, Theme } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-coding-agent";
import {
Text,
type AutocompleteItem,
type AutocompleteProvider,
type AutocompleteSuggestions,
fuzzyFilter,
-} from "@mariozechner/pi-tui";
+} from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
-import { StringEnum } from "@mariozechner/pi-ai";
+import { StringEnum } from "@earendil-works/pi-ai";
import type { GhDetails } from "./types";
import {
dots/pi/agent/extensions/github/package.json
@@ -6,7 +6,7 @@
"test": "bun test github.test.ts"
},
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*",
+ "@earendil-works/pi-coding-agent": "*",
"bun-types": "^1.0.0"
}
}
dots/pi/agent/extensions/github/utils.ts
@@ -2,7 +2,7 @@
* Utility functions for GitHub extension
*/
-import type { Theme, ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { Theme, ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { GhDetails, GhPR, GhIssue, GhCheck, GhRun, GhReview, GhReviewComment, GhReviewSummary, GhRelease, GhRepo } from "./types";
// ============================================================================
dots/pi/agent/extensions/guardrails/index.ts
@@ -13,8 +13,8 @@
* Policy config: ~/.config/ai/path-policies.json
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
import { existsSync } from "node:fs";
import { readFile, writeFile } from "node:fs/promises";
import { join, normalize } from "node:path";
dots/pi/agent/extensions/guardrails/package.json
@@ -7,7 +7,7 @@
"extensions": ["./index.ts"]
},
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*",
+ "@earendil-works/pi-coding-agent": "*",
"bun-types": "^1.0.0"
}
}
dots/pi/agent/extensions/jira/actions.ts
@@ -2,7 +2,7 @@
* Action handlers for Jira extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { JiraDetails } from "./types";
import {
buildCommentConfirmation,
dots/pi/agent/extensions/jira/attachment-actions.ts
@@ -2,7 +2,7 @@
* Attachment-related action handlers for Jira extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { JiraDetails } from "./types";
import { getErrorMessage, serializedConfirm } from "./utils";
dots/pi/agent/extensions/jira/epic-actions.ts
@@ -2,7 +2,7 @@
* Epic-related action handlers for Jira extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { JiraDetails } from "./types";
import { getErrorMessage, serializedConfirm } from "./utils";
dots/pi/agent/extensions/jira/index.ts
@@ -16,16 +16,16 @@
* - Red Hat VPN connection
*/
-import type { ExtensionAPI, ExtensionContext, Theme } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-coding-agent";
import {
Text,
type AutocompleteItem,
type AutocompleteProvider,
type AutocompleteSuggestions,
fuzzyFilter,
-} from "@mariozechner/pi-tui";
+} from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
-import { StringEnum } from "@mariozechner/pi-ai";
+import { StringEnum } from "@earendil-works/pi-ai";
import type { JiraDetails } from "./types";
import {
dots/pi/agent/extensions/jira/link-actions.ts
@@ -2,7 +2,7 @@
* Link-related action handlers for Jira extension
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { JiraDetails } from "./types";
import { getErrorMessage, serializedConfirm } from "./utils";
dots/pi/agent/extensions/jira/package.json
@@ -6,7 +6,7 @@
"test": "bun test jira.test.ts"
},
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*",
+ "@earendil-works/pi-coding-agent": "*",
"bun-types": "^1.0.0"
}
}
dots/pi/agent/extensions/jira/utils.ts
@@ -2,7 +2,7 @@
* Utility functions for Jira extension
*/
-import type { Theme, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { Theme, ExtensionContext } from "@earendil-works/pi-coding-agent";
import type { JiraIssue } from "./types";
// ============================================================================
dots/pi/agent/extensions/org-todos/dist/index.js
@@ -1,5 +1,5 @@
// index.ts
-import { DynamicBorder } from "@mariozechner/pi-coding-agent";
+import { DynamicBorder } from "@earendil-works/pi-coding-agent";
import { execSync } from "node:child_process";
import { homedir } from "node:os";
import { join } from "node:path";
@@ -483,7 +483,7 @@ class ReferenceWithTimezone {
return date;
}
getSystemTimezoneAdjustmentMinute(date, overrideTimezoneOffset) {
- if (!date || date.getTime() < 0) {
+ if (!date) {
date = new Date;
}
const currentTimezoneOffset = -date.getTimezoneOffset();
@@ -986,7 +986,7 @@ function parseOrdinalNumberPattern(match) {
num = num.replace(/(?:st|nd|rd|th)$/i, "");
return parseInt(num);
}
-var YEAR_PATTERN = `(?:[1-9][0-9]{0,3}\\s{0,2}(?:BE|AD|BC|BCE|CE)|[1-2][0-9]{3}|[5-9][0-9]|2[0-5])`;
+var YEAR_PATTERN = `(?:[1-9][0-9]{0,3}\\s{0,2}(?:BE|AD|BC|BCE|CE)|[1-9][0-9]{3}|[5-9][0-9]|2[0-5])`;
function parseYear(match) {
if (/BE/i.test(match)) {
match = match.replace(/BE/i, "");
@@ -1813,9 +1813,10 @@ function mergeDateTimeComponent(dateComponent, timeComponent) {
if (timeComponent.isCertain("timezoneOffset")) {
dateTimeComponent.assign("timezoneOffset", timeComponent.get("timezoneOffset"));
}
+ const dateHasMeaningfulMeridiem = dateComponent.get("meridiem") != null && (dateComponent.isCertain("meridiem") || Array.from(dateComponent.tags()).some((t) => t.startsWith("casualReference/")));
if (timeComponent.isCertain("meridiem")) {
dateTimeComponent.assign("meridiem", timeComponent.get("meridiem"));
- } else if (timeComponent.get("meridiem") != null && dateTimeComponent.get("meridiem") == null) {
+ } else if (timeComponent.get("meridiem") != null && !dateHasMeaningfulMeridiem) {
dateTimeComponent.imply("meridiem", timeComponent.get("meridiem"));
}
if (dateTimeComponent.get("meridiem") == Meridiem.PM && dateTimeComponent.get("hour") < 12) {
@@ -1977,6 +1978,63 @@ class OverlapRemovalRefiner {
}
}
+// node_modules/chrono-node/dist/esm/calculation/weekdays.js
+function createParsingComponentsAtWeekday(reference, weekday, modifier) {
+ const refDate = reference.getDateWithAdjustedTimezone();
+ const daysToWeekday = getDaysToWeekday(refDate, weekday, modifier);
+ let components = new ParsingComponents(reference);
+ components = components.addDurationAsImplied({ day: daysToWeekday });
+ components.assign("weekday", weekday);
+ return components;
+}
+function getDaysToWeekday(refDate, weekday, modifier) {
+ const refWeekday = refDate.getDay();
+ switch (modifier) {
+ case "this":
+ return getDaysForwardToWeekday(refDate, weekday);
+ case "last":
+ return getBackwardDaysToWeekday(refDate, weekday);
+ case "next":
+ if (refWeekday == Weekday.SUNDAY) {
+ return weekday == Weekday.SUNDAY ? 7 : weekday;
+ }
+ if (refWeekday == Weekday.SATURDAY) {
+ if (weekday == Weekday.SATURDAY)
+ return 7;
+ if (weekday == Weekday.SUNDAY)
+ return 8;
+ return 1 + weekday;
+ }
+ if (weekday < refWeekday && weekday != Weekday.SUNDAY) {
+ return getDaysForwardToWeekday(refDate, weekday);
+ } else {
+ return getDaysForwardToWeekday(refDate, weekday) + 7;
+ }
+ }
+ return getDaysToWeekdayClosest(refDate, weekday);
+}
+function getDaysToWeekdayClosest(refDate, weekday) {
+ const backward = getBackwardDaysToWeekday(refDate, weekday);
+ const forward = getDaysForwardToWeekday(refDate, weekday);
+ return forward < -backward ? forward : backward;
+}
+function getDaysForwardToWeekday(refDate, weekday) {
+ const refWeekday = refDate.getDay();
+ let forwardCount = weekday - refWeekday;
+ if (forwardCount < 0) {
+ forwardCount += 7;
+ }
+ return forwardCount;
+}
+function getBackwardDaysToWeekday(refDate, weekday) {
+ const refWeekday = refDate.getDay();
+ let backwardCount = weekday - refWeekday;
+ if (backwardCount >= 0) {
+ backwardCount -= 7;
+ }
+ return backwardCount;
+}
+
// node_modules/chrono-node/dist/esm/common/refiners/ForwardDateRefiner.js
class ForwardDateRefiner {
refine(context, results) {
@@ -2002,22 +2060,16 @@ class ForwardDateRefiner {
}
}
if (result.start.isOnlyWeekdayComponent() && refDate > result.start.date()) {
- let daysToAdd = result.start.get("weekday") - refDate.getDay();
- if (daysToAdd <= 0) {
- daysToAdd += 7;
- }
- refDate = addDuration(refDate, { day: daysToAdd });
- implySimilarDate(result.start, refDate);
+ let daysToAdd = getDaysForwardToWeekday(refDate, result.start.get("weekday")) || 7;
+ const forwardedWeekday = addDuration(refDate, { day: daysToAdd });
+ implySimilarDate(result.start, forwardedWeekday);
context.debug(() => {
console.log(`${this.constructor.name} adjusted ${result} weekday (${result.start})`);
});
- if (result.end && result.end.isOnlyWeekdayComponent()) {
- let daysToAdd2 = result.end.get("weekday") - refDate.getDay();
- if (daysToAdd2 <= 0) {
- daysToAdd2 += 7;
- }
- refDate = addDuration(refDate, { day: daysToAdd2 });
- implySimilarDate(result.end, refDate);
+ if (result.end && result.start.date() > result.end.date()) {
+ let daysToAdd2 = getDaysForwardToWeekday(refDate, result.start.get("weekday")) || 7;
+ const forwardedWeekday2 = addDuration(refDate, { day: daysToAdd2 });
+ implySimilarDate(result.end, forwardedWeekday2);
context.debug(() => {
console.log(`${this.constructor.name} adjusted ${result} weekday (${result.end})`);
});
@@ -2350,65 +2402,8 @@ class ENCasualTimeParser extends AbstractParserWithWordBoundaryChecking {
}
}
-// node_modules/chrono-node/dist/esm/calculation/weekdays.js
-function createParsingComponentsAtWeekday(reference, weekday, modifier) {
- const refDate = reference.getDateWithAdjustedTimezone();
- const daysToWeekday = getDaysToWeekday(refDate, weekday, modifier);
- let components = new ParsingComponents(reference);
- components = components.addDurationAsImplied({ day: daysToWeekday });
- components.assign("weekday", weekday);
- return components;
-}
-function getDaysToWeekday(refDate, weekday, modifier) {
- const refWeekday = refDate.getDay();
- switch (modifier) {
- case "this":
- return getDaysForwardToWeekday(refDate, weekday);
- case "last":
- return getBackwardDaysToWeekday(refDate, weekday);
- case "next":
- if (refWeekday == Weekday.SUNDAY) {
- return weekday == Weekday.SUNDAY ? 7 : weekday;
- }
- if (refWeekday == Weekday.SATURDAY) {
- if (weekday == Weekday.SATURDAY)
- return 7;
- if (weekday == Weekday.SUNDAY)
- return 8;
- return 1 + weekday;
- }
- if (weekday < refWeekday && weekday != Weekday.SUNDAY) {
- return getDaysForwardToWeekday(refDate, weekday);
- } else {
- return getDaysForwardToWeekday(refDate, weekday) + 7;
- }
- }
- return getDaysToWeekdayClosest(refDate, weekday);
-}
-function getDaysToWeekdayClosest(refDate, weekday) {
- const backward = getBackwardDaysToWeekday(refDate, weekday);
- const forward = getDaysForwardToWeekday(refDate, weekday);
- return forward < -backward ? forward : backward;
-}
-function getDaysForwardToWeekday(refDate, weekday) {
- const refWeekday = refDate.getDay();
- let forwardCount = weekday - refWeekday;
- if (forwardCount < 0) {
- forwardCount += 7;
- }
- return forwardCount;
-}
-function getBackwardDaysToWeekday(refDate, weekday) {
- const refWeekday = refDate.getDay();
- let backwardCount = weekday - refWeekday;
- if (backwardCount >= 0) {
- backwardCount -= 7;
- }
- return backwardCount;
-}
-
// node_modules/chrono-node/dist/esm/locales/en/parsers/ENWeekdayParser.js
-var PATTERN11 = new RegExp("(?:(?:\\,|\\(|\\()\\s*)?" + "(?:on\\s*?)?" + "(?:(this|last|past|next)\\s*)?" + `(${matchAnyPattern(WEEKDAY_DICTIONARY)}|weekend|weekday)` + "(?:\\s*(?:\\,|\\)|\\)))?" + "(?:\\s*(this|last|past|next)\\s*week)?" + "(?=\\W|$)", "i");
+var PATTERN11 = new RegExp("(?:(?:\\,|\\(|\\()\\s*)?" + "(?:on\\s*?)?" + "(?:(this|last|past|next)\\s*)?" + `(${matchAnyPattern(WEEKDAY_DICTIONARY)}|weekend|weekday)` + "(?:\\s*(?:\\,|\\)|\\)))?" + "(?:\\s*(?:of\\s*)?(this|last|past|next)\\s*week)?" + "(?=\\W|$)", "i");
var PREFIX_GROUP2 = 1;
var WEEKDAY_GROUP = 2;
var POSTFIX_GROUP = 3;
@@ -2874,7 +2869,12 @@ function parseDate(text, ref, option) {
}
// index.ts
-import { Container, SelectList, Text } from "@mariozechner/pi-tui";
+import {
+ Container,
+ SelectList,
+ Text,
+ fuzzyFilter
+} from "@earendil-works/pi-tui";
var DEFAULT_ORG_FILE = join(homedir(), "desktop/org/todos.org");
var INBOX_FILE = join(homedir(), "desktop/org/inbox.org");
var DEFAULT_SECTION = "Inbox";
@@ -3041,6 +3041,12 @@ function org_todos_default(pi) {
pi.registerTool({
name: "org_todo",
label: "Org TODO",
+ promptSnippet: "Manage org-mode TODOs. Actions: list, scheduled, upcoming, overdue, search, get, done, state, schedule, deadline, priority, add, append, inbox-list, inbox-count, inbox-add, refile-targets, refile",
+ promptGuidelines: [
+ "NEVER edit .org files directly — always use the org_todo tool for all TODO operations",
+ "For scheduling, use YYYY-MM-DD date format (natural language dates are NOT supported by this tool)",
+ "Use inbox-add for quick capture, then refile to the appropriate section later"
+ ],
description: `Manage org-mode TODOs. Actions:
- list: List active TODOs (TODO, NEXT, STRT)
- scheduled: Get today's scheduled items
@@ -3966,15 +3972,93 @@ ${selected.display}`,
pi.on("session_start", async (_event, ctx) => {
updateInboxStatus(ctx);
updateTodayStatus(ctx);
+ setupTodoAutocomplete(ctx);
const updateInterval = setInterval(() => {
updateInboxStatus(ctx);
updateTodayStatus(ctx);
}, 5 * 60 * 1000);
+ updateInterval.unref();
pi.on("session_end", async () => {
clearInterval(updateInterval);
});
});
}
+var TODO_MAX_SUGGESTIONS = 20;
+function extractTodoToken(textBeforeCursor) {
+ const match = textBeforeCursor.match(/(?:^|[ \t])t:([^\s]*)$/);
+ return match?.[1];
+}
+function formatTodoItem(item) {
+ return {
+ value: item.heading,
+ label: item.heading,
+ description: `[${item.todo}]`
+ };
+}
+function filterTodoItems(items, query) {
+ if (!query.trim()) {
+ return items.slice(0, TODO_MAX_SUGGESTIONS).map(formatTodoItem);
+ }
+ return fuzzyFilter(items, query, (item) => `${item.todo} ${item.heading}`).slice(0, TODO_MAX_SUGGESTIONS).map(formatTodoItem);
+}
+function createTodoAutocompleteProvider(current, getItems) {
+ return {
+ async getSuggestions(lines, cursorLine, cursorCol, options) {
+ const currentLine = lines[cursorLine] ?? "";
+ const textBeforeCursor = currentLine.slice(0, cursorCol);
+ const query = extractTodoToken(textBeforeCursor);
+ if (query === undefined) {
+ return current.getSuggestions(lines, cursorLine, cursorCol, options);
+ }
+ const items = await getItems();
+ if (options.signal.aborted || !items || items.length === 0) {
+ return current.getSuggestions(lines, cursorLine, cursorCol, options);
+ }
+ const suggestions = filterTodoItems(items, query);
+ if (suggestions.length === 0) {
+ return current.getSuggestions(lines, cursorLine, cursorCol, options);
+ }
+ return { items: suggestions, prefix: `t:${query}` };
+ },
+ applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
+ if (prefix.startsWith("t:")) {
+ const currentLine = lines[cursorLine] || "";
+ const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
+ const afterCursor = currentLine.slice(cursorCol);
+ const value = item.value.includes(" ") ? `"${item.value}"` : item.value;
+ const newLine = beforePrefix + value + " " + afterCursor;
+ const newLines = [...lines];
+ newLines[cursorLine] = newLine;
+ return {
+ lines: newLines,
+ cursorLine,
+ cursorCol: beforePrefix.length + value.length + 1
+ };
+ }
+ return current.applyCompletion(lines, cursorLine, cursorCol, item, prefix);
+ },
+ shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
+ return current.shouldTriggerFileCompletion?.(lines, cursorLine, cursorCol) ?? true;
+ }
+ };
+}
+function setupTodoAutocomplete(ctx) {
+ let itemsPromise;
+ const getItems = async () => {
+ itemsPromise ||= (async () => {
+ const result = execEmacs("(pi/org-todo-list)");
+ if (!result.success || !Array.isArray(result.data))
+ return;
+ return result.data.map((item) => ({
+ heading: item.heading,
+ todo: item.todo || "TODO"
+ }));
+ })();
+ return itemsPromise;
+ };
+ getItems();
+ ctx.ui.addAutocompleteProvider((current) => createTodoAutocompleteProvider(current, getItems));
+}
export {
org_todos_default as default
};
dots/pi/agent/extensions/org-todos/index.ts
@@ -30,8 +30,8 @@
* - org-ql and pi-org-todos.el loaded
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
-import { DynamicBorder } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
+import { DynamicBorder } from "@earendil-works/pi-coding-agent";
import { execSync } from "node:child_process";
import { homedir } from "node:os";
import { join } from "node:path";
@@ -45,7 +45,7 @@ import {
type AutocompleteProvider,
type AutocompleteSuggestions,
fuzzyFilter,
-} from "@mariozechner/pi-tui";
+} from "@earendil-works/pi-tui";
// Configuration
const DEFAULT_ORG_FILE = join(homedir(), "desktop/org/todos.org");
dots/pi/agent/extensions/org-todos/Makefile
@@ -121,7 +121,7 @@ test-daemon-check:
# Build TypeScript
build:
@echo -e "$(YELLOW)Building TypeScript...$(NC)"
- @bun build index.ts --target=node --outdir dist --external @mariozechner/pi-coding-agent --external @mariozechner/pi-tui
+ @bun build index.ts --target=node --outdir dist --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui
@echo -e "$(GREEN)✓ Build complete: dist/index.js$(NC)"
# Clean build artifacts
dots/pi/agent/extensions/org-todos/package.json
@@ -9,7 +9,7 @@
"chrono-node": "^2.7.0"
},
"devDependencies": {
- "@mariozechner/pi-coding-agent": "*",
+ "@earendil-works/pi-coding-agent": "*",
"bun-types": "^1.0.0"
}
}
dots/pi/agent/extensions/search/index.ts
@@ -19,8 +19,8 @@
* SEARXNG_URL - SearXNG instance URL (default: https://search.sbr.pm)
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { Text } from "@mariozechner/pi-tui";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { Text } from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
import {
BraveAPIBackend,
dots/pi/agent/extensions/shell-completions/bash.ts
@@ -7,7 +7,7 @@
* Philosophy: Only provide completions if the user has bash-completion available.
*/
-import type { AutocompleteItem } from "@mariozechner/pi-tui";
+import type { AutocompleteItem } from "@earendil-works/pi-tui";
import { spawnSync } from "node:child_process";
import * as fs from "node:fs";
import * as path from "node:path";
dots/pi/agent/extensions/shell-completions/fish.ts
@@ -8,7 +8,7 @@
* returns null for "user hasn't configured completions".
*/
-import type { AutocompleteItem } from "@mariozechner/pi-tui";
+import type { AutocompleteItem } from "@earendil-works/pi-tui";
import { spawnSync } from "node:child_process";
import type { CompletionResult, ShellCompletionProvider } from "./types.js";
dots/pi/agent/extensions/shell-completions/index.ts
@@ -17,8 +17,8 @@
* This means completions respect the user's shell setup, aliases, and customizations.
*/
-import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import type { AutocompleteItem, AutocompleteProvider } from "@mariozechner/pi-tui";
+import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import type { AutocompleteItem, AutocompleteProvider } from "@earendil-works/pi-tui";
import * as fs from "node:fs";
import * as path from "node:path";
dots/pi/agent/extensions/shell-completions/package.json
@@ -14,7 +14,7 @@
"extensions": ["./index.ts"]
},
"peerDependencies": {
- "@mariozechner/pi-coding-agent": "*",
- "@mariozechner/pi-tui": "*"
+ "@earendil-works/pi-coding-agent": "*",
+ "@earendil-works/pi-tui": "*"
}
}
dots/pi/agent/extensions/shell-completions/types.ts
@@ -2,7 +2,7 @@
* Shared types for shell completions extension.
*/
-import type { AutocompleteItem } from "@mariozechner/pi-tui";
+import type { AutocompleteItem } from "@earendil-works/pi-tui";
export type ShellType = "fish" | "zsh" | "bash";
dots/pi/agent/extensions/shell-completions/zsh.ts
@@ -18,7 +18,7 @@ import * as fs from "node:fs";
import * as path from "node:path";
import { fileURLToPath } from "node:url";
import type { CompletionResult } from "./types.js";
-import type { AutocompleteItem } from "@mariozechner/pi-tui";
+import type { AutocompleteItem } from "@earendil-works/pi-tui";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const CAPTURE_SCRIPT = path.join(__dirname, "scripts", "zsh-capture.zsh");
dots/pi/agent/extensions/subagent/agents.ts
@@ -5,7 +5,7 @@
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
-import { parseFrontmatter } from "@mariozechner/pi-coding-agent";
+import { parseFrontmatter } from "@earendil-works/pi-coding-agent";
export type AgentScope = "user" | "project" | "both";
dots/pi/agent/extensions/subagent/index.ts
@@ -16,11 +16,11 @@ import { spawn } from "node:child_process";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
-import type { AgentToolResult } from "@mariozechner/pi-agent-core";
-import type { Message } from "@mariozechner/pi-ai";
-import { StringEnum } from "@mariozechner/pi-ai";
-import { type ExtensionAPI, getMarkdownTheme } from "@mariozechner/pi-coding-agent";
-import { Container, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
+import type { AgentToolResult } from "@earendil-works/pi-agent-core";
+import type { Message } from "@earendil-works/pi-ai";
+import { StringEnum } from "@earendil-works/pi-ai";
+import { type ExtensionAPI, getMarkdownTheme } from "@earendil-works/pi-coding-agent";
+import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
import { type AgentConfig, type AgentScope, discoverAgents } from "./agents.js";
dots/pi/agent/extensions/threads/index.ts
@@ -9,15 +9,15 @@ import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import { Type } from "@sinclair/typebox";
-import { StringEnum } from "@mariozechner/pi-ai";
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import { StringEnum } from "@earendil-works/pi-ai";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import {
parseSessionEntries,
type FileEntry,
type SessionEntry,
type SessionHeader,
-} from "@mariozechner/pi-coding-agent";
-import { Text, Container, Spacer } from "@mariozechner/pi-tui";
+} from "@earendil-works/pi-coding-agent";
+import { Text, Container, Spacer } from "@earendil-works/pi-tui";
// ============================================================================
// Session Parsing Utilities
dots/pi/agent/extensions/threads/package.json
@@ -14,9 +14,9 @@
"extensions": ["./index.ts"]
},
"peerDependencies": {
- "@mariozechner/pi-ai": "*",
- "@mariozechner/pi-coding-agent": "*",
- "@mariozechner/pi-tui": "*",
+ "@earendil-works/pi-ai": "*",
+ "@earendil-works/pi-coding-agent": "*",
+ "@earendil-works/pi-tui": "*",
"@sinclair/typebox": "*"
}
}
dots/pi/agent/extensions/ask-user.ts
@@ -11,9 +11,9 @@
* ask_user({ question: "Which features?", suggestions: ["auth", "logging", "caching"], multiSelect: true })
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { DynamicBorder, getSettingsListTheme } from "@mariozechner/pi-coding-agent";
-import { Container, type SettingItem, SettingsList, Text } from "@mariozechner/pi-tui";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { DynamicBorder, getSettingsListTheme } from "@earendil-works/pi-coding-agent";
+import { Container, type SettingItem, SettingsList, Text } from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
/**
dots/pi/agent/extensions/cost-tracker.ts
@@ -5,7 +5,7 @@
* similar to GitHub Copilot's premium request multiplier display.
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// Premium request multipliers (cost relative to Sonnet baseline)
const MULTIPLIERS: Record<string, number> = {
dots/pi/agent/extensions/custom-header.ts
@@ -8,8 +8,8 @@
* - /resources command to show loaded extensions/skills/prompts inline
*/
-import type { ExtensionAPI, Theme } from "@mariozechner/pi-coding-agent";
-import { VERSION } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, Theme } from "@earendil-works/pi-coding-agent";
+import { VERSION } from "@earendil-works/pi-coding-agent";
// Pi symbol ASCII art (using Braille patterns) with green-to-blue gradient
function getPiArt(theme: Theme): string[] {
dots/pi/agent/extensions/debug-requests.ts
@@ -9,7 +9,7 @@
* Logs to: /tmp/pi-requests.log (truncated per session)
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { appendFileSync, writeFileSync } from "node:fs";
const LOG_FILE = "/tmp/pi-requests.log";
dots/pi/agent/extensions/interactive-shell.ts
@@ -21,7 +21,7 @@
*/
import { spawnSync } from "node:child_process";
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// Default interactive commands - editors, pagers, git ops, TUIs
const DEFAULT_INTERACTIVE_COMMANDS = [
dots/pi/agent/extensions/kitty-image.ts
@@ -11,9 +11,9 @@
* - /show-image command: quick display from the command line
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { convertToPng as convertToPngNative } from "@mariozechner/pi-coding-agent";
-import { Text } from "@mariozechner/pi-tui";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { convertToPng as convertToPngNative } from "@earendil-works/pi-coding-agent";
+import { Text } from "@earendil-works/pi-tui";
import { Type } from "@sinclair/typebox";
import { readFileSync, existsSync, statSync } from "node:fs";
import { execSync, execFileSync } from "node:child_process";
dots/pi/agent/extensions/message-queue.ts
@@ -17,9 +17,9 @@
* - Escape to close without sending
*/
-import type { ExtensionAPI, ExtensionContext, Theme } from "@mariozechner/pi-coding-agent";
-import { DynamicBorder } from "@mariozechner/pi-coding-agent";
-import { matchesKey, Key, truncateToWidth } from "@mariozechner/pi-tui";
+import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-coding-agent";
+import { DynamicBorder } from "@earendil-works/pi-coding-agent";
+import { matchesKey, Key, truncateToWidth } from "@earendil-works/pi-tui";
interface QueuedMessage {
text: string;
dots/pi/agent/extensions/orc-mode.ts
@@ -16,7 +16,7 @@
* 2. Or start with --orc flag
*/
-import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
// Tools available in orchestrator mode - subagent for delegation, subagent_status for async monitoring
const ORC_MODE_TOOLS = ["subagent", "subagent_status"];
dots/pi/agent/extensions/prompt-editor.ts
@@ -1,6 +1,6 @@
-import type { ExtensionAPI, ExtensionContext, ModelSelectEvent, ThinkingLevel } from "@mariozechner/pi-coding-agent";
-import { CustomEditor, DynamicBorder, ModelSelectorComponent, SettingsManager } from "@mariozechner/pi-coding-agent";
-import { Container, type SelectItem, SelectList, Text, matchesKey, Key } from "@mariozechner/pi-tui";
+import type { ExtensionAPI, ExtensionContext, ModelSelectEvent, ThinkingLevel } from "@earendil-works/pi-coding-agent";
+import { CustomEditor, DynamicBorder, ModelSelectorComponent, SettingsManager } from "@earendil-works/pi-coding-agent";
+import { Container, type SelectItem, SelectList, Text, matchesKey, Key } from "@earendil-works/pi-tui";
import path from "node:path";
import os from "node:os";
import fs from "node:fs/promises";
dots/pi/agent/extensions/review.ts
@@ -28,9 +28,9 @@
* Note: PR review requires a clean working tree (no uncommitted changes to tracked files).
*/
-import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
-import { DynamicBorder, BorderedLoader } from "@mariozechner/pi-coding-agent";
-import { Container, type SelectItem, SelectList, Text, Key } from "@mariozechner/pi-tui";
+import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
+import { DynamicBorder, BorderedLoader } from "@earendil-works/pi-coding-agent";
+import { Container, type SelectItem, SelectList, Text, Key } from "@earendil-works/pi-tui";
import path from "node:path";
import { promises as fs, readdirSync, readFileSync } from "node:fs";
import { execSync } from "node:child_process";
dots/pi/agent/extensions/subagent-commands.ts
@@ -8,7 +8,7 @@
* - /review-code <query> - Review workflow: scout → reviewer
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// /scout - Quick reconnaissance
dots/pi/agent/extensions/terminal-status.ts
@@ -22,7 +22,7 @@
* Migrated from: notify.ts + Go-based claude-hooks-update-terminal-title
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { execSync } from "node:child_process";
import { hostname } from "node:os";
import path from "node:path";
dots/pi/agent/extensions/tool-filter.ts
@@ -14,7 +14,7 @@
* PI_ALL_TOOLS=1 — Disable filtering entirely
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { existsSync } from "fs";
import { join } from "path";
dots/pi/agent/extensions/usage-bar.ts
@@ -8,8 +8,8 @@
* - Reset countdowns
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { visibleWidth } from "@mariozechner/pi-tui";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
+import { visibleWidth } from "@earendil-works/pi-tui";
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
dots/pi/agent/extensions/validate-git-push.ts
@@ -14,7 +14,7 @@
* 3. Use specific file paths for git add
*/
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
+import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
/**
* Check if a git push command uses explicit refspec (branch:branch)