@sns-myagent/cli 0.3.4 → 0.3.6

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 (43) hide show
  1. package/package.json +6 -4
  2. package/scripts/smoke-tui.ts +110 -0
  3. package/src/cli/agents-cli.ts +1 -1
  4. package/src/cli/commands/init-xdg.ts +1 -1
  5. package/src/cli/profile-alias.ts +6 -6
  6. package/src/cli/ssh-cli.ts +7 -7
  7. package/src/commands/read.ts +1 -1
  8. package/src/config/settings-schema.ts +1 -1
  9. package/src/config/settings.ts +1 -1
  10. package/src/dap/session.ts +2 -2
  11. package/src/hindsight/bank.ts +1 -1
  12. package/src/hindsight/config.ts +1 -1
  13. package/src/internal-urls/docs-index.ts +1 -1
  14. package/src/internal-urls/index.ts +1 -1
  15. package/src/internal-urls/local-protocol.ts +2 -2
  16. package/src/internal-urls/router.ts +3 -3
  17. package/src/internal-urls/{omp-protocol.ts → snsagent-protocol.ts} +12 -12
  18. package/src/internal-urls/types.ts +1 -1
  19. package/src/modes/acp/acp-agent.ts +1 -1
  20. package/src/modes/components/welcome.ts +9 -7
  21. package/src/modes/internal-url-autocomplete.ts +1 -1
  22. package/src/modes/setup-wizard/scenes/splash.ts +1 -1
  23. package/src/task/omp-command.ts +1 -1
  24. package/src/tools/image-gen.ts +1 -1
  25. package/src/tools/read.ts +2 -2
  26. package/src/tools/report-tool-issue.ts +1 -1
  27. package/src/tools/search.ts +4 -4
  28. package/src/tui/chat-blocks.ts +117 -174
  29. package/src/tui/code-cell.ts +9 -9
  30. package/src/tui/command-palette.ts +62 -175
  31. package/src/tui/hyperlink.ts +1 -1
  32. package/src/tui/index.ts +1 -1
  33. package/src/tui/splash.ts +67 -111
  34. package/src/ui/banner.ts +1 -1
  35. package/src/ui/error-display.ts +67 -103
  36. package/src/ui/gradient.ts +15 -95
  37. package/src/ui/index.ts +3 -9
  38. package/src/ui/memory-toast.ts +51 -77
  39. package/src/ui/status-bar.ts +26 -47
  40. package/src/web/scrapers/crates-io.ts +1 -1
  41. package/src/web/scrapers/docs-rs.ts +1 -1
  42. package/src/web/scrapers/github.ts +1 -1
  43. package/src/web/search/providers/codex.ts +2 -2
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sns-myagent/cli",
4
- "version": "0.3.4",
5
- "description": "SNS-MyAgent \u2014 Pi Agent size, full features. BYOK coding agent CLI.",
4
+ "version": "0.3.6",
5
+ "description": "SNS-MyAgent \u2014 BYOK coding agent CLI. Multi-agent + Telegram + self-learning memory. ~120MB binary, zero forced cost.",
6
6
  "homepage": "https://github.com/Reihantt6/sns-myagent",
7
7
  "author": "Reihantt6",
8
8
  "contributors": [],
@@ -23,7 +23,9 @@
23
23
  "telegram",
24
24
  "multi-agent",
25
25
  "tui",
26
- "agent"
26
+ "agent",
27
+ "snsagent",
28
+ "sns-myagent"
27
29
  ],
28
30
  "main": "./src/index.ts",
29
31
  "types": "./dist/types/index.d.ts",
@@ -115,4 +117,4 @@
115
117
  "CHANGELOG.md",
116
118
  "dist/types"
117
119
  ]
118
- }
120
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Visual smoke test for the SNS-MyAgent TUI rebrand.
3
+ * Renders all 7 branded components and prints their ANSI output.
4
+ * Run: /root/.bun/bin/bun run scripts/smoke-tui.ts
5
+ *
6
+ * ANSI codes are EXPECTED — they render as colors in a real terminal.
7
+ * Don't strip them; the user sees them on their Mac.
8
+ */
9
+ import { renderSplash, renderInlineHeader } from "../src/tui/splash.js";
10
+ import { renderChatBlock, renderSessionHeader } from "../src/tui/chat-blocks.js";
11
+ import { CHAT_COMMANDS, renderCommandPalette } from "../src/tui/command-palette.js";
12
+ import { renderErrorDisplay } from "../src/ui/error-display.js";
13
+ import { renderMemoryToast, renderMemoryRecall } from "../src/ui/memory-toast.js";
14
+ import { renderStatusBar } from "../src/ui/status-bar.js";
15
+ import { accent, brand, subtle, inline } from "../src/ui/gradient.js";
16
+
17
+ // Stub stdout.columns so width-dependent renderers behave deterministically.
18
+ Object.defineProperty(process.stdout, "columns", { value: 100, configurable: true });
19
+
20
+ const sessionStart = Date.now() - 10_000; // 10s ago
21
+
22
+ function section(title: string) {
23
+ console.log(`\n\x1b[1m\x1b[36m─── ${title} ───\x1b[0m`);
24
+ }
25
+
26
+ section("1. SPLASH");
27
+ console.log(
28
+ renderSplash({
29
+ model: "gpt-4o-mini",
30
+ provider: "openai",
31
+ cwd: "/root/sns-myagent",
32
+ platform: "darwin-arm64",
33
+ nodeVersion: "v22",
34
+ }),
35
+ );
36
+
37
+ section("1b. INLINE HEADER");
38
+ console.log(
39
+ renderInlineHeader({ model: "gpt-4o-mini", provider: "openai" }),
40
+ );
41
+
42
+ section("2. CHAT BLOCKS");
43
+ console.log(
44
+ renderChatBlock({ role: "user", content: "halo, design barunya udah jadi?", meta: "10:23" }),
45
+ );
46
+ console.log();
47
+ console.log(
48
+ renderChatBlock({
49
+ role: "assistant",
50
+ content: "Sudah! Aku SnsAgent — premium gradient TUI dengan splash, chat blocks, status bar, command palette, error display, memory toast. Semua branded SNS-MyAgent.",
51
+ meta: "10:23",
52
+ }),
53
+ );
54
+ console.log();
55
+ console.log(
56
+ renderChatBlock({
57
+ role: "tool",
58
+ label: "TOOL LS",
59
+ content: "$ ls -la src/tui\ntotal 12\ndrwxr-xr-x . src/tui/",
60
+ meta: "12 files",
61
+ }),
62
+ );
63
+
64
+ section("3. SESSION HEADER");
65
+ console.log(renderSessionHeader("openai/gpt-4o-mini", "0.3.5"));
66
+
67
+ section("4. COMMAND PALETTE");
68
+ console.log(
69
+ renderCommandPalette({ commands: CHAT_COMMANDS, query: "mod", highlighted: 3 }),
70
+ );
71
+
72
+ section("5. ERROR DISPLAY");
73
+ console.log(
74
+ renderErrorDisplay({
75
+ severity: "error",
76
+ title: "API key not configured",
77
+ message: "OPENAI_API_KEY is missing. Set it in .env or via /init.",
78
+ code: "AUTH_001",
79
+ suggestion: "Run `snsagent init` to create .sns-myagent/config.json with your key.",
80
+ }),
81
+ );
82
+
83
+ section("6. MEMORY TOAST");
84
+ console.log(
85
+ renderMemoryToast({
86
+ type: "recall",
87
+ message: "preferences: dark theme",
88
+ relevance: 0.85,
89
+ }),
90
+ );
91
+ console.log(
92
+ renderMemoryRecall("dark theme", "user prefers dark theme for terminal UI", 0.92),
93
+ );
94
+
95
+ section("8. STATUS BAR");
96
+ renderStatusBar({
97
+ model: "gpt-4o-mini",
98
+ tokensUsed: 12345,
99
+ sessionStarted: Date.now() - 10_000,
100
+ memoryHits: 3,
101
+ });
102
+ console.log(); // newline after status bar (renderStatusBar writes to stdout directly)
103
+
104
+ section("9. GRADIENT HELPERS (minimal)");
105
+ console.log("brand: ", brand("SnsAgent — coding agent CLI"));
106
+ console.log("accent: ", accent("accent cyan"));
107
+ console.log("subtle: ", subtle("dim text"));
108
+ console.log("inline: ", inline("file.ts:42"));
109
+
110
+ console.log("\n\x1b[1m\x1b[32m✓ All 7 TUI components rendered without crashing.\x1b[0m");
@@ -46,7 +46,7 @@ function resolveTargetDir(flags: AgentsCommandArgs["flags"]): string {
46
46
  }
47
47
 
48
48
  if (flags.project) {
49
- return path.resolve(getProjectDir(), ".omp", "agents");
49
+ return path.resolve(getProjectDir(), ".sns-myagent", "agents");
50
50
  }
51
51
 
52
52
  return path.join(getAgentDir(), "agents");
@@ -2,7 +2,7 @@ import * as fs from "node:fs/promises";
2
2
  import * as os from "node:os";
3
3
  import * as path from "node:path";
4
4
 
5
- const APP_NAME = "omp";
5
+ const APP_NAME = "snsagent";
6
6
 
7
7
  export async function initXdg(): Promise<void> {
8
8
  if (process.platform !== "linux" && process.platform !== "darwin") {
@@ -20,10 +20,10 @@ export interface ProfileAliasCommand {
20
20
  }
21
21
 
22
22
  const DEFAULT_ALIAS_COMMAND: ProfileAliasCommand = {
23
- display: "omp",
24
- posix: "omp",
25
- fish: "omp",
26
- powerShell: "omp",
23
+ display: "snsagent",
24
+ posix: "snsagent",
25
+ fish: "snsagent",
26
+ powerShell: "snsagent",
27
27
  };
28
28
 
29
29
  export interface ProfileAliasInstallOptions {
@@ -147,8 +147,8 @@ function validateAliasName(aliasName: string, shell: ProfileAliasShell): string
147
147
  if (!ALIAS_NAME_RE.test(normalized)) {
148
148
  throw new Error(`Invalid alias "${aliasName}". Alias names must match ${ALIAS_NAME_RE.source}.`);
149
149
  }
150
- if (normalized.toLowerCase() === "omp") {
151
- throw new Error('Invalid alias "omp". Refusing to shadow the base omp command.');
150
+ if (normalized.toLowerCase() === "snsagent") {
151
+ throw new Error('Invalid alias "snsagent". Refusing to shadow the base snsagent command.');
152
152
  }
153
153
  if (getReservedAliasNames(shell).has(normalized.toLowerCase())) {
154
154
  throw new Error(`Invalid alias "${aliasName}". Refusing to create a ${shell} reserved word.`);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * SSH CLI command handlers.
3
3
  *
4
- * Handles `omp ssh <command>` subcommands for SSH host configuration management.
4
+ * Handles `snsagent ssh <command>` subcommands for SSH host configuration management.
5
5
  */
6
6
 
7
7
  import { getSSHConfigPath } from "@oh-my-pi/pi-utils";
@@ -60,7 +60,7 @@ async function handleAdd(cmd: SSHCommandArgs): Promise<void> {
60
60
  if (!name) {
61
61
  process.stdout.write(chalk.red("Error: Host name required\n"));
62
62
  process.stdout.write(
63
- chalk.dim("Usage: omp ssh add <name> --host <address> [--user <user>] [--port <port>] [--key <path>]\n"),
63
+ chalk.dim("Usage: snsagent ssh add <name> --host <address> [--user <user>] [--port <port>] [--key <path>]\n"),
64
64
  );
65
65
  process.exitCode = 1;
66
66
  return;
@@ -69,7 +69,7 @@ async function handleAdd(cmd: SSHCommandArgs): Promise<void> {
69
69
  const host = cmd.flags.host;
70
70
  if (!host) {
71
71
  process.stdout.write(chalk.red("Error: --host is required\n"));
72
- process.stdout.write(chalk.dim("Usage: omp ssh add <name> --host <address>\n"));
72
+ process.stdout.write(chalk.dim("Usage: snsagent ssh add <name> --host <address>\n"));
73
73
  process.exitCode = 1;
74
74
  return;
75
75
  }
@@ -107,7 +107,7 @@ async function handleRemove(cmd: SSHCommandArgs): Promise<void> {
107
107
  const name = cmd.args[0];
108
108
  if (!name) {
109
109
  process.stdout.write(chalk.red("Error: Host name required\n"));
110
- process.stdout.write(chalk.dim("Usage: omp ssh remove <name> [--scope project|user]\n"));
110
+ process.stdout.write(chalk.dim("Usage: snsagent ssh remove <name> [--scope project|user]\n"));
111
111
  process.exitCode = 1;
112
112
  return;
113
113
  }
@@ -144,12 +144,12 @@ async function handleList(cmd: SSHCommandArgs): Promise<void> {
144
144
 
145
145
  if (!hasProject && !hasUser) {
146
146
  process.stdout.write(chalk.dim("No SSH hosts configured\n"));
147
- process.stdout.write(chalk.dim("Add one with: omp ssh add <name> --host <address>\n"));
147
+ process.stdout.write(chalk.dim("Add one with: snsagent ssh add <name> --host <address>\n"));
148
148
  return;
149
149
  }
150
150
 
151
151
  if (hasProject) {
152
- process.stdout.write(chalk.bold("Project SSH Hosts (.omp/ssh.json):\n"));
152
+ process.stdout.write(chalk.bold("Project SSH Hosts (.sns-myagent/ssh.json):\n"));
153
153
  printHosts(projectHosts);
154
154
  }
155
155
 
@@ -158,7 +158,7 @@ async function handleList(cmd: SSHCommandArgs): Promise<void> {
158
158
  }
159
159
 
160
160
  if (hasUser) {
161
- process.stdout.write(chalk.bold("User SSH Hosts (~/.omp/agent/ssh.json):\n"));
161
+ process.stdout.write(chalk.bold("User SSH Hosts (~/.sns-myagent/agent/ssh.json):\n"));
162
162
  printHosts(userHosts);
163
163
  }
164
164
  }
@@ -21,7 +21,7 @@ export default class Read extends Command {
21
21
  "omp read src/foo.ts:50-100",
22
22
  "omp read src/foo.ts:raw",
23
23
  "omp read https://example.com",
24
- "omp read omp://",
24
+ "omp read snsagent://",
25
25
  "omp read issue://123",
26
26
  "omp read path/to/archive.zip:dir/file.ts",
27
27
  "omp read path/to/db.sqlite:users:42",
@@ -2529,7 +2529,7 @@ export const SETTINGS_SCHEMA = {
2529
2529
  },
2530
2530
  "hindsight.retainEveryNTurns": { type: "number", default: 3 },
2531
2531
  "hindsight.retainOverlapTurns": { type: "number", default: 2 },
2532
- "hindsight.retainContext": { type: "string", default: "omp" },
2532
+ "hindsight.retainContext": { type: "string", default: "snsagent" },
2533
2533
 
2534
2534
  "hindsight.recallBudget": {
2535
2535
  type: "enum",
@@ -901,7 +901,7 @@ export class Settings {
901
901
  !("bankId" in hindsightObj) &&
902
902
  typeof agentName === "string" &&
903
903
  agentName.trim().length > 0 &&
904
- agentName !== "omp"
904
+ agentName !== "snsagent"
905
905
  ) {
906
906
  hindsightObj.bankId = agentName;
907
907
  }
@@ -1153,8 +1153,8 @@ export class DapSessionManager {
1153
1153
 
1154
1154
  #buildInitializeArguments(adapter: DapResolvedAdapter): DapInitializeArguments {
1155
1155
  return {
1156
- clientID: "omp",
1157
- clientName: "Oh My Pi",
1156
+ clientID: "snsagent",
1157
+ clientName: "SNS-MyAgent",
1158
1158
  adapterID: adapter.name,
1159
1159
  locale: "en-US",
1160
1160
  linesStartAt1: true,
@@ -26,7 +26,7 @@ import * as git from "../utils/git";
26
26
  import type { HindsightApi } from "./client";
27
27
  import type { HindsightConfig } from "./config";
28
28
 
29
- const DEFAULT_BANK_NAME = "omp";
29
+ const DEFAULT_BANK_NAME = "snsagent";
30
30
  const PROJECT_TAG_PREFIX = "project:";
31
31
  const UNKNOWN_PROJECT = "unknown";
32
32
  const MISSION_SET_CAP = 10_000;
@@ -147,7 +147,7 @@ export function loadHindsightConfig(settings: Settings, env: NodeJS.ProcessEnv =
147
147
  retainMode: retainModeEnv ?? settingsRetainMode ?? "full-session",
148
148
  retainEveryNTurns: retainEveryNTurnsEnv ?? settings.get("hindsight.retainEveryNTurns"),
149
149
  retainOverlapTurns: settings.get("hindsight.retainOverlapTurns"),
150
- retainContext: settings.get("hindsight.retainContext") ?? "omp",
150
+ retainContext: settings.get("hindsight.retainContext") ?? "snsagent",
151
151
 
152
152
  recallBudget: recallBudgetEnv ?? settingsRecallBudget ?? "mid",
153
153
  recallMaxTokens: recallMaxTokensEnv ?? settings.get("hindsight.recallMaxTokens"),
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Harness documentation index for the `omp://` protocol.
2
+ * Harness documentation index for the `snsagent://` protocol.
3
3
  *
4
4
  * Compiled binaries and the prepacked npm bundle inline a compressed index from
5
5
  * `docs-index.generated.txt` (populated by `scripts/generate-docs-index.ts
@@ -16,7 +16,7 @@ export * from "./json-query";
16
16
  export * from "./local-protocol";
17
17
  export * from "./mcp-protocol";
18
18
  export * from "./memory-protocol";
19
- export * from "./omp-protocol";
19
+ export * from "./snsagent-protocol";
20
20
  export * from "./parse";
21
21
  export * from "./router";
22
22
  export * from "./rule-protocol";
@@ -39,7 +39,7 @@ function shortLocalRoot(options: LocalProtocolOptions): string {
39
39
  // Derive the short root from the stable session id, never the artifact path,
40
40
  // so `SessionManager.moveTo()` and the resume-after-move flow keep finding
41
41
  // the same `local://` directory the session wrote pre-move.
42
- return path.join(os.tmpdir(), "omp-local", safeSessionId(options));
42
+ return path.join(os.tmpdir(), "snsagent-local", safeSessionId(options));
43
43
  }
44
44
 
45
45
  function getContentType(filePath: string): InternalResource["contentType"] {
@@ -134,7 +134,7 @@ export function resolveLocalRoot(options: LocalProtocolOptions, platform: NodeJS
134
134
  return candidate;
135
135
  }
136
136
 
137
- return path.join(os.tmpdir(), "omp-local", safeSessionId(options));
137
+ return path.join(os.tmpdir(), "snsagent-local", safeSessionId(options));
138
138
  }
139
139
 
140
140
  /** Resolve a local:// URL to an on-disk path under the active session's local root. */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Internal URL router for internal protocols (`agent://`, `artifact://`, `history://`, `issue://`, `local://`, `mcp://`, `memory://`, `omp://`, `pr://`, `rule://`, `skill://`, and `vault://`).
2
+ * Internal URL router for internal protocols (`agent://`, `artifact://`, `history://`, `issue://`, `local://`, `mcp://`, `memory://`, `snsagent://`, `pr://`, `rule://`, `skill://`, and `vault://`).
3
3
  *
4
4
  * One process-global router with one handler per scheme. Access via
5
5
  * `InternalUrlRouter.instance()`. Handlers are stateless; per-session and
@@ -12,7 +12,7 @@ import { IssueProtocolHandler, PrProtocolHandler } from "./issue-pr-protocol";
12
12
  import { LocalProtocolHandler } from "./local-protocol";
13
13
  import { McpProtocolHandler } from "./mcp-protocol";
14
14
  import { MemoryProtocolHandler } from "./memory-protocol";
15
- import { OmpProtocolHandler } from "./omp-protocol";
15
+ import { SnsAgentProtocolHandler } from "./snsagent-protocol";
16
16
  import { parseInternalUrl } from "./parse";
17
17
  import { RuleProtocolHandler } from "./rule-protocol";
18
18
  import { SkillProtocolHandler } from "./skill-protocol";
@@ -25,7 +25,7 @@ export class InternalUrlRouter {
25
25
  #handlers = new Map<string, ProtocolHandler>();
26
26
 
27
27
  constructor() {
28
- this.register(new OmpProtocolHandler());
28
+ this.register(new SnsAgentProtocolHandler());
29
29
  this.register(new AgentProtocolHandler());
30
30
  this.register(new ArtifactProtocolHandler());
31
31
  this.register(new MemoryProtocolHandler());
@@ -1,23 +1,23 @@
1
1
  /**
2
- * Protocol handler for omp:// URLs.
2
+ * Protocol handler for snsagent:// URLs.
3
3
  *
4
4
  * Serves statically embedded documentation files bundled at build time.
5
5
  *
6
6
  * URL forms:
7
- * - omp:// - Lists all available documentation files
8
- * - omp://<file>.md - Reads a specific documentation file
7
+ * - snsagent:// - Lists all available documentation files
8
+ * - snsagent://<file>.md - Reads a specific documentation file
9
9
  */
10
10
  import * as path from "node:path";
11
11
  import { getDocFilenames, getEmbeddedDoc } from "./docs-index";
12
12
  import type { InternalResource, InternalUrl, ProtocolHandler, UrlCompletion } from "./types";
13
13
 
14
14
  /**
15
- * Handler for omp:// URLs.
15
+ * Handler for snsagent:// URLs.
16
16
  *
17
17
  * Resolves documentation file names to their content, or lists available docs.
18
18
  */
19
- export class OmpProtocolHandler implements ProtocolHandler {
20
- readonly scheme = "omp";
19
+ export class SnsAgentProtocolHandler implements ProtocolHandler {
20
+ readonly scheme = "snsagent";
21
21
  readonly immutable = true;
22
22
 
23
23
  async resolve(url: InternalUrl): Promise<InternalResource> {
@@ -34,7 +34,7 @@ export class OmpProtocolHandler implements ProtocolHandler {
34
34
  }
35
35
 
36
36
  async complete(): Promise<UrlCompletion[]> {
37
- return getDocFilenames().map(value => ({ value }));
37
+ return getDocFilenames().map((value) => ({ value }));
38
38
  }
39
39
 
40
40
  async #listDocs(url: InternalUrl): Promise<InternalResource> {
@@ -43,7 +43,7 @@ export class OmpProtocolHandler implements ProtocolHandler {
43
43
  throw new Error("No documentation files found");
44
44
  }
45
45
 
46
- const listing = filenames.map(f => `- [${f}](omp://${f})`).join("\n");
46
+ const listing = filenames.map((f) => `- [${f}](snsagent://${f})`).join("\n");
47
47
  const content = `# Documentation\n\n${filenames.length} files available:\n\n${listing}\n`;
48
48
 
49
49
  return {
@@ -57,12 +57,12 @@ export class OmpProtocolHandler implements ProtocolHandler {
57
57
  async #readDoc(filename: string, url: InternalUrl): Promise<InternalResource> {
58
58
  // Validate: no traversal, no absolute paths
59
59
  if (path.isAbsolute(filename)) {
60
- throw new Error("Absolute paths are not allowed in omp:// URLs");
60
+ throw new Error("Absolute paths are not allowed in snsagent:// URLs");
61
61
  }
62
62
 
63
63
  const normalized = path.posix.normalize(filename.replaceAll("\\", "/"));
64
64
  if (normalized === ".." || normalized.startsWith("../") || normalized.includes("/../")) {
65
- throw new Error("Path traversal (..) is not allowed in omp:// URLs");
65
+ throw new Error("Path traversal (..) is not allowed in snsagent:// URLs");
66
66
  }
67
67
 
68
68
  const docPath =
@@ -75,12 +75,12 @@ export class OmpProtocolHandler implements ProtocolHandler {
75
75
  if (content === undefined) {
76
76
  const lookup = docPath.replace(/\.md$/, "");
77
77
  const suggestions = getDocFilenames()
78
- .filter(f => f.includes(lookup) || lookup.includes(f.replace(/\.md$/, "")))
78
+ .filter((f) => f.includes(lookup) || lookup.includes(f.replace(/\.md$/, "")))
79
79
  .slice(0, 5);
80
80
  const suffix =
81
81
  suggestions.length > 0
82
82
  ? `\nDid you mean: ${suggestions.join(", ")}`
83
- : "\nUse omp:// to list available files.";
83
+ : "\nUse snsagent:// to list available files.";
84
84
  throw new Error(`Documentation file not found: ${filename}${suffix}`);
85
85
  }
86
86
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Types for the internal URL routing system.
3
3
  *
4
- * Internal URLs (`agent://`, `artifact://`, `history://`, `issue://`, `local://`, `mcp://`, `memory://`, `omp://`, `pr://`, `rule://`, `skill://`, and `vault://`) are resolved by tools like read,
4
+ * Internal URLs (`agent://`, `artifact://`, `history://`, `issue://`, `local://`, `mcp://`, `memory://`, `snsagent://`, `pr://`, `rule://`, `skill://`, and `vault://`) are resolved by tools like read,
5
5
  * providing access to agent outputs and server resources without exposing filesystem paths.
6
6
  */
7
7
 
@@ -479,7 +479,7 @@ export class AcpAgent implements Agent {
479
479
  protocolVersion: PROTOCOL_VERSION,
480
480
  agentInfo: {
481
481
  name: "sns-myagent",
482
- title: "Oh My Pi",
482
+ title: "SNS-MyAgent",
483
483
  version: VERSION,
484
484
  },
485
485
  authMethods,
@@ -7,10 +7,12 @@ import {
7
7
  visibleWidth,
8
8
  wrapTextWithAnsi,
9
9
  } from "@oh-my-pi/pi-tui";
10
- import { APP_NAME } from "@oh-my-pi/pi-utils";
11
10
  import { theme } from "../../modes/theme/theme";
12
11
  import tipsText from "./tips.txt" with { type: "text" };
13
12
 
13
+ // Local override — upstream APP_NAME still reports "omp"/"pi-utils" identity.
14
+ const APP_NAME = "SnsAgent";
15
+
14
16
  /** Tips embedded at build time, one per line; blanks dropped. */
15
17
  const TIPS: readonly string[] = tipsText
16
18
  .split("\n")
@@ -454,12 +456,12 @@ export class WelcomeComponent implements Component {
454
456
  }
455
457
 
456
458
  export const PI_LOGO = [
457
- "███╗ ██╗███████╗██╗ ██╗██╗ ██╗███████╗",
458
- "████╗ ██║██╔════╝╚██╗██╔╝██║ ██║██╔════╝",
459
- "██╔██╗ ██║█████╗ ╚███╔╝ ██║ ██║███████╗",
460
- "██║╚██╗██║██╔══╝ ██╔██╗ ██║ ██║╚════██║",
461
- "██║ ╚████║███████╗██╔╝ ╚██╗╚██████╔╝███████║",
462
- "╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝",
459
+ "██████╗███╗ ██╗███████╗ █████╗ ██████╗ ███████╗███╗ ██╗████████╗",
460
+ "██╔════╝████╗ ██║██╔════╝██╔══██╗██╔═══██╗██╔════╝████╗ ██║╚══██╔══╝",
461
+ "██████╗ ██╔██╗ ██║███████╗███████║██║ ██║█████╗ ██╔██╗ ██║ ██║ ",
462
+ "╚════██║██║╚██╗██║╚════██║██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ",
463
+ "██████║██║ ╚████║███████║██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ",
464
+ "╚═════╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ",
463
465
  ];
464
466
 
465
467
  /** Multi-stop palette for the diagonal gradient. */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Autocomplete for internal-url schemes (skill://, rule://, omp://, local://,
2
+ * Autocomplete for internal-url schemes (skill://, rule://, snsagent://, local://,
3
3
  * memory://, agent://, artifact://) while composing a prompt.
4
4
  *
5
5
  * Detection here MUST stay in sync with the generic URL-scheme trigger in the
@@ -189,7 +189,7 @@ export function renderSetupSplash(width: number, height: number, elapsedMs: numb
189
189
  /** Centered fallback for windows too small to hold the full scene. */
190
190
  function renderCompactSplash(width: number, height: number, phase: number, shine: ShineConfig): string[] {
191
191
  const art = height >= 14 ? LARGE_LOGO : PI_LOGO;
192
- const content = [...gradientLogo(art, phase, shine), "", theme.bold("S n s C o d e r")];
192
+ const content = [...gradientLogo(art, phase, shine), "", theme.bold("S n s A g e n t")];
193
193
  const start = Math.max(0, Math.floor((height - content.length) / 2));
194
194
  const lines: string[] = [];
195
195
  for (let y = 0; y < height; y++) {
@@ -8,7 +8,7 @@ interface OmpCommand {
8
8
  shell: boolean;
9
9
  }
10
10
 
11
- const DEFAULT_CMD = process.platform === "win32" ? "omp.cmd" : "omp";
11
+ const DEFAULT_CMD = process.platform === "win32" ? "snsagent.cmd" : "snsagent";
12
12
  const DEFAULT_SHELL = process.platform === "win32";
13
13
 
14
14
  export function resolveOmpCommand(): OmpCommand {
@@ -837,7 +837,7 @@ function buildOpenAIImageHeaders(model: Model, apiKey: string, sessionId: string
837
837
  headers.set(OPENAI_HEADERS.ACCOUNT_ID, accountId);
838
838
  headers.set(OPENAI_HEADERS.BETA, OPENAI_HEADER_VALUES.BETA_RESPONSES);
839
839
  headers.set(OPENAI_HEADERS.ORIGINATOR, OPENAI_HEADER_VALUES.ORIGINATOR_CODEX);
840
- headers.set("User-Agent", `pi/${packageJson.version} (${os.platform()} ${os.release()}; ${os.arch()})`);
840
+ headers.set("User-Agent", `snsagent/${packageJson.version} (${os.platform()} ${os.release()}; ${os.arch()})`);
841
841
  if (sessionId) {
842
842
  headers.set(OPENAI_HEADERS.CONVERSATION_ID, sessionId);
843
843
  headers.set(OPENAI_HEADERS.SESSION_ID, sessionId);
package/src/tools/read.ts CHANGED
@@ -690,7 +690,7 @@ function splitPdfImageMemberReadPath(readPath: string): { pdfPath: string; membe
690
690
 
691
691
  const readSchema = type({
692
692
  path: type("string").describe(
693
- 'Local path, internal URI (e.g. "omp://", "issue://123", "pr://123"), or URL; append :<sel> for line ranges or raw mode (e.g. "src/foo.ts:50-100")',
693
+ 'Local path, internal URI (e.g. "snsagent://", "issue://123", "pr://123"), or URL; append :<sel> for line ranges or raw mode (e.g. "src/foo.ts:50-100")',
694
694
  ),
695
695
  });
696
696
 
@@ -1998,7 +1998,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1998
1998
  return executeReadUrl(this.session, { path: parsedUrlTarget.path, raw: parsedUrlTarget.raw }, signal);
1999
1999
  }
2000
2000
 
2001
- // Handle internal URLs (agent://, artifact://, memory://, skill://, rule://, local://, mcp://, omp://, issue://, pr://).
2001
+ // Handle internal URLs (agent://, artifact://, memory://, skill://, rule://, local://, mcp://, snsagent://, issue://, pr://).
2002
2002
  // Use the internal-URL-aware splitter so malformed selectors are peeled
2003
2003
  // off the URL and surfaced via parseSel rather than confusing handlers.
2004
2004
  const internalRouter = InternalUrlRouter.instance();
@@ -353,7 +353,7 @@ async function performFlush(db: Database, config: PushConfig, options: FlushOpti
353
353
  if (rows.length === 0) return { pushed: totalPushed, ok: true };
354
354
 
355
355
  const body = JSON.stringify({
356
- agent: { name: "omp", version: VERSION },
356
+ agent: { name: "snsagent", version: VERSION },
357
357
  installId: getInstallId(),
358
358
  // Coarse host fingerprint for triage — `darwin`/`linux`/`win32` +
359
359
  // `arm64`/`x64`. Useful for "is this bug arch-specific?" without
@@ -242,7 +242,7 @@ async function resolveArchiveSearchPaths(
242
242
  }
243
243
 
244
244
  if (!tempDir) {
245
- tempDir = await mkdtemp(path.join(tmpdir(), "omp-search-archive-"));
245
+ tempDir = await mkdtemp(path.join(tmpdir(), "snsagent-search-archive-"));
246
246
  }
247
247
  // Per-entry filename keeps the scratch path unique even when two selectors
248
248
  // resolve to members with the same basename.
@@ -292,7 +292,7 @@ interface IndexedContentLines {
292
292
  starts: number[];
293
293
  }
294
294
 
295
- const OMP_ROOT_URL_RE = /^omp:\/\/(?:\/?|docs\/?)$/i;
295
+ const OMP_ROOT_URL_RE = /^snsagent:\/\/(?:\/?|docs\/?)$/i;
296
296
 
297
297
  function normalizeSearchLine(line: string): string {
298
298
  return line.endsWith("\r") ? line.slice(0, -1) : line;
@@ -551,14 +551,14 @@ async function expandVirtualInternalResource(
551
551
  ranges: readonly LineRange[] | undefined,
552
552
  ): Promise<VirtualSearchResource[]> {
553
553
  if (OMP_ROOT_URL_RE.test(rawPath)) {
554
- const completions = await internalRouter.complete("omp", "");
554
+ const completions = await internalRouter.complete("snsagent", "");
555
555
  if (completions && completions.length > 0) {
556
556
  const resources: VirtualSearchResource[] = [];
557
557
  const seen = new Set<string>();
558
558
  for (const completion of completions) {
559
559
  if (seen.has(completion.value)) continue;
560
560
  seen.add(completion.value);
561
- const docUrl = `omp://${completion.value}`;
561
+ const docUrl = `snsagent://${completion.value}`;
562
562
  const doc = await internalRouter.resolve(docUrl, context);
563
563
  if (!doc.sourcePath) {
564
564
  resources.push({ path: docUrl, content: doc.content, ranges });