From 2a652458ab59b8d1eb9bf349e45bc0bda7dcff99 Mon Sep 17 00:00:00 2001
From: Boris Tane
Date: Sat, 10 Oct 2026 07:36:13 -0700
Subject: [PATCH] fix: remove repo grep, read and tree
The Polylane API no longer serves the codefiles search, contents and tree
routes these commands called (coreplanelabs/nominal#4531), so they returned
404. Agents read code in their own clone; `repo find` and the GitHub read
tools under `tools run` cover finding and fetching it.
Co-Authored-By: Claude Opus 5.5
---
README.md | 2 +-
skill/SKILL.md | 7 ++---
src/commands/repo/grep.ts | 63 --------------------------------------
src/commands/repo/index.ts | 6 ----
src/commands/repo/read.ts | 37 ----------------------
src/commands/repo/tree.ts | 40 ------------------------
src/registry.ts | 4 +--
7 files changed, 6 insertions(+), 153 deletions(-)
delete mode 100644 src/commands/repo/grep.ts
delete mode 100644 src/commands/repo/read.ts
delete mode 100644 src/commands/repo/tree.ts
diff --git a/README.md b/README.md
index a034bcc..af8c448 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# polylane
Agent-focused CLI for the Polylane platform.
-Investigate production issues, explore cloud infrastructure, search code, and drive threads — from any agent or terminal.
+Investigate production issues, explore cloud infrastructure, find the repositories behind a service, and drive threads — from any agent or terminal.
Your coding agent writes the code. It can't see production. Polylane is the missing sense.
diff --git a/skill/SKILL.md b/skill/SKILL.md
index 85cbc50..f504562 100644
--- a/skill/SKILL.md
+++ b/skill/SKILL.md
@@ -1,6 +1,6 @@
---
name: polylane-cli
-description: Use `polylane` to investigate production issues, explore cloud infrastructure (logs / metrics / dependency graphs), search code, save memories, connect observability tools and cloud accounts, and drive threads with the Polylane agent. Use when the user wants to debug a production issue, look up a service, search their codebase, manage integrations, connect a cloud provider, or talk to the Polylane agent from the terminal.
+description: Use `polylane` to investigate production issues, explore cloud infrastructure (logs / metrics / dependency graphs), find the repositories that deploy a service, save memories, connect observability tools and cloud accounts, and drive threads with the Polylane agent. Use when the user wants to debug a production issue, look up a service, find a repository, manage integrations, connect a cloud provider, or talk to the Polylane agent from the terminal.
---
# Polylane CLI — Agent Skill Guide
@@ -184,9 +184,8 @@ polylane service logs --since 1h --grep error
polylane service metrics --metric --since 1h
polylane service graph --direction both --depth 1
-# Search code
+# Find the repository, then search it in a local clone
polylane repo find ""
-polylane repo grep ""
# Save what you learned
polylane memory save ""
@@ -194,7 +193,7 @@ polylane memory save ""
### Running agent tools directly
-Polylane exposes the same tools its own agent uses — observability queries across every connected provider, infra-graph traversal, code and change-record search, deployments, audit logs. Discover them, then run them, without opening a thread.
+Polylane exposes the same tools its own agent uses — observability queries across every connected provider, infra-graph traversal, GitHub file and code reads, change-record search, deployments, audit logs. Discover them, then run them, without opening a thread.
```bash
# Discover tools available to this workspace (filtered to your credential's scopes)
diff --git a/src/commands/repo/grep.ts b/src/commands/repo/grep.ts
deleted file mode 100644
index d25e4ab..0000000
--- a/src/commands/repo/grep.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import type { Command } from '../../command';
-import type { Config } from '../../config/schema';
-import { PolylaneAPI } from '../../generated/client';
-import { formatList } from '../../output/formatter';
-import { requireWorkspace, requirePositional, getAllPositional, getArgNumber } from '../helpers';
-import { resolveRepoId } from './id';
-
-export const repoGrepCommand: Command = {
- name: 'repo grep',
- description: 'Semantic code search within a repository',
- operationId: 'repositories.codefiles.search',
- positional: [
- { name: 'repo-id', description: 'Repo ID, owner/name, or short name' },
- { name: 'prompt', description: 'Search query', variadic: true },
- ],
- options: [{ flag: '--limit ', description: 'Max chunks (default 20)', type: 'number' }],
- examples: ['polylane repo grep cli "http request handler"'],
- async execute(config: Config, _flags, args: Record): Promise {
- const workspaceId = await requireWorkspace(config);
- const repoRaw = requirePositional(args, 0, 'repo-id');
- const promptParts = getAllPositional(args).slice(1);
- if (promptParts.length === 0) {
- throw new Error('Missing ');
- }
- const prompt = promptParts.join(' ');
- const limit = getArgNumber(args, 'limit') ?? 20;
-
- const repoId = await resolveRepoId(config, repoRaw, workspaceId);
- const api = new PolylaneAPI(config);
- const chunks = await api.repositoriesCodefilesSearch(
- { workspaceId, id: repoId, prompt },
- { perPage: limit }
- );
-
- const items = chunks.map((c) => ({
- path: c.path,
- symbol: c.symbol ?? '',
- language: c.language,
- range: `${c.start}-${c.end}`,
- snippet: truncate(c.text, 200),
- }));
-
- formatList(
- config,
- { items, count: items.length },
- {
- headers: ['Path', 'Symbol', 'Lang', 'Range', 'Snippet'],
- rows: (item) => [
- String(item.path ?? ''),
- String(item.symbol ?? ''),
- String(item.language ?? ''),
- String(item.range ?? ''),
- String(item.snippet ?? ''),
- ],
- }
- );
- },
-};
-
-function truncate(s: string, max: number): string {
- const oneLine = s.replace(/\n+/g, ' ').replace(/\s+/g, ' ');
- return oneLine.length > max ? oneLine.slice(0, max - 1) + '…' : oneLine;
-}
diff --git a/src/commands/repo/index.ts b/src/commands/repo/index.ts
index 2fb7286..0908f91 100644
--- a/src/commands/repo/index.ts
+++ b/src/commands/repo/index.ts
@@ -1,15 +1,9 @@
import { repoListCommand } from './list';
import { repoShowCommand } from './show';
import { repoFindCommand } from './find';
-import { repoGrepCommand } from './grep';
-import { repoTreeCommand } from './tree';
-import { repoReadCommand } from './read';
export const repoCommands = [
repoListCommand,
repoShowCommand,
repoFindCommand,
- repoGrepCommand,
- repoTreeCommand,
- repoReadCommand,
];
diff --git a/src/commands/repo/read.ts b/src/commands/repo/read.ts
deleted file mode 100644
index 6e1f398..0000000
--- a/src/commands/repo/read.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { Command } from '../../command';
-import type { Config } from '../../config/schema';
-import { PolylaneAPI } from '../../generated/client';
-import { formatOutput } from '../../output/formatter';
-import { requireWorkspace, requirePositional } from '../helpers';
-import { resolveRepoId } from './id';
-
-export const repoReadCommand: Command = {
- name: 'repo read',
- description: 'Read a file from a repository',
- operationId: 'repositories.codefiles.contents',
- positional: [
- { name: 'repo-id', description: 'Repo ID, owner/name, or short name' },
- { name: 'path', description: 'Path to the file' },
- ],
- examples: ['polylane repo read cli src/main.ts'],
- async execute(config: Config, _flags, args: Record): Promise {
- const workspaceId = await requireWorkspace(config);
- const repoRaw = requirePositional(args, 0, 'repo-id');
- const path = requirePositional(args, 1, 'path');
-
- const repoId = await resolveRepoId(config, repoRaw, workspaceId);
- const api = new PolylaneAPI(config);
- const result = await api.repositoriesCodefilesContents({
- workspaceId,
- repositoryId: repoId,
- path,
- });
-
- if (config.output === 'json') {
- formatOutput(config, result);
- return;
- }
- process.stdout.write(result.contents);
- if (!result.contents.endsWith('\n')) process.stdout.write('\n');
- },
-};
diff --git a/src/commands/repo/tree.ts b/src/commands/repo/tree.ts
deleted file mode 100644
index 370d7f3..0000000
--- a/src/commands/repo/tree.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type { Command } from '../../command';
-import type { Config } from '../../config/schema';
-import { PolylaneAPI } from '../../generated/client';
-import { formatList } from '../../output/formatter';
-import { requireWorkspace, requirePositional, getPositional } from '../helpers';
-import { resolveRepoId } from './id';
-
-export const repoTreeCommand: Command = {
- name: 'repo tree',
- description: 'List files in a directory of a repository',
- operationId: 'repositories.codefiles.tree',
- positional: [
- { name: 'repo-id', description: 'Repo ID, owner/name, or short name' },
- { name: 'path', description: 'Directory path (default: root)', required: false },
- ],
- examples: ['polylane repo tree cli src/commands'],
- async execute(config: Config, _flags, args: Record): Promise {
- const workspaceId = await requireWorkspace(config);
- const repoRaw = requirePositional(args, 0, 'repo-id');
- const path = getPositional(args, 1) ?? '';
-
- const repoId = await resolveRepoId(config, repoRaw, workspaceId);
- const api = new PolylaneAPI(config);
- const result = await api.repositoriesCodefilesTree(workspaceId, repoId, { path });
-
- formatList(
- config,
- { items: result.items as Array>, count: result.totalCount },
- {
- headers: ['Name', 'Type', 'Lang', 'Path'],
- rows: (item) => [
- String(item.name ?? ''),
- String(item.type ?? ''),
- String(item.language ?? ''),
- String(item.path ?? ''),
- ],
- }
- );
- },
-};
diff --git a/src/registry.ts b/src/registry.ts
index d438d65..b0eb185 100644
--- a/src/registry.ts
+++ b/src/registry.ts
@@ -18,8 +18,8 @@ const RESOURCE_ORDER: Record = {
feed: { name: 'feed', description: 'Workspace activity feed (what just happened)', order: 6 },
issue: { name: 'issue', description: 'Detected issues (anomalies + alerts) and their timelines', order: 8 },
service: { name: 'service', description: 'Cloud infrastructure (nodes, logs, metrics, graph)', order: 20 },
- repo: { name: 'repo', description: 'Repositories and code search', order: 30 },
- tools: { name: 'tools', description: 'Run Polylane agent tools (observability, infra graph, code search)', order: 40 },
+ repo: { name: 'repo', description: 'Repositories', order: 30 },
+ tools: { name: 'tools', description: 'Run Polylane agent tools (observability, infra graph, GitHub reads)', order: 40 },
memory: { name: 'memory', description: 'Persistent agent memory', order: 50 },
note: { name: 'note', description: 'Daily and global workspace notes', order: 52 },
thread: { name: 'thread', description: 'Conversation threads', order: 60 },