omegon 0.6.3 → 0.6.4
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 +12 -10
- package/bin/omegon.mjs +40 -0
- package/bin/pi.mjs +5 -26
- package/extensions/00-secrets/index.ts +146 -39
- package/extensions/01-auth/auth.ts +1 -1
- package/extensions/01-auth/index.ts +3 -3
- package/extensions/auto-compact.ts +1 -1
- package/extensions/bootstrap/deps.ts +42 -0
- package/extensions/bootstrap/index.ts +326 -110
- package/extensions/chronos/index.ts +1 -1
- package/extensions/cleave/dispatcher.ts +6 -6
- package/extensions/cleave/index.ts +6 -6
- package/extensions/cleave/planner.ts +1 -1
- package/extensions/cleave/worktree.ts +1 -1
- package/extensions/core-renderers.ts +24 -84
- package/extensions/dashboard/footer.ts +184 -40
- package/extensions/dashboard/git.ts +2 -2
- package/extensions/dashboard/index.ts +4 -4
- package/extensions/dashboard/overlay-data.ts +5 -5
- package/extensions/dashboard/overlay.ts +5 -5
- package/extensions/dashboard/render-utils.ts +1 -1
- package/extensions/dashboard/types.ts +15 -0
- package/extensions/defaults.ts +4 -12
- package/extensions/design-tree/dashboard-state.ts +6 -6
- package/extensions/design-tree/design-card.ts +3 -3
- package/extensions/design-tree/index.ts +64 -44
- package/extensions/design-tree/types.ts +4 -2
- package/extensions/distill.ts +1 -1
- package/extensions/effort/index.ts +137 -10
- package/extensions/lib/model-routing.ts +304 -32
- package/extensions/lib/operator-fallback.ts +1 -1
- package/extensions/lib/operator-profile.ts +1 -1
- package/extensions/lib/provider-env.ts +163 -0
- package/extensions/{sci-ui.ts → lib/sci-ui.ts} +119 -2
- package/extensions/{shared-state.ts → lib/shared-state.ts} +13 -9
- package/extensions/lib/slash-command-bridge.ts +1 -1
- package/extensions/{types.d.ts → lib/types.d.ts} +3 -3
- package/extensions/local-inference/index.ts +1 -1
- package/extensions/mcp-bridge/index.ts +1 -1
- package/extensions/model-budget.ts +10 -10
- package/extensions/offline-driver.ts +11 -4
- package/extensions/openspec/archive-gate.ts +1 -1
- package/extensions/openspec/branch-cleanup.ts +1 -1
- package/extensions/openspec/dashboard-state.ts +3 -3
- package/extensions/openspec/index.ts +5 -5
- package/extensions/project-memory/factstore.ts +5 -11
- package/extensions/project-memory/index.ts +48 -34
- package/extensions/project-memory/package.json +1 -1
- package/extensions/project-memory/sci-renderers.ts +1 -1
- package/extensions/render/index.ts +1 -1
- package/extensions/session-log.ts +1 -1
- package/extensions/spinner-verbs.ts +1 -1
- package/extensions/style.ts +1 -1
- package/extensions/terminal-title.ts +3 -3
- package/extensions/tool-profile/index.ts +1 -1
- package/extensions/vault/index.ts +1 -1
- package/extensions/version-check.ts +13 -9
- package/extensions/view/index.ts +4 -4
- package/extensions/web-search/index.ts +5 -2
- package/extensions/web-ui/index.ts +1 -1
- package/extensions/web-ui/state.ts +1 -1
- package/package.json +8 -7
- package/scripts/preinstall.sh +19 -3
- package/scripts/publish-pi-mono.sh +92 -0
- package/skills/pi-extensions/SKILL.md +2 -2
- package/skills/pi-tui/SKILL.md +17 -17
- package/skills/typescript/SKILL.md +1 -1
- package/themes/alpharius.json +7 -6
- /package/extensions/{debug.ts → lib/debug.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ExtensionAPI, ExtensionContext } from "@
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@styrene-lab/pi-coding-agent";
|
|
2
2
|
import { basename } from "path";
|
|
3
|
-
import { DASHBOARD_UPDATE_EVENT, sharedState } from "./shared-state.ts";
|
|
3
|
+
import { DASHBOARD_UPDATE_EVENT, sharedState } from "./lib/shared-state.ts";
|
|
4
4
|
import type { CleaveState } from "./dashboard/types.ts";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -65,7 +65,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
65
65
|
function render() {
|
|
66
66
|
if (!ctx?.ui?.setTitle) return;
|
|
67
67
|
|
|
68
|
-
const parts: string[] = [
|
|
68
|
+
const parts: string[] = [`Ω ${project}`];
|
|
69
69
|
|
|
70
70
|
// Cleave dispatch — takes priority when active
|
|
71
71
|
const cleaveActive = cleaveStatus !== "idle" && cleaveStatus !== "done" && cleaveStatus !== "failed";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* manage_tools — List, enable, disable tools or switch profiles
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import type { ExtensionAPI } from "@
|
|
17
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
18
18
|
import { Type } from "@sinclair/typebox";
|
|
19
19
|
import { StringEnum } from "../lib/typebox-helpers.ts";
|
|
20
20
|
import {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { execSync, spawn, type ChildProcess } from "node:child_process";
|
|
18
|
-
import type { ExtensionAPI } from "@
|
|
18
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
19
19
|
|
|
20
20
|
const DEFAULT_PORT = 3333;
|
|
21
21
|
const BINARY_NAME = "mdserve";
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Respects PI_SKIP_VERSION_CHECK and PI_OFFLINE environment variables.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { ExtensionAPI } from "@
|
|
11
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
12
12
|
import { readFileSync } from "node:fs";
|
|
13
13
|
import { join, dirname } from "node:path";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
@@ -45,15 +45,19 @@ async function fetchLatestRelease(): Promise<string | null> {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/**
|
|
49
|
-
function isNewer(latest: string, current: string): boolean {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
/** Compare dotted numeric version parts, including fork/prerelease suffix digits. */
|
|
49
|
+
export function isNewer(latest: string, current: string): boolean {
|
|
50
|
+
const latestParts = latest.match(/\d+/g)?.map((part) => Number.parseInt(part, 10)) ?? [];
|
|
51
|
+
const currentParts = current.match(/\d+/g)?.map((part) => Number.parseInt(part, 10)) ?? [];
|
|
52
|
+
const length = Math.max(latestParts.length, currentParts.length);
|
|
53
|
+
|
|
54
|
+
for (let i = 0; i < length; i += 1) {
|
|
55
|
+
const latestPart = latestParts[i] ?? 0;
|
|
56
|
+
const currentPart = currentParts[i] ?? 0;
|
|
57
|
+
if (latestPart > currentPart) return true;
|
|
58
|
+
if (latestPart < currentPart) return false;
|
|
56
59
|
}
|
|
60
|
+
|
|
57
61
|
return false;
|
|
58
62
|
}
|
|
59
63
|
|
package/extensions/view/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "node:fs";
|
|
26
26
|
import { basename, extname, resolve, join, relative } from "node:path";
|
|
27
27
|
import { tmpdir } from "node:os";
|
|
28
|
-
import type { ExtensionAPI } from "@
|
|
28
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
29
29
|
import { Type } from "@sinclair/typebox";
|
|
30
30
|
import { resolveUri, loadConfig, osc8Link } from "./uri-resolver.js";
|
|
31
31
|
import { getMdservePort } from "../vault/index.ts";
|
|
@@ -704,11 +704,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
704
704
|
// Custom message renderer for /view output
|
|
705
705
|
// ------------------------------------------------------------------
|
|
706
706
|
pi.registerMessageRenderer("view", (message, options, theme) => {
|
|
707
|
-
const tui = require("@
|
|
707
|
+
const tui = require("@styrene-lab/pi-tui");
|
|
708
708
|
const { Container, Text, Image, Markdown, Spacer } = tui;
|
|
709
709
|
|
|
710
710
|
let piAgent: any;
|
|
711
|
-
try { piAgent = require("@
|
|
711
|
+
try { piAgent = require("@styrene-lab/pi-coding-agent"); } catch { piAgent = null; }
|
|
712
712
|
|
|
713
713
|
const container = new Container();
|
|
714
714
|
|
|
@@ -768,7 +768,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
768
768
|
const maxWidth = scale?.widthCells ?? 999; // Default: fill terminal
|
|
769
769
|
|
|
770
770
|
await ctx.ui.custom((tui: any, theme: any, _kb: any, done: (r: void) => void) => {
|
|
771
|
-
const piTui = require("@
|
|
771
|
+
const piTui = require("@styrene-lab/pi-tui");
|
|
772
772
|
const { Container, Text, Image: ImageComp, Spacer, DynamicBorder, getEditorKeybindings } = piTui;
|
|
773
773
|
|
|
774
774
|
const container = new Container();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @secret TAVILY_API_KEY "Tavily Search API key"
|
|
3
3
|
// @secret SERPER_API_KEY "Serper/Google Search API key"
|
|
4
4
|
|
|
5
|
-
import type { ExtensionAPI } from "@
|
|
5
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
6
6
|
import { Type } from "@sinclair/typebox";
|
|
7
7
|
import { StringEnum } from "../lib/typebox-helpers";
|
|
8
8
|
import { getAvailableProviders, getProvider, type SearchResult } from "./providers.ts";
|
|
@@ -176,7 +176,10 @@ Only providers with configured API keys are available.`,
|
|
|
176
176
|
"info"
|
|
177
177
|
);
|
|
178
178
|
} else {
|
|
179
|
-
|
|
179
|
+
const { sharedState } = await import("../lib/shared-state.ts");
|
|
180
|
+
if (!sharedState.bootstrapPending) {
|
|
181
|
+
ctx.ui.notify("Web Search: No API keys configured", "warning");
|
|
182
|
+
}
|
|
180
183
|
}
|
|
181
184
|
});
|
|
182
185
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn as nodeSpawn } from "node:child_process";
|
|
2
|
-
import type { ExtensionAPI } from "@
|
|
2
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
3
3
|
import { startWebUIServer, type WebUIServer } from "./server.ts";
|
|
4
4
|
|
|
5
5
|
let server: WebUIServer | null = null;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import * as fs from "node:fs";
|
|
13
13
|
import * as path from "node:path";
|
|
14
|
-
import { sharedState } from "../shared-state.ts";
|
|
14
|
+
import { sharedState } from "../lib/shared-state.ts";
|
|
15
15
|
import { listChanges, listDesignChanges } from "../openspec/spec.ts";
|
|
16
16
|
import { scanDesignDocs, countAcceptanceCriteria } from "../design-tree/tree.ts";
|
|
17
17
|
import {
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omegon",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Omegon — an opinionated distribution of pi (by Mario Zechner) with extensions for lifecycle management, memory, orchestration, and visualization",
|
|
5
5
|
"bin": {
|
|
6
|
-
"omegon": "bin/
|
|
6
|
+
"omegon": "bin/omegon.mjs",
|
|
7
7
|
"pi": "bin/pi.mjs"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"preinstall": "sh ./scripts/preinstall.sh",
|
|
12
12
|
"test": "npx tsx --test tests/*.test.ts extensions/**/*.test.ts",
|
|
13
|
-
"typecheck": "tsc --noEmit",
|
|
13
|
+
"typecheck": "npx tsc --noEmit",
|
|
14
14
|
"check:lifecycle": "npx tsx extensions/openspec/lifecycle-files.ts",
|
|
15
|
-
"check": "tsc --noEmit && npm run check:lifecycle && npx tsx --test extensions/*.test.ts extensions/**/*.test.ts",
|
|
15
|
+
"check": "npx tsc --noEmit && npm run check:lifecycle && npx tsx --test extensions/*.test.ts extensions/**/*.test.ts",
|
|
16
16
|
"build:pi": "cd vendor/pi-mono && npm run build",
|
|
17
17
|
"update:pi": "git -C vendor/pi-mono pull --ff-only origin main && npm run build:pi",
|
|
18
18
|
"setup": "git submodule update --init --recursive && cd vendor/pi-mono && npm install && npm run build && cd ../.. && npm link --force"
|
|
@@ -72,9 +72,10 @@
|
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@
|
|
76
|
-
"@
|
|
77
|
-
"@
|
|
75
|
+
"@styrene-lab/pi-coding-agent": "0.58.1-cwilson613.1",
|
|
76
|
+
"@styrene-lab/pi-agent-core": "0.58.1",
|
|
77
|
+
"@styrene-lab/pi-ai": "0.58.1-cwilson613.1",
|
|
78
|
+
"@styrene-lab/pi-tui": "0.58.1-cwilson613.1",
|
|
78
79
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
79
80
|
"@resvg/resvg-js": "^2.6.2",
|
|
80
81
|
"@sinclair/typebox": "^0.34.48",
|
package/scripts/preinstall.sh
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
# that bundles extensions, themes, skills, and memory on top of the core
|
|
6
6
|
# pi coding agent by Mario Zechner (@badlogic).
|
|
7
7
|
#
|
|
8
|
-
# Both omegon and the standalone pi packages (@
|
|
9
|
-
# @mariozechner/pi-coding-agent) register a `pi` binary. npm cannot create
|
|
8
|
+
# Both omegon and the standalone pi packages (@styrene-lab/pi-coding-agent,
|
|
9
|
+
# @cwilson613/pi-coding-agent, @mariozechner/pi-coding-agent) register a `pi` binary. npm cannot create
|
|
10
10
|
# a bin link if another package already owns it, so this script removes the
|
|
11
11
|
# standalone pi package before omegon installs — preventing an EEXIST error.
|
|
12
12
|
#
|
|
@@ -21,7 +21,7 @@ if [ "$npm_config_global" != "true" ]; then
|
|
|
21
21
|
exit 0
|
|
22
22
|
fi
|
|
23
23
|
|
|
24
|
-
for pkg in @cwilson613/pi-coding-agent @mariozechner/pi-coding-agent; do
|
|
24
|
+
for pkg in @styrene-lab/pi-coding-agent @cwilson613/pi-coding-agent @mariozechner/pi-coding-agent; do
|
|
25
25
|
if npm ls -g "$pkg" --depth=0 >/dev/null 2>&1; then
|
|
26
26
|
echo ""
|
|
27
27
|
echo " omegon: Found standalone pi package ($pkg)."
|
|
@@ -32,3 +32,19 @@ for pkg in @cwilson613/pi-coding-agent @mariozechner/pi-coding-agent; do
|
|
|
32
32
|
npm uninstall -g "$pkg" 2>/dev/null || true
|
|
33
33
|
fi
|
|
34
34
|
done
|
|
35
|
+
|
|
36
|
+
# Handle self-update: if omegon is already installed, its 'pi' and 'omegon'
|
|
37
|
+
# bin links conflict with the new installation. Remove stale links so npm
|
|
38
|
+
# can recreate them cleanly (avoids EEXIST during `pi update`).
|
|
39
|
+
if npm ls -g omegon --depth=0 >/dev/null 2>&1; then
|
|
40
|
+
prefix="$(npm prefix -g 2>/dev/null)"
|
|
41
|
+
for bin in pi omegon; do
|
|
42
|
+
link="$prefix/bin/$bin"
|
|
43
|
+
if [ -L "$link" ]; then
|
|
44
|
+
target="$(readlink "$link" 2>/dev/null || true)"
|
|
45
|
+
case "$target" in
|
|
46
|
+
*omegon*) rm -f "$link" 2>/dev/null || true ;;
|
|
47
|
+
esac
|
|
48
|
+
fi
|
|
49
|
+
done
|
|
50
|
+
fi
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Publish pi-mono fork packages to npm if their versions don't match what's on the registry.
|
|
3
|
+
# Called by CI before publishing omegon itself.
|
|
4
|
+
# Also rewrites file: refs in both omegon's package.json and pi-mono's internal cross-deps.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
PACKAGES=("ai" "tui" "agent" "coding-agent" "mom" "pods" "web-ui")
|
|
8
|
+
SCOPED_NAMES=("@styrene-lab/pi-ai" "@styrene-lab/pi-tui" "@styrene-lab/pi-agent-core" "@styrene-lab/pi-coding-agent" "@styrene-lab/pi-mom" "@styrene-lab/pi" "@styrene-lab/pi-web-ui")
|
|
9
|
+
BASE="vendor/pi-mono/packages"
|
|
10
|
+
|
|
11
|
+
# Phase 1: Rewrite file: refs in pi-mono packages to pinned versions (for npm publish)
|
|
12
|
+
echo "Phase 1: Rewriting internal file: refs to pinned versions..."
|
|
13
|
+
for i in "${!PACKAGES[@]}"; do
|
|
14
|
+
pkg="${PACKAGES[$i]}"
|
|
15
|
+
dir="$BASE/$pkg"
|
|
16
|
+
[ ! -d "$dir" ] && continue
|
|
17
|
+
|
|
18
|
+
node -e "
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const pkgJson = JSON.parse(fs.readFileSync('$dir/package.json', 'utf8'));
|
|
21
|
+
let changed = false;
|
|
22
|
+
for (const section of ['dependencies', 'peerDependencies']) {
|
|
23
|
+
if (!pkgJson[section]) continue;
|
|
24
|
+
for (const [name, ver] of Object.entries(pkgJson[section])) {
|
|
25
|
+
if (typeof ver === 'string' && ver.startsWith('file:')) {
|
|
26
|
+
// Resolve the target package.json to get its version
|
|
27
|
+
const targetDir = require('path').resolve('$dir', ver.replace('file:', ''));
|
|
28
|
+
try {
|
|
29
|
+
const targetPkg = JSON.parse(fs.readFileSync(targetDir + '/package.json', 'utf8'));
|
|
30
|
+
pkgJson[section][name] = targetPkg.version;
|
|
31
|
+
changed = true;
|
|
32
|
+
console.log(' ' + name + ': file: → ' + targetPkg.version);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.error(' WARNING: could not resolve ' + name + ' at ' + targetDir);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (changed) {
|
|
40
|
+
fs.writeFileSync('$dir/package.json', JSON.stringify(pkgJson, null, '\t') + '\n');
|
|
41
|
+
}
|
|
42
|
+
"
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
# Phase 2: Publish packages in dependency order (runtime core first, then auxiliary packages)
|
|
46
|
+
echo ""
|
|
47
|
+
echo "Phase 2: Publishing packages..."
|
|
48
|
+
for i in "${!PACKAGES[@]}"; do
|
|
49
|
+
pkg="${PACKAGES[$i]}"
|
|
50
|
+
name="${SCOPED_NAMES[$i]}"
|
|
51
|
+
dir="$BASE/$pkg"
|
|
52
|
+
|
|
53
|
+
if [ ! -d "$dir" ]; then
|
|
54
|
+
echo "⚠ Skipping $name — $dir not found"
|
|
55
|
+
continue
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
local_ver=$(node -p "require('./$dir/package.json').version")
|
|
59
|
+
npm_ver=$(npm view "$name" version 2>/dev/null || echo "0.0.0")
|
|
60
|
+
|
|
61
|
+
if [ "$local_ver" = "$npm_ver" ]; then
|
|
62
|
+
echo "✓ $name@$local_ver already published"
|
|
63
|
+
else
|
|
64
|
+
echo "→ Publishing $name@$local_ver (registry has $npm_ver)"
|
|
65
|
+
(cd "$dir" && npm publish --access public --provenance --tag latest)
|
|
66
|
+
fi
|
|
67
|
+
done
|
|
68
|
+
|
|
69
|
+
# Phase 3: Rewrite omegon package.json — file: refs → registry versions
|
|
70
|
+
echo ""
|
|
71
|
+
echo "Phase 3: Rewriting omegon package.json for registry publish..."
|
|
72
|
+
for i in "${!PACKAGES[@]}"; do
|
|
73
|
+
pkg="${PACKAGES[$i]}"
|
|
74
|
+
name="${SCOPED_NAMES[$i]}"
|
|
75
|
+
dir="$BASE/$pkg"
|
|
76
|
+
ver=$(node -p "require('./$dir/package.json').version")
|
|
77
|
+
|
|
78
|
+
node -e "
|
|
79
|
+
const fs = require('fs');
|
|
80
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
81
|
+
if (pkg.dependencies['$name']?.startsWith('file:')) {
|
|
82
|
+
pkg.dependencies['$name'] = '$ver';
|
|
83
|
+
fs.writeFileSync('package.json', JSON.stringify(pkg, null, '\t') + '\n');
|
|
84
|
+
console.log(' ✓ $name → $ver');
|
|
85
|
+
} else {
|
|
86
|
+
console.log(' - $name already pinned');
|
|
87
|
+
}
|
|
88
|
+
"
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
echo "Done. pi-mono packages published and package.json updated for omegon publish."
|
|
@@ -8,7 +8,7 @@ description: Pi extension API reference and conventions. Use when creating, modi
|
|
|
8
8
|
Extensions are TypeScript modules exporting a default function that receives `ExtensionAPI`.
|
|
9
9
|
|
|
10
10
|
```typescript
|
|
11
|
-
import type { ExtensionAPI } from "@
|
|
11
|
+
import type { ExtensionAPI } from "@styrene-lab/pi-coding-agent";
|
|
12
12
|
|
|
13
13
|
export default function (pi: ExtensionAPI) {
|
|
14
14
|
// register tools, commands, shortcuts, event handlers
|
|
@@ -89,7 +89,7 @@ pi.registerTool({
|
|
|
89
89
|
|
|
90
90
|
### StringEnum helper
|
|
91
91
|
|
|
92
|
-
For enum parameters, use the local helper (NOT `@
|
|
92
|
+
For enum parameters, use the local helper (NOT `@styrene-lab/pi-ai`):
|
|
93
93
|
|
|
94
94
|
```typescript
|
|
95
95
|
import { StringEnum } from "../lib/typebox-helpers";
|
package/skills/pi-tui/SKILL.md
CHANGED
|
@@ -14,14 +14,14 @@ This skill covers the TUI layer for pi extensions. Read alongside `pi-extensions
|
|
|
14
14
|
## Package Geography
|
|
15
15
|
|
|
16
16
|
```
|
|
17
|
-
@
|
|
18
|
-
@
|
|
17
|
+
@styrene-lab/pi-coding-agent — ExtensionAPI, Theme, DynamicBorder, BorderedLoader, CustomEditor, etc.
|
|
18
|
+
@styrene-lab/pi-tui — Component, Container, TUI, Text, Box, SelectList, etc.
|
|
19
19
|
@sinclair/typebox — Type schema for tool parameters
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
All three are available via pi's jiti loader at runtime. **Do NOT `npm install` them** — they resolve through the alias map in the extension loader.
|
|
23
23
|
|
|
24
|
-
> ⚠️ Value imports from `@
|
|
24
|
+
> ⚠️ Value imports from `@styrene-lab/pi-tui` (e.g. `truncateToWidth`, `matchesKey`, `visibleWidth`) work inside pi but **fail under `tsx` or `node` directly** because pi-tui is a nested dependency of pi-coding-agent. Tests that need these must either mock them or run through pi.
|
|
25
25
|
|
|
26
26
|
## Component Interface
|
|
27
27
|
|
|
@@ -45,18 +45,18 @@ interface Component {
|
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
47
|
// Types (compile-time only — safe everywhere)
|
|
48
|
-
import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@
|
|
49
|
-
import type { Component, OverlayHandle, OverlayOptions, TUI } from "@
|
|
48
|
+
import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@styrene-lab/pi-coding-agent";
|
|
49
|
+
import type { Component, OverlayHandle, OverlayOptions, TUI } from "@styrene-lab/pi-tui";
|
|
50
50
|
|
|
51
51
|
// Values from pi-coding-agent (re-exported, always available)
|
|
52
|
-
import { DynamicBorder, BorderedLoader, CustomEditor } from "@
|
|
53
|
-
import { getMarkdownTheme, getSelectListTheme, getSettingsListTheme, highlightCode } from "@
|
|
52
|
+
import { DynamicBorder, BorderedLoader, CustomEditor } from "@styrene-lab/pi-coding-agent";
|
|
53
|
+
import { getMarkdownTheme, getSelectListTheme, getSettingsListTheme, highlightCode } from "@styrene-lab/pi-coding-agent";
|
|
54
54
|
|
|
55
55
|
// Values from pi-tui (work via jiti at runtime only)
|
|
56
|
-
import { matchesKey, Key, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@
|
|
57
|
-
import { Container, Text, Box, Spacer, Markdown, Image } from "@
|
|
58
|
-
import { SelectList, SettingsList } from "@
|
|
59
|
-
import type { SelectItem, SelectListTheme, SettingItem } from "@
|
|
56
|
+
import { matchesKey, Key, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@styrene-lab/pi-tui";
|
|
57
|
+
import { Container, Text, Box, Spacer, Markdown, Image } from "@styrene-lab/pi-tui";
|
|
58
|
+
import { SelectList, SettingsList } from "@styrene-lab/pi-tui";
|
|
59
|
+
import type { SelectItem, SelectListTheme, SettingItem } from "@styrene-lab/pi-tui";
|
|
60
60
|
|
|
61
61
|
// TypeBox for tool parameter schemas
|
|
62
62
|
import { Type } from "@sinclair/typebox";
|
|
@@ -175,7 +175,7 @@ overlayOptions: {
|
|
|
175
175
|
## Keyboard Handling
|
|
176
176
|
|
|
177
177
|
```typescript
|
|
178
|
-
import { matchesKey, Key } from "@
|
|
178
|
+
import { matchesKey, Key } from "@styrene-lab/pi-tui";
|
|
179
179
|
|
|
180
180
|
handleInput(data: string): void {
|
|
181
181
|
if (matchesKey(data, Key.escape)) { /* ... */ }
|
|
@@ -210,8 +210,8 @@ After handling input, call `tui.requestRender()` to trigger a redraw.
|
|
|
210
210
|
### SelectList
|
|
211
211
|
|
|
212
212
|
```typescript
|
|
213
|
-
import { SelectList } from "@
|
|
214
|
-
import type { SelectItem } from "@
|
|
213
|
+
import { SelectList } from "@styrene-lab/pi-tui";
|
|
214
|
+
import type { SelectItem } from "@styrene-lab/pi-tui";
|
|
215
215
|
|
|
216
216
|
const items: SelectItem[] = [
|
|
217
217
|
{ value: "a", label: "Option A", description: "Details" },
|
|
@@ -411,7 +411,7 @@ export function renderStatusLine(state: MyState, thFn: ThemeFn, width: number):
|
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
// overlay.ts (pi-tui bridge, not unit-tested)
|
|
414
|
-
import type { Theme } from "@
|
|
414
|
+
import type { Theme } from "@styrene-lab/pi-coding-agent";
|
|
415
415
|
const thFn: ThemeFn = (color, text) => theme.fg(color as any, text);
|
|
416
416
|
const line = renderStatusLine(state, thFn, width);
|
|
417
417
|
```
|
|
@@ -459,7 +459,7 @@ class CachedComponent {
|
|
|
459
459
|
For components with text cursors (CJK input method support):
|
|
460
460
|
|
|
461
461
|
```typescript
|
|
462
|
-
import { CURSOR_MARKER, type Focusable } from "@
|
|
462
|
+
import { CURSOR_MARKER, type Focusable } from "@styrene-lab/pi-tui";
|
|
463
463
|
|
|
464
464
|
class MyInput implements Component, Focusable {
|
|
465
465
|
focused = false;
|
|
@@ -478,7 +478,7 @@ Container components with embedded inputs must propagate `focused` to child inpu
|
|
|
478
478
|
Extend `CustomEditor` (not `Editor`) for vim-mode or alternative key handling:
|
|
479
479
|
|
|
480
480
|
```typescript
|
|
481
|
-
import { CustomEditor } from "@
|
|
481
|
+
import { CustomEditor } from "@styrene-lab/pi-coding-agent";
|
|
482
482
|
|
|
483
483
|
class VimEditor extends CustomEditor {
|
|
484
484
|
private mode: "normal" | "insert" = "insert";
|
|
@@ -219,7 +219,7 @@ interface ToolResult {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
// ✅ Import from SDK
|
|
222
|
-
import type { AgentToolResult } from "@
|
|
222
|
+
import type { AgentToolResult } from "@styrene-lab/pi-coding-agent";
|
|
223
223
|
```
|
|
224
224
|
|
|
225
225
|
**Directive:** Always import SDK types. Never redefine them locally. If an SDK type is not exported, file an issue or use module augmentation — don't copy the shape.
|
package/themes/alpharius.json
CHANGED
|
@@ -9,15 +9,16 @@
|
|
|
9
9
|
"mutedFg": "#607888",
|
|
10
10
|
"dimFg": "#405870",
|
|
11
11
|
"bg": "#02030a",
|
|
12
|
-
"cardBg": "#
|
|
13
|
-
"surfaceBg": "#
|
|
12
|
+
"cardBg": "#080e1a",
|
|
13
|
+
"surfaceBg": "#0a1020",
|
|
14
14
|
"borderColor": "#1a4458",
|
|
15
|
-
"borderDim": "#
|
|
15
|
+
"borderDim": "#0c1828",
|
|
16
16
|
"green": "#1ab878",
|
|
17
17
|
"red": "#e04848",
|
|
18
18
|
"orange": "#c86418",
|
|
19
19
|
"yellow": "#78b820",
|
|
20
|
-
"selectedBg": "#
|
|
20
|
+
"selectedBg": "#081020",
|
|
21
|
+
"userMsgBg": "#0a1225",
|
|
21
22
|
"toolErrorBg": "#1a0a10",
|
|
22
23
|
"syntaxComment": "#344858",
|
|
23
24
|
"syntaxType": "#5aa8e0",
|
|
@@ -36,13 +37,13 @@
|
|
|
36
37
|
"text": "fg",
|
|
37
38
|
"thinkingText": "dimFg",
|
|
38
39
|
"selectedBg": "selectedBg",
|
|
39
|
-
"userMessageBg": "
|
|
40
|
+
"userMessageBg": "userMsgBg",
|
|
40
41
|
"userMessageText": "fg",
|
|
41
42
|
"customMessageBg": "bg",
|
|
42
43
|
"customMessageText": "fg",
|
|
43
44
|
"customMessageLabel": "primaryMuted",
|
|
44
45
|
"toolPendingBg": "cardBg",
|
|
45
|
-
"toolSuccessBg": "
|
|
46
|
+
"toolSuccessBg": "#081018",
|
|
46
47
|
"toolErrorBg": "toolErrorBg",
|
|
47
48
|
"toolTitle": "primary",
|
|
48
49
|
"toolOutput": "mutedFg",
|
|
File without changes
|