omni-pi 0.8.3 → 0.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.1 - 2026-04-24
4
+
5
+ ### Release follow-up
6
+
7
+ - republished the previous 0.10.0 release work under a new patch version because npm will not republish a previously published version number
8
+ - kept the bundled `pi-diff-review` and `pi-prompt-template-model` integration changes intact
9
+
10
+ ## 0.10.0 - 2026-04-24
11
+
12
+ ### Runtime and integrations
13
+
14
+ - upgraded `@mariozechner/pi-coding-agent` to `0.70.0`
15
+ - bundled `pi-diff-review` as a packaged Omni-Pi dependency so `/diff-review` is available out of the box
16
+ - vendored `pi-diff-review` locally so global installs no longer fail on the extension's git prepare hook
17
+ - bundled `pi-prompt-template-model` so packaged prompt templates can register smarter slash commands
18
+
19
+ ### Commands
20
+
21
+ - added `/commit` to review local changes and create a descriptive conventional commit
22
+ - added `/push` with a deterministic first `git push` attempt that only hands off to the model when the push fails
23
+
3
24
  ## 0.8.3 - 2026-04-17
4
25
 
5
26
  ### Model refresh flow
package/README.md CHANGED
@@ -14,7 +14,8 @@ Requires Node.js 22 or newer.
14
14
  - `/omni-mode` turns on Omni's specialized interview, plan, build, and verify workflow for the current project.
15
15
  - Keeps durable standards and project context in `.omni/`, even when Omni mode is off.
16
16
  - Writes specs, tasks, and progress into `.omni/` once Omni mode is enabled.
17
- - Bundles web search, guided interviews, themed UI, native micro-UI via Glimpse, a task viewer, a powerbar, custom provider/model management, and automatic updates out of the box.
17
+ - Adds a repo map that indexes supported source files, ranks them by structure plus recent activity, and injects a compact codebase-awareness block into Omni prompts.
18
+ - Bundles web search, guided interviews, themed UI, native micro-UI via Glimpse, native git diff review, prompt-template-powered workflow commands, a task viewer, a powerbar, custom provider/model management, and automatic updates out of the box.
18
19
 
19
20
  ## Install
20
21
 
@@ -41,6 +42,25 @@ Omni-Pi now ships the essential skill-discovery stack in the package itself:
41
42
  - `skill-creator` is bundled for creating project-specific skills when nothing suitable exists
42
43
  - `brainstorming` is bundled and used for Omni planning and task creation flows
43
44
 
45
+ ### Repo Map
46
+
47
+ Omni-Pi now includes a SoulForge-style repo map for codebase awareness while Omni mode is on.
48
+
49
+ The first shipped version includes:
50
+
51
+ - incremental indexing of supported repo files while respecting `.gitignore`
52
+ - symbol/import extraction for TypeScript/JavaScript-family files with graceful fallback for partial/unsupported cases
53
+ - graph-aware ranking blended with current-turn boosts from recent reads, edits, writes, and prompt mentions
54
+ - budget-aware prompt rendering so Omni gets a compact ranked view of important files and exported symbols
55
+ - runtime cache storage under `.pi/repo-map/` rather than durable `.omni/` memory
56
+
57
+ Current deferred roadmap items remain intentional and visible in docs rather than hidden in code:
58
+
59
+ - semantic symbol summaries
60
+ - git co-change ranking
61
+ - richer analysis views such as dead-code or clone-detection signals
62
+ - broader parser/language coverage as needed
63
+
44
64
  ### Bundled Extensions
45
65
 
46
66
  | Extension | What it does |
@@ -51,6 +71,8 @@ Omni-Pi now ships the essential skill-discovery stack in the package itself:
51
71
  | **glimpseui** | Native micro-UI windows and the optional floating companion widget |
52
72
  | **pi-web-access** | Web search and fetch tools for the agent |
53
73
  | **pi-interview** | Guided Q&A when the agent needs clarification |
74
+ | **pi-diff-review** | Native git diff review window that inserts structured review feedback into the editor |
75
+ | **pi-prompt-template-model** | Prompt templates can set thinking/model behavior and back commands like `/commit` and `/push` |
54
76
  | **pi-powerbar** | Powerline-style status bar with segments |
55
77
  | **pi-extension-settings** | Settings persistence for extensions |
56
78
 
@@ -70,6 +92,9 @@ Omni-Pi now bundles [Glimpse](https://github.com/HazAT/glimpse) for native micro
70
92
  | `/manage-providers` | Remove stored auth for bundled providers |
71
93
  | `/omni-mode` | Toggle persistent Omni mode on or off for this project |
72
94
  | `/companion` | Toggle the Glimpse floating companion widget |
95
+ | `/diff-review` | Open a native git diff review window and insert feedback into the editor |
96
+ | `/commit` | Review local changes and create a descriptive conventional commit |
97
+ | `/push` | Push the current branch, with automatic recovery flow if the first push fails |
73
98
  | `/theme` | Switch between color presets (lavender, ember, ocean, mint, rose, gold, arctic, neon, copper, slate) |
74
99
  | `/update` | Check for Omni-Pi updates |
75
100
 
@@ -107,6 +132,7 @@ Omni-Pi keeps its current branding and shell at all times, but the specialized w
107
132
 
108
133
  - When Omni mode is off, Omni behaves like normal Pi and only uses `.omni/` as passive standards/context when those files already exist.
109
134
  - When Omni mode is on, Omni lazily initializes or migrates `.omni/` on the first real turn, then uses the full interview, planning, task, and verification workflow.
135
+ - While Omni mode is on, Omni also maintains a runtime repo map in `.pi/repo-map/` so prompts can include a compact ranked view of important files and symbols.
110
136
  - During Omni init, Omni can discover standards from files like `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, Copilot instructions, Cursor rules, Windsurf rules, and Continue rules, then ask whether to keep those standards in Omni's durable memory.
111
137
  - In Git repos, Omni ensures `.pi/` is ignored because that directory is only runtime-local Pi state.
112
138
  - While Omni mode is on, every planned or executed task checks for required skills, auto-installs matching skills into `.omni/project-skills/`, creates a project skill when none exists, records task-to-skill dependencies, and removes project skills once no open task still needs them.
@@ -1,3 +1,5 @@
1
+ import { fileURLToPath } from "node:url";
2
+
1
3
  import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
4
 
3
5
  import {
@@ -12,13 +14,25 @@ import {
12
14
  registerOmniMessageRenderer,
13
15
  registerPiCommands,
14
16
  } from "../../src/pi.js";
17
+ import { ensureBundledPromptTemplates } from "../../src/prompt-template-sync.js";
15
18
  import { registerProviderAuthCommand } from "../../src/provider-auth-command.js";
19
+ import {
20
+ buildRepoMapPromptSuffix,
21
+ registerRepoMapTracking,
22
+ warmRepoMap,
23
+ } from "../../src/repo-map-runtime.js";
24
+ import {
25
+ formatRtkModeStatus,
26
+ refreshRtkStatusIndicator,
27
+ registerRtkBashRouting,
28
+ } from "../../src/rtk.js";
16
29
  import {
17
30
  createOmniTheme,
18
31
  ensurePiSettings,
19
32
  formatOmniModeStatus,
20
33
  loadSavedTheme,
21
34
  readOmniMode,
35
+ readRtkMode,
22
36
  } from "../../src/theme.js";
23
37
  import { registerThemeCommand } from "../../src/theme-command.js";
24
38
  import { registerTodoShortcut } from "../../src/todo-shortcut.js";
@@ -33,23 +47,37 @@ export default function omniCoreExtension(api: ExtensionAPI): void {
33
47
  registerThemeCommand(api);
34
48
  registerTodoShortcut(api);
35
49
  registerUpdater(api);
50
+ registerRtkBashRouting(api);
51
+ registerRepoMapTracking(api);
36
52
 
37
53
  api.on("session_start", async (_event, ctx) => {
38
54
  await ensurePiSettings(ctx.cwd);
55
+ ensureBundledPromptTemplates(
56
+ fileURLToPath(
57
+ new URL("../../templates/managed-prompts", import.meta.url),
58
+ ),
59
+ );
39
60
  loadSavedTheme(ctx.cwd);
40
61
  const omniMode = readOmniMode(ctx.cwd);
41
62
  ctx.ui.setTitle("Omni-Pi");
42
63
  ctx.ui.setTheme(createOmniTheme());
43
64
  ctx.ui.setHeader((_tui, theme) => renderHeader(theme));
44
65
  ctx.ui.setStatus("omni", formatOmniModeStatus(omniMode));
66
+ ctx.ui.setStatus("rtk", formatRtkModeStatus(readRtkMode(ctx.cwd), false));
67
+ await refreshRtkStatusIndicator(ctx);
68
+ void warmRepoMap(ctx.cwd);
45
69
  });
46
70
 
47
71
  api.on("before_agent_start", async (event, ctx) => {
48
72
  const omniMode = readOmniMode(ctx.cwd);
49
73
  const passivePrompt = await buildPassiveOmniPromptSuffix(ctx.cwd);
74
+ const repoMapPrompt = await buildRepoMapPromptSuffix(ctx.cwd, {
75
+ prompt: typeof event.prompt === "string" ? event.prompt : "",
76
+ maxTokens: omniMode ? undefined : 120,
77
+ });
50
78
  if (!omniMode) {
51
79
  return {
52
- systemPrompt: [event.systemPrompt, passivePrompt]
80
+ systemPrompt: [event.systemPrompt, passivePrompt, repoMapPrompt]
53
81
  .filter(Boolean)
54
82
  .join("\n\n"),
55
83
  };
@@ -66,6 +94,7 @@ export default function omniCoreExtension(api: ExtensionAPI): void {
66
94
  event.systemPrompt,
67
95
  passivePrompt,
68
96
  workflowPrompt,
97
+ repoMapPrompt,
69
98
  onboardingKickoff,
70
99
  ]
71
100
  .filter(Boolean)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omni-pi",
3
- "version": "0.8.3",
3
+ "version": "0.10.1",
4
4
  "description": "Single-agent Pi package that interviews the user, documents the spec, and implements work in bounded slices.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -36,6 +36,7 @@
36
36
  "skills",
37
37
  "src",
38
38
  "templates",
39
+ "vendor/pi-diff-review",
39
40
  "README.md",
40
41
  "PROVIDERS.md",
41
42
  "CREDITS.md"
@@ -64,13 +65,16 @@
64
65
  "./node_modules/glimpseui/pi-extension/index.ts",
65
66
  "./node_modules/pi-web-access/index.ts",
66
67
  "./node_modules/pi-interview/index.ts",
68
+ "./node_modules/pi-diff-review/src/index.ts",
69
+ "./node_modules/pi-prompt-template-model/index.ts",
67
70
  "./node_modules/@juanibiapina/pi-extension-settings/dist/index.js",
68
71
  "./node_modules/@juanibiapina/pi-powerbar/dist"
69
72
  ],
70
73
  "skills": [
71
74
  "./skills",
72
75
  "./node_modules/glimpseui/skills",
73
- "./node_modules/pi-web-access/skills"
76
+ "./node_modules/pi-web-access/skills",
77
+ "./node_modules/pi-prompt-template-model/skills"
74
78
  ],
75
79
  "prompts": [
76
80
  "./prompts"
@@ -78,12 +82,14 @@
78
82
  },
79
83
  "dependencies": {
80
84
  "@anthropic-ai/claude-agent-sdk": "0.2.84",
81
- "@juanibiapina/pi-extension-settings": "^0.6.0",
82
- "@juanibiapina/pi-powerbar": "^0.7.1",
83
- "@mariozechner/pi-coding-agent": "^0.65.2",
84
- "glimpseui": "^0.6.2",
85
- "pi-interview": "^0.5.5",
86
- "pi-web-access": "^0.10.3",
85
+ "@juanibiapina/pi-extension-settings": "^0.6.1",
86
+ "@juanibiapina/pi-powerbar": "^0.8.0",
87
+ "@mariozechner/pi-coding-agent": "^0.70.0",
88
+ "glimpseui": "^0.7.0",
89
+ "pi-diff-review": "file:./vendor/pi-diff-review",
90
+ "pi-interview": "^0.6.2",
91
+ "pi-prompt-template-model": "^0.8.2",
92
+ "pi-web-access": "^0.10.6",
87
93
  "zod": "^4.3.6"
88
94
  },
89
95
  "overrides": {
package/src/commands.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { AppCommandDefinition } from "./pi.js";
2
+ import { executeRtkCommand } from "./rtk.js";
2
3
  import { formatOmniModeStatus, readOmniMode, saveOmniMode } from "./theme.js";
3
4
 
4
5
  export function createOmniCommands(): AppCommandDefinition[] {
@@ -22,5 +23,16 @@ export function createOmniCommands(): AppCommandDefinition[] {
22
23
  : "Omni mode is now OFF. Omni will keep using durable standards from .omni/ when present, but task workflow state is disabled.";
23
24
  },
24
25
  },
26
+ {
27
+ name: "omni-rtk",
28
+ description:
29
+ "Install RTK and control Omni's bash-side RTK routing (status, install, on, off)",
30
+ async execute(context) {
31
+ if (!context.runtime) {
32
+ return "The /omni-rtk command is only available inside Omni-Pi interactive sessions.";
33
+ }
34
+ return await executeRtkCommand(context.args, context.runtime.ctx);
35
+ },
36
+ },
25
37
  ];
26
38
  }
@@ -0,0 +1,63 @@
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ readFileSync,
5
+ rmSync,
6
+ writeFileSync,
7
+ } from "node:fs";
8
+ import os from "node:os";
9
+ import path from "node:path";
10
+
11
+ const MANAGED_PROMPT_FILES = ["commit.md", "push.md"] as const;
12
+ const MANAGED_SUBDIR = "omni-pi";
13
+ const LEGACY_MANAGED_SUBDIRS = ["zz-omni-pi"] as const;
14
+
15
+ export function ensureBundledPromptTemplates(
16
+ sourceDir: string,
17
+ options?: {
18
+ homeDir?: string;
19
+ targetSubdir?: string;
20
+ promptFiles?: readonly string[];
21
+ legacySubdirs?: readonly string[];
22
+ },
23
+ ): string[] {
24
+ const homeDir = options?.homeDir ?? os.homedir();
25
+ const targetSubdir = options?.targetSubdir ?? MANAGED_SUBDIR;
26
+ const promptFiles = options?.promptFiles ?? MANAGED_PROMPT_FILES;
27
+ const legacySubdirs = options?.legacySubdirs ?? LEGACY_MANAGED_SUBDIRS;
28
+ const promptsRoot = path.join(homeDir, ".pi", "agent", "prompts");
29
+ const targetDir = path.join(promptsRoot, targetSubdir);
30
+
31
+ for (const legacySubdir of legacySubdirs) {
32
+ const legacyDir = path.join(promptsRoot, legacySubdir);
33
+ if (legacyDir === targetDir || !existsSync(legacyDir)) {
34
+ continue;
35
+ }
36
+ rmSync(legacyDir, { recursive: true, force: true });
37
+ }
38
+
39
+ mkdirSync(targetDir, { recursive: true });
40
+
41
+ const written: string[] = [];
42
+ for (const file of promptFiles) {
43
+ const sourcePath = path.join(sourceDir, file);
44
+ const targetPath = path.join(targetDir, file);
45
+ const nextContent = readFileSync(sourcePath, "utf8");
46
+
47
+ let currentContent: string | null = null;
48
+ try {
49
+ currentContent = readFileSync(targetPath, "utf8");
50
+ } catch {
51
+ currentContent = null;
52
+ }
53
+
54
+ if (currentContent === nextContent) {
55
+ continue;
56
+ }
57
+
58
+ writeFileSync(targetPath, nextContent, "utf8");
59
+ written.push(targetPath);
60
+ }
61
+
62
+ return written;
63
+ }
@@ -0,0 +1,93 @@
1
+ import path from "node:path";
2
+
3
+ export const REPO_MAP_DIR = path.join(".pi", "repo-map");
4
+ export const REPO_MAP_STATE_FILE = path.join(REPO_MAP_DIR, "state.json");
5
+ export const REPO_MAP_SCHEMA_VERSION = 1;
6
+
7
+ export type RepoMapParserStatus =
8
+ | "indexed"
9
+ | "unsupported"
10
+ | "binary-fallback"
11
+ | "parse-fallback";
12
+
13
+ export type RepoMapSignalType = "read" | "edit" | "write" | "mention";
14
+
15
+ export interface RepoMapSymbol {
16
+ name: string;
17
+ kind:
18
+ | "function"
19
+ | "class"
20
+ | "interface"
21
+ | "type"
22
+ | "enum"
23
+ | "const"
24
+ | "default"
25
+ | "module";
26
+ signature?: string;
27
+ exported: boolean;
28
+ }
29
+
30
+ export interface RepoMapImport {
31
+ specifier: string;
32
+ resolvedPath?: string;
33
+ }
34
+
35
+ export interface RepoMapFileRecord {
36
+ path: string;
37
+ language: string;
38
+ parserStatus: RepoMapParserStatus;
39
+ size: number;
40
+ mtimeMs: number;
41
+ fingerprint: string;
42
+ indexedAt: string;
43
+ firstIndexedAt: string;
44
+ symbols: RepoMapSymbol[];
45
+ imports: RepoMapImport[];
46
+ outgoingPaths: string[];
47
+ incomingPaths: string[];
48
+ }
49
+
50
+ export interface RepoMapState {
51
+ schemaVersion: number;
52
+ indexedAt: string;
53
+ files: Record<string, RepoMapFileRecord>;
54
+ }
55
+
56
+ export interface RepoMapRankedEntry {
57
+ path: string;
58
+ file: RepoMapFileRecord;
59
+ baseScore: number;
60
+ turnScore: number;
61
+ finalScore: number;
62
+ blastRadius: number;
63
+ tags: string[];
64
+ }
65
+
66
+ export interface RepoMapSignal {
67
+ type: RepoMapSignalType;
68
+ path: string;
69
+ timestamp: number;
70
+ }
71
+
72
+ export interface RepoMapSessionState {
73
+ signals: RepoMapSignal[];
74
+ dirtyPaths: Set<string>;
75
+ }
76
+
77
+ export interface RepoMapRenderOptions {
78
+ prompt?: string;
79
+ maxTokens?: number;
80
+ }
81
+
82
+ export interface RepoMapRefreshResult {
83
+ state: RepoMapState;
84
+ indexedPaths: string[];
85
+ removedPaths: string[];
86
+ reusedPaths: string[];
87
+ }
88
+
89
+ export interface RepoMapDebugSnapshot {
90
+ state: RepoMapState;
91
+ ranked: RepoMapRankedEntry[];
92
+ rendered: string;
93
+ }