@octp/cli 0.1.4 → 0.1.5

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 CHANGED
@@ -203,6 +203,44 @@ Remove a document from the knowledge base.
203
203
  octopus knowledge remove cm3x1234
204
204
  ```
205
205
 
206
+ ### `octopus skills list`
207
+
208
+ List available Octopus skills and their install status for Claude Code and Codex.
209
+
210
+ ```
211
+ $ octopus skills list
212
+
213
+ Skill Description Claude Codex
214
+ octopus-fix Check open PRs for review comments, apply fixes, and push updates yes no
215
+ ```
216
+
217
+ ### `octopus skills install`
218
+
219
+ Install Octopus skills for AI coding agents. By default installs for both Claude Code and Codex.
220
+
221
+ ```bash
222
+ # Install for both Claude Code and Codex
223
+ octopus skills install
224
+
225
+ # Install only for Claude Code
226
+ octopus skills install --claude
227
+
228
+ # Install only for Codex
229
+ octopus skills install --codex
230
+ ```
231
+
232
+ Once installed, you can use the skills as slash commands:
233
+ - **Claude Code**: `/octopus-fix`
234
+ - **Codex**: Automatically available as a skill
235
+
236
+ ### `octopus analyze-deps <repo-url>`
237
+
238
+ Analyze npm dependencies in a GitHub repository for security risks. Streams results in real-time with risk categorization.
239
+
240
+ ```bash
241
+ octopus analyze-deps https://github.com/acme/backend
242
+ ```
243
+
206
244
  ### `octopus usage`
207
245
 
208
246
  Show your organization's monthly usage, spend, and credit balance.
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const skillsCommand: Command;
@@ -0,0 +1,130 @@
1
+ import { Command } from "commander";
2
+ import { readdir, readFile, mkdir, writeFile, access } from "node:fs/promises";
3
+ import { resolve, join, dirname } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { homedir } from "node:os";
6
+ import chalk from "chalk";
7
+ import { success, error, info, table } from "../lib/output.js";
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const SKILLS_DIR = resolve(__dirname, "..", "..", "src", "skiils");
11
+ const CLAUDE_DIR = join(homedir(), ".claude", "commands");
12
+ const CODEX_DIR = join(homedir(), ".agents", "skills");
13
+ function parseSkillFrontmatter(content) {
14
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
15
+ if (!match)
16
+ return { name: "", description: "" };
17
+ const fm = match[1];
18
+ const name = fm.match(/(?:^|\n)name:\s*(.+)/)?.[1]?.trim() ?? "";
19
+ const desc = fm.match(/(?:^|\n)description:\s*(.+)/)?.[1]?.trim() ?? "";
20
+ return { name, description: desc };
21
+ }
22
+ async function getSkills() {
23
+ try {
24
+ const files = await readdir(SKILLS_DIR);
25
+ const skills = [];
26
+ for (const file of files) {
27
+ if (!file.endsWith(".md"))
28
+ continue;
29
+ const content = await readFile(join(SKILLS_DIR, file), "utf-8");
30
+ const { name, description } = parseSkillFrontmatter(content);
31
+ skills.push({
32
+ fileName: file,
33
+ name: name || file.replace(/\.md$/, ""),
34
+ description,
35
+ });
36
+ }
37
+ return skills;
38
+ }
39
+ catch {
40
+ return [];
41
+ }
42
+ }
43
+ async function exists(path) {
44
+ try {
45
+ await access(path);
46
+ return true;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ async function installForClaude(skills) {
53
+ await mkdir(CLAUDE_DIR, { recursive: true });
54
+ let count = 0;
55
+ for (const skill of skills) {
56
+ const src = join(SKILLS_DIR, skill.fileName);
57
+ const dest = join(CLAUDE_DIR, skill.fileName);
58
+ const content = await readFile(src, "utf-8");
59
+ await writeFile(dest, content, "utf-8");
60
+ count++;
61
+ }
62
+ return count;
63
+ }
64
+ async function installForCodex(skills) {
65
+ let count = 0;
66
+ for (const skill of skills) {
67
+ const skillName = skill.fileName.replace(/\.md$/, "");
68
+ const skillDir = join(CODEX_DIR, skillName);
69
+ await mkdir(skillDir, { recursive: true });
70
+ const src = join(SKILLS_DIR, skill.fileName);
71
+ const content = await readFile(src, "utf-8");
72
+ // Codex expects SKILL.md inside a named directory
73
+ await writeFile(join(skillDir, "SKILL.md"), content, "utf-8");
74
+ count++;
75
+ }
76
+ return count;
77
+ }
78
+ // --- Commands ---
79
+ const installCommand = new Command("install")
80
+ .description("Install Octopus skills for Claude Code and/or Codex")
81
+ .option("--claude", "Install only for Claude Code")
82
+ .option("--codex", "Install only for Codex")
83
+ .action(async (opts) => {
84
+ const skills = await getSkills();
85
+ if (skills.length === 0) {
86
+ error("No skills found to install.");
87
+ return;
88
+ }
89
+ const both = !opts.claude && !opts.codex;
90
+ let claudeCount = 0;
91
+ let codexCount = 0;
92
+ if (both || opts.claude) {
93
+ claudeCount = await installForClaude(skills);
94
+ success(`Installed ${claudeCount} skill(s) to ${chalk.dim(CLAUDE_DIR)}`);
95
+ }
96
+ if (both || opts.codex) {
97
+ codexCount = await installForCodex(skills);
98
+ success(`Installed ${codexCount} skill(s) to ${chalk.dim(CODEX_DIR)}`);
99
+ }
100
+ console.log();
101
+ for (const skill of skills) {
102
+ info(`${chalk.bold(skill.name)} — ${skill.description || chalk.dim("no description")}`);
103
+ }
104
+ });
105
+ const listCommand = new Command("list")
106
+ .description("List available Octopus skills and their install status")
107
+ .action(async () => {
108
+ const skills = await getSkills();
109
+ if (skills.length === 0) {
110
+ info("No skills available.");
111
+ return;
112
+ }
113
+ const rows = [];
114
+ for (const skill of skills) {
115
+ const claudeInstalled = await exists(join(CLAUDE_DIR, skill.fileName));
116
+ const codexInstalled = await exists(join(CODEX_DIR, skill.fileName.replace(/\.md$/, ""), "SKILL.md"));
117
+ rows.push([
118
+ chalk.bold(skill.name),
119
+ skill.description || chalk.dim("—"),
120
+ claudeInstalled ? chalk.green("yes") : chalk.dim("no"),
121
+ codexInstalled ? chalk.green("yes") : chalk.dim("no"),
122
+ ]);
123
+ }
124
+ table(rows, ["Skill", "Description", "Claude", "Codex"]);
125
+ });
126
+ export const skillsCommand = new Command("skills")
127
+ .description("Manage Octopus skills for AI coding agents")
128
+ .addCommand(installCommand)
129
+ .addCommand(listCommand);
130
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { repoCommand } from "./commands/repo/index.js";
8
8
  import { prCommand } from "./commands/pr/index.js";
9
9
  import { knowledgeCommand } from "./commands/knowledge/index.js";
10
10
  import { analyzeDepsCommand } from "./commands/analyze-deps.js";
11
+ import { skillsCommand } from "./commands/skills.js";
11
12
  const program = new Command();
12
13
  program
13
14
  .name("octopus")
@@ -22,5 +23,6 @@ program.addCommand(repoCommand);
22
23
  program.addCommand(prCommand);
23
24
  program.addCommand(knowledgeCommand);
24
25
  program.addCommand(analyzeDepsCommand);
26
+ program.addCommand(skillsCommand);
25
27
  program.parse();
26
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAEvC,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octp/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "CLI tool for Octopus — AI-powered PR review and codebase intelligence",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,7 +17,8 @@
17
17
  },
18
18
  "files": [
19
19
  "dist",
20
- "bin"
20
+ "bin",
21
+ "src/skiils"
21
22
  ],
22
23
  "dependencies": {
23
24
  "chalk": "^5.4.1",
@@ -0,0 +1,120 @@
1
+ ---
2
+ allowed-tools: Bash(git:*), Bash(gh:*), Read, Edit, Write, Glob, Grep
3
+ description: Check open PRs for review comments, apply fixes, and push updates
4
+ ---
5
+
6
+ # Octopus Fix
7
+
8
+ Review all open PRs for pending reviews and requested changes from Octopus Review bot. Apply the necessary fixes, commit them, and push the updates.
9
+
10
+ Rules:
11
+ - Ignore false-positive feedback.
12
+ - For each false positive, react to the comment with 👎 and explain .
13
+ - For each valid and useful suggestion, react to the comment with 👍.
14
+ - After fixing a valid issue, reply in the relevant review thread with a brief note describing the fix.
15
+ - Resolve the thread/conversation after replying, if resolving is supported.
16
+ - If thread resolution is not supported, leave a reply clearly stating that the issue has been addressed.
17
+
18
+ Once all fixes are applied and pushed, post a final PR comment tagging @octopus to notify it that the updates are ready for review.
19
+
20
+ ## Instructions
21
+
22
+ Follow these steps carefully and in order:
23
+
24
+ ### Step 1: Discover Open PRs
25
+
26
+ 1. Save the current branch name: `git branch --show-current`
27
+ 2. List open PRs authored by the current user:
28
+ ```
29
+ gh pr list --author "@me" --state open --json number,title,headRefName,reviewDecision,url
30
+ ```
31
+ 3. If no open PRs exist, inform the user and stop.
32
+ 4. Display the list of open PRs with their review status to the user.
33
+
34
+ ### Step 2: Check Reviews for Each PR
35
+
36
+ For each open PR (or a specific PR if the user provided a number as argument `$ARGUMENTS`):
37
+
38
+ 1. Fetch review comments and review threads:
39
+ ```
40
+ gh pr view <number> --json reviews,reviewRequests,comments,title,headRefName,url
41
+ gh api repos/{owner}/{repo}/pulls/<number>/comments --jq '.[] | {id, path, line, body, user: .user.login, created_at}'
42
+ gh api repos/{owner}/{repo}/pulls/<number>/reviews --jq '.[] | {id, state, body, user: .user.login}'
43
+ ```
44
+ 2. Also check for inline review comments (conversation threads):
45
+ ```
46
+ gh pr view <number> --comments --json comments
47
+ ```
48
+ 3. Filter for actionable feedback:
49
+ - Reviews with state `CHANGES_REQUESTED`
50
+ - Unresolved review comments (inline code suggestions, requested changes)
51
+ - General PR comments that contain action items
52
+ 4. Skip PRs that have no actionable feedback (state is `APPROVED` or no reviews).
53
+
54
+ ### Step 3: Present Review Summary
55
+
56
+ Before making any changes, present a summary to the user:
57
+
58
+ For each PR with actionable feedback, show:
59
+ - PR title and number
60
+ - Branch name
61
+ - Reviewer(s) who requested changes
62
+ - List of each review comment with:
63
+ - File path and line number (if inline)
64
+ - The comment text
65
+ - Your proposed fix or action
66
+
67
+ **Ask the user to confirm** which reviews to address before proceeding.
68
+
69
+ ### Step 4: Apply Fixes
70
+
71
+ For each confirmed PR:
72
+
73
+ 1. **Checkout the PR branch**:
74
+ ```
75
+ git checkout <branch-name> && git pull origin <branch-name>
76
+ ```
77
+ 2. **Read the relevant files** mentioned in the review comments.
78
+ 3. **Apply the requested changes**:
79
+ - For code suggestions: apply the suggested code change exactly
80
+ - For style/refactor requests: make the minimal change that addresses the feedback
81
+ - For bug reports: fix the bug as described
82
+ - For questions/clarifications: if a code change is needed, make it; otherwise note it for the summary
83
+ 4. **Stage and commit** the fixes:
84
+ ```
85
+ git add <changed-files>
86
+ git commit -m "$(cat <<'EOF'
87
+ fix: address review feedback on #<PR-number>
88
+
89
+ <bullet list of changes made in response to reviews>
90
+
91
+ EOF
92
+ )"
93
+ ````
94
+ 5. **Push** the changes:
95
+ ```
96
+ git push origin <branch-name>
97
+ ```
98
+
99
+ ### Step 5: Return to Original Branch
100
+
101
+ After all fixes are pushed, checkout back to the branch the user was originally on.
102
+
103
+ ### Step 6: Report Summary
104
+
105
+ Print a summary table showing:
106
+ - PR number and title
107
+ - Branch name
108
+ - Number of review comments addressed
109
+ - What was changed (brief description)
110
+ - PR URL
111
+
112
+ ## Important Rules
113
+
114
+ - **Never force-push** — always use regular `git push`.
115
+ - **Always show the proposed fixes to the user** and get confirmation before committing.
116
+ - **Make minimal changes** — only fix what the reviewer asked for, do not refactor surrounding code.
117
+ - **If a review comment is unclear or ambiguous**, present it to the user and ask how to proceed rather than guessing.
118
+ - **If the review is just a question** (no code change needed), note it in the summary but don't make unnecessary changes.
119
+ - **If there are merge conflicts** when pulling the branch, inform the user and stop — do not attempt to resolve conflicts automatically.
120
+ - **Preserve the existing commit history** — do not squash, rebase, or amend existing commits.