@code-yeongyu/senpi 2026.8.10 → 2026.8.11

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 (32) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/core/footer-data-provider.d.ts +1 -4
  3. package/dist/core/footer-data-provider.d.ts.map +1 -1
  4. package/dist/core/footer-data-provider.js +0 -7
  5. package/dist/core/footer-data-provider.js.map +1 -1
  6. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  7. package/dist/modes/interactive/components/footer.js +1 -8
  8. package/dist/modes/interactive/components/footer.js.map +1 -1
  9. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  10. package/dist/modes/interactive/interactive-mode.js +0 -2
  11. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  12. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  13. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  14. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  15. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  16. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  17. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  18. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  19. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  20. package/package.json +6 -6
  21. package/dist/core/omo-native-detect.d.ts +0 -3
  22. package/dist/core/omo-native-detect.d.ts.map +0 -1
  23. package/dist/core/omo-native-detect.js +0 -64
  24. package/dist/core/omo-native-detect.js.map +0 -1
  25. package/dist/core/omo-native-detect.test.d.ts +0 -2
  26. package/dist/core/omo-native-detect.test.d.ts.map +0 -1
  27. package/dist/core/omo-native-detect.test.js +0 -47
  28. package/dist/core/omo-native-detect.test.js.map +0 -1
  29. package/dist/modes/interactive/components/footer-omo-native-badge.test.d.ts +0 -2
  30. package/dist/modes/interactive/components/footer-omo-native-badge.test.d.ts.map +0 -1
  31. package/dist/modes/interactive/components/footer-omo-native-badge.test.js +0 -52
  32. package/dist/modes/interactive/components/footer-omo-native-badge.test.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-ai",
3
3
  "private": true,
4
- "version": "2026.8.10",
4
+ "version": "2026.8.11",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-pty",
3
3
  "private": true,
4
- "version": "2026.8.10",
4
+ "version": "2026.8.11",
5
5
  "description": "Typed PTY session loader for Senpi persistent terminals",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-tui",
3
3
  "private": true,
4
- "version": "2026.8.10",
4
+ "version": "2026.8.11",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.8.10",
3
+ "version": "2026.8.11",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -48,11 +48,11 @@
48
48
  "dependencies": {
49
49
  "@anthropic-ai/sdk": "0.91.1",
50
50
  "@aws-sdk/client-bedrock-runtime": "3.1095.0",
51
- "@code-yeongyu/senpi-codemode": "2026.8.10",
52
- "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.10",
53
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.10",
54
- "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.10",
55
- "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.10",
51
+ "@code-yeongyu/senpi-codemode": "2026.8.11",
52
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.11",
53
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.11",
54
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.11",
55
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.11",
56
56
  "@mistralai/mistralai": "2.5.0",
57
57
  "@modelcontextprotocol/sdk": "1.30.0",
58
58
  "@mozilla/readability": "0.6.0",
@@ -1,3 +0,0 @@
1
- import type { PackageSource } from "./settings-manager.ts";
2
- export declare function detectOmoNativeInstall(packages: PackageSource[] | undefined, agentDir: string, env?: Record<string, string | undefined>): boolean;
3
- //# sourceMappingURL=omo-native-detect.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"omo-native-detect.d.ts","sourceRoot":"","sources":["../../src/core/omo-native-detect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA+B3D,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACnD,OAAO,CA+BT"}
@@ -1,64 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { join, resolve } from "node:path";
4
- import { isLocalPath, resolvePath } from "../utils/paths.js";
5
- /**
6
- * Synchronous, dependency-free detection of the "OMO Native" local install: a settings
7
- * `packages` entry that is a local path resolving to a dir whose package.json name is
8
- * `@code-yeongyu/omo-senpi`, whose derived repo root (pluginPath/../../..) contains both
9
- * workspace packages `@oh-my-opencode/omo-senpi` and `@oh-my-opencode/senpi-task`.
10
- *
11
- * This mirrors gates 1 and 2 of the beta `detectOmoLocalInstall` (beta/omo-local-update.ts)
12
- * but drops gate 3 (the `git rev-parse --show-toplevel` integrity check) so it stays sync and
13
- * cheap enough for footer rendering. The beta module's export policy forbids importing its
14
- * helpers into production core, so this isolated module is the footer's own detection.
15
- */
16
- const OMO_SENPI_PLUGIN_PACKAGE = "@code-yeongyu/omo-senpi";
17
- const OMO_SENPI_WORKSPACE_PACKAGE = "@oh-my-opencode/omo-senpi";
18
- const SENPI_TASK_WORKSPACE_PACKAGE = "@oh-my-opencode/senpi-task";
19
- function homeDir() {
20
- return process.env.HOME || homedir();
21
- }
22
- function readPackageName(packageJsonPath) {
23
- try {
24
- const json = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
25
- const name = json.name;
26
- return typeof name === "string" ? name : undefined;
27
- }
28
- catch {
29
- return undefined;
30
- }
31
- }
32
- export function detectOmoNativeInstall(packages, agentDir, env = process.env) {
33
- // The omo launcher marks every senpi spawn it owns; omo-ai global installs load the plugin via
34
- // --extension, so no settings.packages entry ever exists for them and the env marker is the only
35
- // signal available at footer-render time.
36
- if (env.OMO_NATIVE === "1") {
37
- return true;
38
- }
39
- if (!packages) {
40
- return false;
41
- }
42
- for (const entry of packages) {
43
- const source = typeof entry === "string" ? entry : entry.source;
44
- if (!isLocalPath(source)) {
45
- continue;
46
- }
47
- const pluginPath = resolvePath(source, agentDir, { homeDir: homeDir(), trim: true });
48
- if (readPackageName(join(pluginPath, "package.json")) !== OMO_SENPI_PLUGIN_PACKAGE) {
49
- continue;
50
- }
51
- const repoRoot = resolve(pluginPath, "..", "..", "..");
52
- const omoSenpiPkg = join(repoRoot, "packages", "omo-senpi", "package.json");
53
- if (!existsSync(omoSenpiPkg) || readPackageName(omoSenpiPkg) !== OMO_SENPI_WORKSPACE_PACKAGE) {
54
- continue;
55
- }
56
- const senpiTaskPkg = join(repoRoot, "packages", "senpi-task", "package.json");
57
- if (!existsSync(senpiTaskPkg) || readPackageName(senpiTaskPkg) !== SENPI_TASK_WORKSPACE_PACKAGE) {
58
- continue;
59
- }
60
- return true;
61
- }
62
- return false;
63
- }
64
- //# sourceMappingURL=omo-native-detect.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"omo-native-detect.js","sourceRoot":"","sources":["../../src/core/omo-native-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;;;;;GAUG;AACH,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAC3D,MAAM,2BAA2B,GAAG,2BAA2B,CAAC;AAChE,MAAM,4BAA4B,GAAG,4BAA4B,CAAC;AAElE,SAAS,OAAO;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,eAAe,CAAC,eAAuB;IAC/C,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAuB,CAAC;QACtF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,QAAqC,EACrC,QAAgB,EAChB,GAAG,GAAuC,OAAO,CAAC,GAAG;IAErD,+FAA+F;IAC/F,iGAAiG;IACjG,0CAA0C;IAC1C,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACd,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QAChE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,SAAS;QACV,CAAC;QACD,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,KAAK,wBAAwB,EAAE,CAAC;YACpF,SAAS;QACV,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAC5E,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC,WAAW,CAAC,KAAK,2BAA2B,EAAE,CAAC;YAC9F,SAAS;QACV,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QAC9E,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,eAAe,CAAC,YAAY,CAAC,KAAK,4BAA4B,EAAE,CAAC;YACjG,SAAS;QACV,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { isLocalPath, resolvePath } from \"../utils/paths.ts\";\nimport type { PackageSource } from \"./settings-manager.ts\";\n\n/**\n * Synchronous, dependency-free detection of the \"OMO Native\" local install: a settings\n * `packages` entry that is a local path resolving to a dir whose package.json name is\n * `@code-yeongyu/omo-senpi`, whose derived repo root (pluginPath/../../..) contains both\n * workspace packages `@oh-my-opencode/omo-senpi` and `@oh-my-opencode/senpi-task`.\n *\n * This mirrors gates 1 and 2 of the beta `detectOmoLocalInstall` (beta/omo-local-update.ts)\n * but drops gate 3 (the `git rev-parse --show-toplevel` integrity check) so it stays sync and\n * cheap enough for footer rendering. The beta module's export policy forbids importing its\n * helpers into production core, so this isolated module is the footer's own detection.\n */\nconst OMO_SENPI_PLUGIN_PACKAGE = \"@code-yeongyu/omo-senpi\";\nconst OMO_SENPI_WORKSPACE_PACKAGE = \"@oh-my-opencode/omo-senpi\";\nconst SENPI_TASK_WORKSPACE_PACKAGE = \"@oh-my-opencode/senpi-task\";\n\nfunction homeDir(): string {\n\treturn process.env.HOME || homedir();\n}\n\nfunction readPackageName(packageJsonPath: string): string | undefined {\n\ttry {\n\t\tconst json = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as { name?: unknown };\n\t\tconst name = json.name;\n\t\treturn typeof name === \"string\" ? name : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function detectOmoNativeInstall(\n\tpackages: PackageSource[] | undefined,\n\tagentDir: string,\n\tenv: Record<string, string | undefined> = process.env,\n): boolean {\n\t// The omo launcher marks every senpi spawn it owns; omo-ai global installs load the plugin via\n\t// --extension, so no settings.packages entry ever exists for them and the env marker is the only\n\t// signal available at footer-render time.\n\tif (env.OMO_NATIVE === \"1\") {\n\t\treturn true;\n\t}\n\tif (!packages) {\n\t\treturn false;\n\t}\n\tfor (const entry of packages) {\n\t\tconst source = typeof entry === \"string\" ? entry : entry.source;\n\t\tif (!isLocalPath(source)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst pluginPath = resolvePath(source, agentDir, { homeDir: homeDir(), trim: true });\n\t\tif (readPackageName(join(pluginPath, \"package.json\")) !== OMO_SENPI_PLUGIN_PACKAGE) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst repoRoot = resolve(pluginPath, \"..\", \"..\", \"..\");\n\t\tconst omoSenpiPkg = join(repoRoot, \"packages\", \"omo-senpi\", \"package.json\");\n\t\tif (!existsSync(omoSenpiPkg) || readPackageName(omoSenpiPkg) !== OMO_SENPI_WORKSPACE_PACKAGE) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst senpiTaskPkg = join(repoRoot, \"packages\", \"senpi-task\", \"package.json\");\n\t\tif (!existsSync(senpiTaskPkg) || readPackageName(senpiTaskPkg) !== SENPI_TASK_WORKSPACE_PACKAGE) {\n\t\t\tcontinue;\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=omo-native-detect.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"omo-native-detect.test.d.ts","sourceRoot":"","sources":["../../src/core/omo-native-detect.test.ts"],"names":[],"mappings":""}
@@ -1,47 +0,0 @@
1
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, describe, expect, it } from "vitest";
5
- import { detectOmoNativeInstall } from "./omo-native-detect.js";
6
- // The omo-ai global install loads the plugin through the launcher's --extension flag, never through a
7
- // settings.packages entry, so detection must also honor the launcher-set OMO_NATIVE env marker or the
8
- // footer badge can never render for shipped installs.
9
- const roots = [];
10
- function omoRepoFixture() {
11
- const root = mkdtempSync(join(tmpdir(), "omo-detect-"));
12
- roots.push(root);
13
- const pluginPath = join(root, "packages", "omo-senpi", "plugin");
14
- mkdirSync(pluginPath, { recursive: true });
15
- writeFileSync(join(pluginPath, "package.json"), JSON.stringify({ name: "@code-yeongyu/omo-senpi" }));
16
- writeFileSync(join(root, "packages", "omo-senpi", "package.json"), JSON.stringify({ name: "@oh-my-opencode/omo-senpi" }));
17
- mkdirSync(join(root, "packages", "senpi-task"), { recursive: true });
18
- writeFileSync(join(root, "packages", "senpi-task", "package.json"), JSON.stringify({ name: "@oh-my-opencode/senpi-task" }));
19
- return { pluginPath };
20
- }
21
- afterEach(() => {
22
- for (const root of roots.splice(0))
23
- rmSync(root, { recursive: true, force: true });
24
- });
25
- describe("detectOmoNativeInstall", () => {
26
- describe("#given the launcher-set OMO_NATIVE env marker", () => {
27
- it("#when packages carry no omo entry #then detection still fires", () => {
28
- expect(detectOmoNativeInstall([], "/tmp/agent", { OMO_NATIVE: "1" })).toBe(true);
29
- });
30
- it("#when the marker holds any other value #then detection ignores it", () => {
31
- expect(detectOmoNativeInstall([], "/tmp/agent", { OMO_NATIVE: "0" })).toBe(false);
32
- expect(detectOmoNativeInstall([], "/tmp/agent", {})).toBe(false);
33
- });
34
- });
35
- describe("#given a settings.packages local-path omo plugin entry", () => {
36
- it("#when the repo gates all pass #then detection fires without the env marker", () => {
37
- const { pluginPath } = omoRepoFixture();
38
- expect(detectOmoNativeInstall([pluginPath], "/tmp/agent", {})).toBe(true);
39
- });
40
- });
41
- describe("#given neither the marker nor a matching package entry", () => {
42
- it("#when detection runs #then it stays false", () => {
43
- expect(detectOmoNativeInstall(undefined, "/tmp/agent", {})).toBe(false);
44
- });
45
- });
46
- });
47
- //# sourceMappingURL=omo-native-detect.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"omo-native-detect.test.js","sourceRoot":"","sources":["../../src/core/omo-native-detect.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport { detectOmoNativeInstall } from \"./omo-native-detect.ts\";\n\n// The omo-ai global install loads the plugin through the launcher's --extension flag, never through a\n// settings.packages entry, so detection must also honor the launcher-set OMO_NATIVE env marker or the\n// footer badge can never render for shipped installs.\n\nconst roots: string[] = [];\n\nfunction omoRepoFixture(): { pluginPath: string } {\n\tconst root = mkdtempSync(join(tmpdir(), \"omo-detect-\"));\n\troots.push(root);\n\tconst pluginPath = join(root, \"packages\", \"omo-senpi\", \"plugin\");\n\tmkdirSync(pluginPath, { recursive: true });\n\twriteFileSync(join(pluginPath, \"package.json\"), JSON.stringify({ name: \"@code-yeongyu/omo-senpi\" }));\n\twriteFileSync(\n\t\tjoin(root, \"packages\", \"omo-senpi\", \"package.json\"),\n\t\tJSON.stringify({ name: \"@oh-my-opencode/omo-senpi\" }),\n\t);\n\tmkdirSync(join(root, \"packages\", \"senpi-task\"), { recursive: true });\n\twriteFileSync(\n\t\tjoin(root, \"packages\", \"senpi-task\", \"package.json\"),\n\t\tJSON.stringify({ name: \"@oh-my-opencode/senpi-task\" }),\n\t);\n\treturn { pluginPath };\n}\n\nafterEach(() => {\n\tfor (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true });\n});\n\ndescribe(\"detectOmoNativeInstall\", () => {\n\tdescribe(\"#given the launcher-set OMO_NATIVE env marker\", () => {\n\t\tit(\"#when packages carry no omo entry #then detection still fires\", () => {\n\t\t\texpect(detectOmoNativeInstall([], \"/tmp/agent\", { OMO_NATIVE: \"1\" })).toBe(true);\n\t\t});\n\n\t\tit(\"#when the marker holds any other value #then detection ignores it\", () => {\n\t\t\texpect(detectOmoNativeInstall([], \"/tmp/agent\", { OMO_NATIVE: \"0\" })).toBe(false);\n\t\t\texpect(detectOmoNativeInstall([], \"/tmp/agent\", {})).toBe(false);\n\t\t});\n\t});\n\n\tdescribe(\"#given a settings.packages local-path omo plugin entry\", () => {\n\t\tit(\"#when the repo gates all pass #then detection fires without the env marker\", () => {\n\t\t\tconst { pluginPath } = omoRepoFixture();\n\t\t\texpect(detectOmoNativeInstall([pluginPath], \"/tmp/agent\", {})).toBe(true);\n\t\t});\n\t});\n\n\tdescribe(\"#given neither the marker nor a matching package entry\", () => {\n\t\tit(\"#when detection runs #then it stays false\", () => {\n\t\t\texpect(detectOmoNativeInstall(undefined, \"/tmp/agent\", {})).toBe(false);\n\t\t});\n\t});\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=footer-omo-native-badge.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"footer-omo-native-badge.test.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer-omo-native-badge.test.ts"],"names":[],"mappings":""}
@@ -1,52 +0,0 @@
1
- import { beforeAll, describe, expect, it } from "vitest";
2
- import { initTheme } from "../theme/theme.js";
3
- import { FooterComponent } from "./footer.js";
4
- // The badge is the only visible marker that a session is running the omo native distribution, so it is
5
- // pinned here at the render() boundary: emoji, wording, and bottom-left anchoring all matter to users.
6
- const OMO_NATIVE_BADGE = "(😺 OmO Native)";
7
- function footerData(isOmoNative) {
8
- return {
9
- getGitBranch: () => undefined,
10
- getExtensionStatuses: () => [],
11
- getAvailableProviderCount: () => 1,
12
- onBranchChange: () => () => { },
13
- isOmoNative: () => isOmoNative,
14
- };
15
- }
16
- function session() {
17
- return {
18
- state: { model: undefined, thinkingLevel: "off" },
19
- sessionManager: {
20
- getCwd: () => "/tmp/omo-footer-fixture",
21
- getSessionName: () => undefined,
22
- getUsageTotals: () => ({ cacheRead: 0, cacheWrite: 0, cost: 0, latestCacheHitRate: undefined }),
23
- },
24
- getContextUsage: () => undefined,
25
- isFastModeActive: () => false,
26
- modelRuntime: { isUsingOAuth: () => false },
27
- };
28
- }
29
- function renderFooter(isOmoNative) {
30
- return new FooterComponent(session(), footerData(isOmoNative)).render(200).join("\n");
31
- }
32
- describe("footer omo native badge", () => {
33
- beforeAll(() => initTheme("dark"));
34
- describe("#given a session running the omo native distribution", () => {
35
- it("#when the footer renders #then the cat badge appears", () => {
36
- expect(renderFooter(true)).toContain(OMO_NATIVE_BADGE);
37
- });
38
- it("#when the footer renders #then the badge leads the left anchor row", () => {
39
- const line = renderFooter(true);
40
- const badgeAt = line.indexOf(OMO_NATIVE_BADGE);
41
- const cwdAt = line.indexOf("omo-footer-fixture");
42
- expect(badgeAt).toBeGreaterThanOrEqual(0);
43
- expect(badgeAt).toBeLessThan(cwdAt);
44
- });
45
- });
46
- describe("#given a session that is not omo native", () => {
47
- it("#when the footer renders #then no badge appears", () => {
48
- expect(renderFooter(false)).not.toContain("OmO Native");
49
- });
50
- });
51
- });
52
- //# sourceMappingURL=footer-omo-native-badge.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"footer-omo-native-badge.test.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer-omo-native-badge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGzD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,uGAAuG;AACvG,uGAAuG;AACvG,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAE3C,SAAS,UAAU,CAAC,WAAoB;IACvC,OAAO;QACN,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS;QAC7B,oBAAoB,EAAE,GAAG,EAAE,CAAC,EAAE;QAC9B,yBAAyB,EAAE,GAAG,EAAE,CAAC,CAAC;QAClC,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QAC9B,WAAW,EAAE,GAAG,EAAE,CAAC,WAAW;KACW,CAAC;AAC5C,CAAC;AAED,SAAS,OAAO;IACf,OAAO;QACN,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE;QACjD,cAAc,EAAE;YACf,MAAM,EAAE,GAAG,EAAE,CAAC,yBAAyB;YACvC,cAAc,EAAE,GAAG,EAAE,CAAC,SAAS;YAC/B,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC;SAC/F;QACD,eAAe,EAAE,GAAG,EAAE,CAAC,SAAS;QAChC,gBAAgB,EAAE,GAAG,EAAE,CAAC,KAAK;QAC7B,YAAY,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE;KAChB,CAAC;AAC9B,CAAC;AAED,SAAS,YAAY,CAAC,WAAoB;IACzC,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvF,CAAC;AAED,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACxC,SAAS,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnC,QAAQ,CAAC,sDAAsD,EAAE,GAAG,EAAE;QACrE,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC/D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC7E,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACxD,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YAC1D,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import { beforeAll, describe, expect, it } from \"vitest\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport { initTheme } from \"../theme/theme.ts\";\nimport { FooterComponent } from \"./footer.ts\";\n\n// The badge is the only visible marker that a session is running the omo native distribution, so it is\n// pinned here at the render() boundary: emoji, wording, and bottom-left anchoring all matter to users.\nconst OMO_NATIVE_BADGE = \"(😺 OmO Native)\";\n\nfunction footerData(isOmoNative: boolean): ReadonlyFooterDataProvider {\n\treturn {\n\t\tgetGitBranch: () => undefined,\n\t\tgetExtensionStatuses: () => [],\n\t\tgetAvailableProviderCount: () => 1,\n\t\tonBranchChange: () => () => {},\n\t\tisOmoNative: () => isOmoNative,\n\t} as unknown as ReadonlyFooterDataProvider;\n}\n\nfunction session(): AgentSession {\n\treturn {\n\t\tstate: { model: undefined, thinkingLevel: \"off\" },\n\t\tsessionManager: {\n\t\t\tgetCwd: () => \"/tmp/omo-footer-fixture\",\n\t\t\tgetSessionName: () => undefined,\n\t\t\tgetUsageTotals: () => ({ cacheRead: 0, cacheWrite: 0, cost: 0, latestCacheHitRate: undefined }),\n\t\t},\n\t\tgetContextUsage: () => undefined,\n\t\tisFastModeActive: () => false,\n\t\tmodelRuntime: { isUsingOAuth: () => false },\n\t} as unknown as AgentSession;\n}\n\nfunction renderFooter(isOmoNative: boolean): string {\n\treturn new FooterComponent(session(), footerData(isOmoNative)).render(200).join(\"\\n\");\n}\n\ndescribe(\"footer omo native badge\", () => {\n\tbeforeAll(() => initTheme(\"dark\"));\n\n\tdescribe(\"#given a session running the omo native distribution\", () => {\n\t\tit(\"#when the footer renders #then the cat badge appears\", () => {\n\t\t\texpect(renderFooter(true)).toContain(OMO_NATIVE_BADGE);\n\t\t});\n\n\t\tit(\"#when the footer renders #then the badge leads the left anchor row\", () => {\n\t\t\tconst line = renderFooter(true);\n\t\t\tconst badgeAt = line.indexOf(OMO_NATIVE_BADGE);\n\t\t\tconst cwdAt = line.indexOf(\"omo-footer-fixture\");\n\t\t\texpect(badgeAt).toBeGreaterThanOrEqual(0);\n\t\t\texpect(badgeAt).toBeLessThan(cwdAt);\n\t\t});\n\t});\n\n\tdescribe(\"#given a session that is not omo native\", () => {\n\t\tit(\"#when the footer renders #then no badge appears\", () => {\n\t\t\texpect(renderFooter(false)).not.toContain(\"OmO Native\");\n\t\t});\n\t});\n});\n"]}