threadlines 0.1.1 → 0.1.3

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
@@ -23,7 +23,7 @@ threadlines check
23
23
  ## Configuration
24
24
 
25
25
  - `THREADLINE_API_URL` - Server URL (default: http://localhost:3000)
26
- - `OPENAI_API_KEY` - Your OpenAI API key (required)
26
+ - Can also be set with `--api-url` flag: `npx threadlines check --api-url http://your-server.com`
27
27
 
28
28
  ## Threadline Files
29
29
 
@@ -52,7 +52,8 @@ async function checkCommand(options) {
52
52
  const threadlines = await (0, experts_1.findThreadlines)(repoRoot);
53
53
  console.log(chalk_1.default.green(`✓ Found ${threadlines.length} threadline(s)\n`));
54
54
  if (threadlines.length === 0) {
55
- console.log(chalk_1.default.yellow('⚠️ No valid threadlines found. Add threadline files to /threadlines folder.'));
55
+ console.log(chalk_1.default.yellow('⚠️ No valid threadlines found.'));
56
+ console.log(chalk_1.default.gray(' Run `npx threadlines init` to create your first threadline.'));
56
57
  process.exit(0);
57
58
  }
58
59
  // 2. Get git diff
@@ -83,20 +84,15 @@ async function checkCommand(options) {
83
84
  contextContent
84
85
  };
85
86
  });
86
- // 4. Get API URL and key
87
+ // 4. Get API URL
87
88
  const apiUrl = options.apiUrl || process.env.THREADLINE_API_URL || 'http://localhost:3000';
88
- const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
89
- if (!apiKey) {
90
- throw new Error('OpenAI API key required. Set OPENAI_API_KEY environment variable.');
91
- }
92
89
  // 5. Call review API
93
90
  console.log(chalk_1.default.gray('🤖 Running threadline checks...'));
94
91
  const client = new client_1.ReviewAPIClient(apiUrl);
95
92
  const response = await client.review({
96
93
  threadlines: threadlinesWithContext,
97
94
  diff: gitDiff.diff,
98
- files: gitDiff.changedFiles,
99
- apiKey
95
+ files: gitDiff.changedFiles
100
96
  });
101
97
  // 6. Display results
102
98
  displayResults(response);
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.initCommand = initCommand;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const TEMPLATE = `---
44
+ id: example-threadline
45
+ version: 1.0.0
46
+ patterns:
47
+ - "**/*.ts"
48
+ - "**/*.tsx"
49
+ context_files: []
50
+ ---
51
+
52
+ # Example Threadline
53
+
54
+ Describe your coding standard or convention here.
55
+
56
+ This threadline will check all TypeScript files (\`**/*.ts\` and \`**/*.tsx\`) against the guidelines you define below.
57
+
58
+ ## Guidelines
59
+
60
+ - Add your first guideline here
61
+ - Add your second guideline here
62
+ - Add examples or patterns to follow
63
+
64
+ ## Examples
65
+
66
+ \`\`\`typescript
67
+ // Good example
68
+ \`\`\`
69
+
70
+ \`\`\`typescript
71
+ // Bad example - avoid this
72
+ \`\`\`
73
+ `;
74
+ async function initCommand() {
75
+ const repoRoot = process.cwd();
76
+ const threadlinesDir = path.join(repoRoot, 'threadlines');
77
+ const exampleFile = path.join(threadlinesDir, 'example.md');
78
+ try {
79
+ // Create threadlines directory if it doesn't exist
80
+ if (!fs.existsSync(threadlinesDir)) {
81
+ fs.mkdirSync(threadlinesDir, { recursive: true });
82
+ console.log(chalk_1.default.green(`✓ Created /threadlines directory`));
83
+ }
84
+ // Check if example file already exists
85
+ if (fs.existsSync(exampleFile)) {
86
+ console.log(chalk_1.default.yellow(`⚠️ ${exampleFile} already exists`));
87
+ console.log(chalk_1.default.gray(' Edit it to create your threadline, or delete it and run init again.'));
88
+ return;
89
+ }
90
+ // Write template file
91
+ fs.writeFileSync(exampleFile, TEMPLATE, 'utf-8');
92
+ console.log(chalk_1.default.green(`✓ Created ${exampleFile}`));
93
+ console.log('');
94
+ console.log(chalk_1.default.blue('Next steps:'));
95
+ console.log(chalk_1.default.gray(' 1. Edit threadlines/example.md with your coding standards'));
96
+ console.log(chalk_1.default.gray(' 2. Rename it to something descriptive (e.g., error-handling.md)'));
97
+ console.log(chalk_1.default.gray(' 3. Run: npx threadlines check'));
98
+ }
99
+ catch (error) {
100
+ console.error(chalk_1.default.red(`\n❌ Error: ${error.message}`));
101
+ process.exit(1);
102
+ }
103
+ }
package/dist/index.js CHANGED
@@ -3,15 +3,19 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const commander_1 = require("commander");
5
5
  const check_1 = require("./commands/check");
6
+ const init_1 = require("./commands/init");
6
7
  const program = new commander_1.Command();
7
8
  program
8
- .name('threadline')
9
+ .name('threadlines')
9
10
  .description('AI-powered linter based on your natural language documentation')
10
11
  .version('0.1.0');
12
+ program
13
+ .command('init')
14
+ .description('Create a template threadline file to get started')
15
+ .action(init_1.initCommand);
11
16
  program
12
17
  .command('check')
13
- .description('Check code against your experts')
18
+ .description('Check code against your threadlines')
14
19
  .option('--api-url <url>', 'Threadline server URL', process.env.THREADLINE_API_URL || 'http://localhost:3000')
15
- .option('--api-key <key>', 'OpenAI API key', process.env.OPENAI_API_KEY)
16
20
  .action(check_1.checkCommand);
17
21
  program.parse();
@@ -42,12 +42,12 @@ const REQUIRED_FIELDS = ['id', 'version', 'patterns'];
42
42
  async function findThreadlines(repoRoot) {
43
43
  const expertsDir = path.join(repoRoot, 'threadlines');
44
44
  if (!fs.existsSync(expertsDir)) {
45
- throw new Error('No /threadlines folder found. Create a /threadlines folder with your threadline markdown files.');
45
+ throw new Error('No /threadlines folder found. Run `npx threadlines init` to create your first threadline.');
46
46
  }
47
47
  const files = fs.readdirSync(expertsDir);
48
48
  const expertFiles = files.filter(f => f.endsWith('.md'));
49
49
  if (expertFiles.length === 0) {
50
- throw new Error('No threadline files found in /threadlines folder. Add .md files with threadline definitions.');
50
+ throw new Error('No threadline files found in /threadlines folder. Run `npx threadlines init` to create a template.');
51
51
  }
52
52
  const threadlines = [];
53
53
  for (const file of expertFiles) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threadlines",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Threadline CLI - AI-powered linter based on your natural language documentation",
5
5
  "main": "dist/index.js",
6
6
  "bin": {