ai-spector 0.1.1 → 0.1.2

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
@@ -1,6 +1,6 @@
1
- # Spec Writer
1
+ # AI Spector
2
2
 
3
- Spec Writer is an npm-installable bootstrapper for incremental documentation workflows in Cursor.
3
+ AI Spector is an npm-installable bootstrapper for incremental documentation workflows in Cursor.
4
4
 
5
5
  1. Analyze project sources with Graphify MCP.
6
6
  2. Generate SRS documents in dependency order.
@@ -116,7 +116,7 @@ From this package repo:
116
116
  ```bash
117
117
  npm login
118
118
  npm whoami
119
- chmod +x bin/spec-writer.js
119
+ chmod +x bin/ai-spector.js
120
120
  npm pack --dry-run
121
121
  npm publish --access public
122
122
  ```
@@ -137,7 +137,7 @@ npm publish
137
137
  generate-srs.md
138
138
  generate-detail-design.md
139
139
  skills/
140
- spec-writer/
140
+ ai-spector/
141
141
  SKILL.md
142
142
 
143
143
  docs/
@@ -1,9 +1,9 @@
1
1
  ---
2
- name: spec-writer
2
+ name: ai-spector
3
3
  description: "Incremental documentation workflow for analyze -> SRS -> detail design using Graphify MCP, dependency DAGs, and parallel subagents."
4
4
  ---
5
5
 
6
- # Spec Writer Skill
6
+ # AI Spector Skill
7
7
 
8
8
  Use this skill when the user requests document generation from project data and templates.
9
9
 
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { runInit } = require("../src/cli/init");
4
+
5
+ function parseArgs(argv) {
6
+ const [command, ...rest] = argv;
7
+ const flags = {
8
+ yes: false,
9
+ force: false,
10
+ noGraphify: false,
11
+ skipIndex: false
12
+ };
13
+
14
+ for (const arg of rest) {
15
+ if (arg === "--yes" || arg === "-y") flags.yes = true;
16
+ if (arg === "--force" || arg === "-f") flags.force = true;
17
+ if (arg === "--no-graphify") flags.noGraphify = true;
18
+ if (arg === "--skip-index") flags.skipIndex = true;
19
+ }
20
+
21
+ return { command, flags };
22
+ }
23
+
24
+ function printHelp() {
25
+ console.log(`ai-spector
26
+
27
+ Usage:
28
+ ai-spector init [--yes] [--force] [--no-graphify] [--skip-index]
29
+
30
+ Commands:
31
+ init Install Cursor commands, skill, templates, and workflow files.
32
+ `);
33
+ }
34
+
35
+ async function main() {
36
+ const { command, flags } = parseArgs(process.argv.slice(2));
37
+
38
+ if (!command || command === "--help" || command === "-h") {
39
+ printHelp();
40
+ return;
41
+ }
42
+
43
+ if (command === "init") {
44
+ await runInit(process.cwd(), flags);
45
+ return;
46
+ }
47
+
48
+ console.error(`Unknown command: ${command}`);
49
+ printHelp();
50
+ process.exitCode = 1;
51
+ }
52
+
53
+ main().catch((error) => {
54
+ console.error(error.message);
55
+ process.exitCode = 1;
56
+ });
@@ -22,10 +22,10 @@ function parseArgs(argv) {
22
22
  }
23
23
 
24
24
  function printHelp() {
25
- console.log(`spec-writer
25
+ console.log(`ai-spector
26
26
 
27
27
  Usage:
28
- spec-writer init [--yes] [--force] [--no-graphify] [--skip-index]
28
+ ai-spector init [--yes] [--force] [--no-graphify] [--skip-index]
29
29
 
30
30
  Commands:
31
31
  init Install Cursor commands, skill, templates, and workflow files.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "ai-spector",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Cursor skill and workflow bootstrapper for incremental SRS/detail design generation.",
5
5
  "type": "commonjs",
6
6
  "bin": {
7
- "ai-spector": "bin/spec-writer.js"
7
+ "ai-spector": "bin/ai-spector.js"
8
8
  },
9
9
  "keywords": [
10
10
  "cursor",
@@ -18,8 +18,8 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "scripts": {
21
- "start": "node bin/spec-writer.js",
22
- "init:local": "node bin/spec-writer.js init",
21
+ "start": "node bin/ai-spector.js",
22
+ "init:local": "node bin/ai-spector.js init",
23
23
  "lint": "node -e \"console.log('No linter configured yet')\""
24
24
  }
25
25
  }
package/src/cli/init.js CHANGED
@@ -1,4 +1,3 @@
1
- const fs = require("fs");
2
1
  const path = require("path");
3
2
  const { spawnSync } = require("child_process");
4
3
  const { ensureDir, copyRecursive, writeJson, readJson } = require("./helpers/fs");
@@ -10,7 +9,7 @@ function getPackageRoot() {
10
9
  function targetPaths(cwd) {
11
10
  return {
12
11
  cursorCommands: path.join(cwd, ".cursor/commands"),
13
- cursorSkill: path.join(cwd, ".cursor/skills/spec-writer"),
12
+ cursorSkill: path.join(cwd, ".cursor/skills/ai-spector"),
14
13
  docsRoot: path.join(cwd, "docs"),
15
14
  templates: path.join(cwd, "docs/_templates"),
16
15
  docflowRoot: path.join(cwd, "docs/.docflow"),
@@ -25,20 +24,26 @@ function targetPaths(cwd) {
25
24
  };
26
25
  }
27
26
 
28
- function installGraphify(cwd) {
27
+ function canRunGraphifyCli(cwd) {
29
28
  const detect = spawnSync("npx", ["--yes", "graphify", "--help"], {
30
29
  cwd,
31
30
  stdio: "ignore"
32
31
  });
33
- if (detect.status === 0) return { installed: false, available: true };
32
+ return detect.status === 0;
33
+ }
34
34
 
35
+ function installGraphify(cwd) {
36
+ if (canRunGraphifyCli(cwd)) {
37
+ return { installed: false, available: true };
38
+ }
35
39
  const install = spawnSync("npm", ["install", "--save-dev", "graphify"], {
36
40
  cwd,
37
41
  stdio: "inherit"
38
42
  });
43
+ const available = install.status === 0 && canRunGraphifyCli(cwd);
39
44
  return {
40
45
  installed: install.status === 0,
41
- available: install.status === 0
46
+ available
42
47
  };
43
48
  }
44
49
 
@@ -50,8 +55,12 @@ function runInitialGraphifyIndex(cwd, graphConfigPath) {
50
55
  "--config",
51
56
  graphConfigPath
52
57
  ];
53
- const result = spawnSync("npx", args, { cwd, stdio: "inherit" });
54
- return result.status === 0;
58
+ const result = spawnSync("npx", args, { cwd, stdio: "pipe", encoding: "utf8" });
59
+ return {
60
+ ok: result.status === 0,
61
+ stderr: result.stderr || "",
62
+ stdout: result.stdout || ""
63
+ };
55
64
  }
56
65
 
57
66
  function installAssets(cwd, options) {
@@ -79,7 +88,7 @@ function installAssets(cwd, options) {
79
88
  copyOptions
80
89
  );
81
90
  copyRecursive(
82
- path.join(pkgRoot, "assets/cursor/skills/spec-writer"),
91
+ path.join(pkgRoot, "assets/cursor/skills/ai-spector"),
83
92
  t.cursorSkill,
84
93
  copyOptions
85
94
  );
@@ -148,14 +157,20 @@ async function runInit(cwd, options) {
148
157
  graphifyInstalled = result.installed;
149
158
  if (!graphifyReady) {
150
159
  console.warn(
151
- "Graphify installation failed. Continue with manual setup later."
160
+ "Graphify CLI was not detected. Continue with manual setup or rerun with --no-graphify."
152
161
  );
153
162
  }
154
163
  }
155
164
 
156
165
  if (graphifyReady && !options.skipIndex) {
157
166
  const graphConfigPath = path.join(t.config, "analyze.graphify.json");
158
- runInitialGraphifyIndex(cwd, graphConfigPath);
167
+ const indexResult = runInitialGraphifyIndex(cwd, graphConfigPath);
168
+ if (!indexResult.ok) {
169
+ console.warn("Graphify index step failed; initialization will continue.");
170
+ if (indexResult.stderr) {
171
+ console.warn(indexResult.stderr.trim());
172
+ }
173
+ }
159
174
  }
160
175
 
161
176
  const statePath = path.join(t.docflowRoot, "state.json");
@@ -167,7 +182,7 @@ async function runInit(cwd, options) {
167
182
  };
168
183
  writeJson(statePath, state, { overwrite: true });
169
184
 
170
- console.log("Spec Writer initialization complete.");
185
+ console.log("AI Spector initialization complete.");
171
186
  console.log("Next steps:");
172
187
  console.log("- Run `/analyze [paths...]` in Cursor.");
173
188
  console.log("- Run `/generate-srs` and `/generate-detail-design` incrementally.");