noslop 0.1.0
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/LICENSE +21 -0
- package/README.md +170 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +281 -0
- package/dist/lib/content.d.ts +143 -0
- package/dist/lib/content.js +463 -0
- package/dist/lib/content.test.d.ts +1 -0
- package/dist/lib/content.test.js +746 -0
- package/dist/lib/templates.d.ts +35 -0
- package/dist/lib/templates.js +264 -0
- package/dist/lib/templates.test.d.ts +1 -0
- package/dist/lib/templates.test.js +110 -0
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +372 -0
- package/package.json +84 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template for new draft posts
|
|
3
|
+
* Placeholders:
|
|
4
|
+
* - {{TITLE}}: Will be replaced with the post title
|
|
5
|
+
*/
|
|
6
|
+
export declare const POST_TEMPLATE = "# {{TITLE}}\n\n## Post\n```\n\n```\n\n## Status\ndraft\n\n## Media\nNone\n\n## Scheduled\n\n## Posted\n\n## Published\n";
|
|
7
|
+
/**
|
|
8
|
+
* Template for NOSLOP.md - tool documentation
|
|
9
|
+
* This file is regenerated on every launch to ensure documentation is up-to-date
|
|
10
|
+
*/
|
|
11
|
+
export declare const NOSLOP_TEMPLATE = "# noslop - Content Workflow CLI\n\nA command-line tool for managing social media content with an interactive TUI.\n\n## Quick Start\n\n```bash\nnoslop # Open interactive TUI\nnoslop init # Initialize new project\nnoslop new \"My Post\" # Create new draft\n```\n\n## Commands\n\n### Core\n| Command | Description |\n|---------|-------------|\n| `noslop` | Open interactive TUI |\n| `noslop init` | Create folder structure + config files |\n| `noslop help` | Show all commands |\n\n### Content Management\n| Command | Description |\n|---------|-------------|\n| `noslop new <title>` | Create new draft with title |\n| `noslop list [--drafts|--posts]` | List content with schedule |\n| `noslop status` | Summary: counts, next scheduled |\n| `noslop show <id>` | Show full content of a post/draft |\n\n### Workflow Actions\n| Command | Description |\n|---------|-------------|\n| `noslop ready <id>` | Mark draft as ready to post |\n| `noslop unready <id>` | Mark draft as in-progress |\n| `noslop post <id>` | Move draft to posts folder |\n| `noslop unpost <id>` | Move post back to drafts |\n| `noslop publish <id> <url>` | Add published URL to post |\n| `noslop schedule <id> <datetime>` | Set/update scheduled time |\n| `noslop delete <id>` | Delete a draft |\n\n### Examples\n```bash\n# Full workflow\nnoslop new \"Monday Motivation\"\nnoslop schedule monday-motivation \"2026-01-27 09:00\"\nnoslop ready monday-motivation\n# ... post manually to platform ...\nnoslop post monday-motivation\nnoslop publish monday-motivation \"https://x.com/user/status/123\"\n```\n\n## Folder Structure\n\n```\nyour-project/\n\u251C\u2500\u2500 CLAUDE.md # Your brand voice & guidelines\n\u251C\u2500\u2500 NOSLOP.md # This file (tool documentation)\n\u251C\u2500\u2500 drafts/ # Work in progress\n\u2502 \u2514\u2500\u2500 post-name/\n\u2502 \u251C\u2500\u2500 x.md # Post content\n\u2502 \u2514\u2500\u2500 assets/ # Images, videos (optional)\n\u2514\u2500\u2500 posts/ # Published/scheduled content\n \u2514\u2500\u2500 post-name/\n \u251C\u2500\u2500 x.md\n \u2514\u2500\u2500 assets/\n```\n\n## Post File Format (x.md)\n\n```markdown\n# Post Title\n\n## Post\n\\`\\`\\`\nyour post content here\nlowercase, brand voice, etc.\n\\`\\`\\`\n\n## Status\ndraft | ready\n\n## Media\nDescription of media to create/attach\n\n## Scheduled\n2026-01-27 09:00\n\n## Posted\n2026-01-27 09:00\n\n## Published\nhttps://x.com/user/status/123\n```\n\n## TUI Keyboard Shortcuts\n\n| Key | Drafts Tab | Posts Tab |\n|-----|------------|-----------|\n| `Tab` | Switch to Posts | Switch to Drafts |\n| `\u2191/\u2193` | Navigate items | Navigate items |\n| `Enter` | Toggle ready/draft | Add URL |\n| `Space` | Move to Posts | Move to Drafts |\n| `Backspace` | Delete (drafts only) | \u2014 |\n| `s` | Toggle schedule view | Toggle schedule view |\n| `\u2190/\u2192` | Navigate weeks | Navigate weeks |\n| `q` | Quit | Quit |\n\n## Working with AI Assistants\n\nThis project is designed to work with Claude Code and other AI assistants:\n\n1. **Use CLI commands** instead of manual file editing\n2. **CLAUDE.md** contains your brand voice and guidelines\n3. **NOSLOP.md** (this file) documents all available commands\n\nThe AI should use commands like `noslop new`, `noslop ready`, `noslop post`\ninstead of directly creating/moving files.\n";
|
|
12
|
+
/**
|
|
13
|
+
* Template for CLAUDE.md - user-specific brand content
|
|
14
|
+
* This file contains brand voice guidelines for AI assistants
|
|
15
|
+
*/
|
|
16
|
+
export declare const CLAUDE_TEMPLATE = "# Content Guide\n\n> This project uses noslop for content management. See NOSLOP.md for CLI commands.\n\n---\n\n## Brand Voice\n\n<!--\nINSTRUCTIONS FOR AI: If this section is empty, interview the user to fill it in.\nAsk about tone, style, what to avoid, platform preferences, etc.\n-->\n\n### Tone & Style\n\n\n### Do's\n\n\n### Don'ts\n\n\n---\n\n## Platform Guidelines\n\n<!-- Which platforms? What's different about each? -->\n\n### Twitter/X\n\n\n### Other Platforms\n\n\n---\n\n## Key Messaging\n\n### Taglines\n\n\n### Key Phrases\n\n\n### Topics to Cover\n\n\n---\n\n## Content Examples\n\n<!-- Add example posts as you create them -->\n\n### Good Examples\n\n\n### Transformations (before \u2192 after)\n\n\n---\n\n## Visual Elements\n\n### Emoji Policy\n\n\n### ASCII Art Library\n\n\n";
|
|
17
|
+
/**
|
|
18
|
+
* Ensure NOSLOP.md documentation file exists and is up-to-date
|
|
19
|
+
* Creates or overwrites NOSLOP.md in the specified directory with
|
|
20
|
+
* the latest tool documentation template.
|
|
21
|
+
* @param cwd - Working directory (defaults to process.cwd())
|
|
22
|
+
*/
|
|
23
|
+
export declare function ensureNoslopMd(cwd?: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Initialize a new noslop project in the specified directory
|
|
26
|
+
* Creates the following structure:
|
|
27
|
+
* - drafts/ directory for work in progress
|
|
28
|
+
* - posts/ directory for published content
|
|
29
|
+
* - CLAUDE.md with brand guidelines template
|
|
30
|
+
* - NOSLOP.md with tool documentation
|
|
31
|
+
*
|
|
32
|
+
* @param cwd - Directory to initialize (defaults to process.cwd())
|
|
33
|
+
* @param projectName - Optional project name for CLAUDE.md header
|
|
34
|
+
*/
|
|
35
|
+
export declare function initProject(cwd?: string, projectName?: string): void;
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Template for new draft posts
|
|
5
|
+
* Placeholders:
|
|
6
|
+
* - {{TITLE}}: Will be replaced with the post title
|
|
7
|
+
*/
|
|
8
|
+
export const POST_TEMPLATE = `# {{TITLE}}
|
|
9
|
+
|
|
10
|
+
## Post
|
|
11
|
+
\`\`\`
|
|
12
|
+
|
|
13
|
+
\`\`\`
|
|
14
|
+
|
|
15
|
+
## Status
|
|
16
|
+
draft
|
|
17
|
+
|
|
18
|
+
## Media
|
|
19
|
+
None
|
|
20
|
+
|
|
21
|
+
## Scheduled
|
|
22
|
+
|
|
23
|
+
## Posted
|
|
24
|
+
|
|
25
|
+
## Published
|
|
26
|
+
`;
|
|
27
|
+
/**
|
|
28
|
+
* Template for NOSLOP.md - tool documentation
|
|
29
|
+
* This file is regenerated on every launch to ensure documentation is up-to-date
|
|
30
|
+
*/
|
|
31
|
+
export const NOSLOP_TEMPLATE = `# noslop - Content Workflow CLI
|
|
32
|
+
|
|
33
|
+
A command-line tool for managing social media content with an interactive TUI.
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
\`\`\`bash
|
|
38
|
+
noslop # Open interactive TUI
|
|
39
|
+
noslop init # Initialize new project
|
|
40
|
+
noslop new "My Post" # Create new draft
|
|
41
|
+
\`\`\`
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
|
|
45
|
+
### Core
|
|
46
|
+
| Command | Description |
|
|
47
|
+
|---------|-------------|
|
|
48
|
+
| \`noslop\` | Open interactive TUI |
|
|
49
|
+
| \`noslop init\` | Create folder structure + config files |
|
|
50
|
+
| \`noslop help\` | Show all commands |
|
|
51
|
+
|
|
52
|
+
### Content Management
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---------|-------------|
|
|
55
|
+
| \`noslop new <title>\` | Create new draft with title |
|
|
56
|
+
| \`noslop list [--drafts|--posts]\` | List content with schedule |
|
|
57
|
+
| \`noslop status\` | Summary: counts, next scheduled |
|
|
58
|
+
| \`noslop show <id>\` | Show full content of a post/draft |
|
|
59
|
+
|
|
60
|
+
### Workflow Actions
|
|
61
|
+
| Command | Description |
|
|
62
|
+
|---------|-------------|
|
|
63
|
+
| \`noslop ready <id>\` | Mark draft as ready to post |
|
|
64
|
+
| \`noslop unready <id>\` | Mark draft as in-progress |
|
|
65
|
+
| \`noslop post <id>\` | Move draft to posts folder |
|
|
66
|
+
| \`noslop unpost <id>\` | Move post back to drafts |
|
|
67
|
+
| \`noslop publish <id> <url>\` | Add published URL to post |
|
|
68
|
+
| \`noslop schedule <id> <datetime>\` | Set/update scheduled time |
|
|
69
|
+
| \`noslop delete <id>\` | Delete a draft |
|
|
70
|
+
|
|
71
|
+
### Examples
|
|
72
|
+
\`\`\`bash
|
|
73
|
+
# Full workflow
|
|
74
|
+
noslop new "Monday Motivation"
|
|
75
|
+
noslop schedule monday-motivation "2026-01-27 09:00"
|
|
76
|
+
noslop ready monday-motivation
|
|
77
|
+
# ... post manually to platform ...
|
|
78
|
+
noslop post monday-motivation
|
|
79
|
+
noslop publish monday-motivation "https://x.com/user/status/123"
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
## Folder Structure
|
|
83
|
+
|
|
84
|
+
\`\`\`
|
|
85
|
+
your-project/
|
|
86
|
+
├── CLAUDE.md # Your brand voice & guidelines
|
|
87
|
+
├── NOSLOP.md # This file (tool documentation)
|
|
88
|
+
├── drafts/ # Work in progress
|
|
89
|
+
│ └── post-name/
|
|
90
|
+
│ ├── x.md # Post content
|
|
91
|
+
│ └── assets/ # Images, videos (optional)
|
|
92
|
+
└── posts/ # Published/scheduled content
|
|
93
|
+
└── post-name/
|
|
94
|
+
├── x.md
|
|
95
|
+
└── assets/
|
|
96
|
+
\`\`\`
|
|
97
|
+
|
|
98
|
+
## Post File Format (x.md)
|
|
99
|
+
|
|
100
|
+
\`\`\`markdown
|
|
101
|
+
# Post Title
|
|
102
|
+
|
|
103
|
+
## Post
|
|
104
|
+
\\\`\\\`\\\`
|
|
105
|
+
your post content here
|
|
106
|
+
lowercase, brand voice, etc.
|
|
107
|
+
\\\`\\\`\\\`
|
|
108
|
+
|
|
109
|
+
## Status
|
|
110
|
+
draft | ready
|
|
111
|
+
|
|
112
|
+
## Media
|
|
113
|
+
Description of media to create/attach
|
|
114
|
+
|
|
115
|
+
## Scheduled
|
|
116
|
+
2026-01-27 09:00
|
|
117
|
+
|
|
118
|
+
## Posted
|
|
119
|
+
2026-01-27 09:00
|
|
120
|
+
|
|
121
|
+
## Published
|
|
122
|
+
https://x.com/user/status/123
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
## TUI Keyboard Shortcuts
|
|
126
|
+
|
|
127
|
+
| Key | Drafts Tab | Posts Tab |
|
|
128
|
+
|-----|------------|-----------|
|
|
129
|
+
| \`Tab\` | Switch to Posts | Switch to Drafts |
|
|
130
|
+
| \`↑/↓\` | Navigate items | Navigate items |
|
|
131
|
+
| \`Enter\` | Toggle ready/draft | Add URL |
|
|
132
|
+
| \`Space\` | Move to Posts | Move to Drafts |
|
|
133
|
+
| \`Backspace\` | Delete (drafts only) | — |
|
|
134
|
+
| \`s\` | Toggle schedule view | Toggle schedule view |
|
|
135
|
+
| \`←/→\` | Navigate weeks | Navigate weeks |
|
|
136
|
+
| \`q\` | Quit | Quit |
|
|
137
|
+
|
|
138
|
+
## Working with AI Assistants
|
|
139
|
+
|
|
140
|
+
This project is designed to work with Claude Code and other AI assistants:
|
|
141
|
+
|
|
142
|
+
1. **Use CLI commands** instead of manual file editing
|
|
143
|
+
2. **CLAUDE.md** contains your brand voice and guidelines
|
|
144
|
+
3. **NOSLOP.md** (this file) documents all available commands
|
|
145
|
+
|
|
146
|
+
The AI should use commands like \`noslop new\`, \`noslop ready\`, \`noslop post\`
|
|
147
|
+
instead of directly creating/moving files.
|
|
148
|
+
`;
|
|
149
|
+
/**
|
|
150
|
+
* Template for CLAUDE.md - user-specific brand content
|
|
151
|
+
* This file contains brand voice guidelines for AI assistants
|
|
152
|
+
*/
|
|
153
|
+
export const CLAUDE_TEMPLATE = `# Content Guide
|
|
154
|
+
|
|
155
|
+
> This project uses noslop for content management. See NOSLOP.md for CLI commands.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Brand Voice
|
|
160
|
+
|
|
161
|
+
<!--
|
|
162
|
+
INSTRUCTIONS FOR AI: If this section is empty, interview the user to fill it in.
|
|
163
|
+
Ask about tone, style, what to avoid, platform preferences, etc.
|
|
164
|
+
-->
|
|
165
|
+
|
|
166
|
+
### Tone & Style
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
### Do's
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
### Don'ts
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Platform Guidelines
|
|
178
|
+
|
|
179
|
+
<!-- Which platforms? What's different about each? -->
|
|
180
|
+
|
|
181
|
+
### Twitter/X
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
### Other Platforms
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Key Messaging
|
|
190
|
+
|
|
191
|
+
### Taglines
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
### Key Phrases
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
### Topics to Cover
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Content Examples
|
|
203
|
+
|
|
204
|
+
<!-- Add example posts as you create them -->
|
|
205
|
+
|
|
206
|
+
### Good Examples
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
### Transformations (before → after)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Visual Elements
|
|
215
|
+
|
|
216
|
+
### Emoji Policy
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
### ASCII Art Library
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
`;
|
|
223
|
+
/**
|
|
224
|
+
* Ensure NOSLOP.md documentation file exists and is up-to-date
|
|
225
|
+
* Creates or overwrites NOSLOP.md in the specified directory with
|
|
226
|
+
* the latest tool documentation template.
|
|
227
|
+
* @param cwd - Working directory (defaults to process.cwd())
|
|
228
|
+
*/
|
|
229
|
+
export function ensureNoslopMd(cwd = process.cwd()) {
|
|
230
|
+
const noslopFile = path.join(cwd, 'NOSLOP.md');
|
|
231
|
+
fs.writeFileSync(noslopFile, NOSLOP_TEMPLATE);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Initialize a new noslop project in the specified directory
|
|
235
|
+
* Creates the following structure:
|
|
236
|
+
* - drafts/ directory for work in progress
|
|
237
|
+
* - posts/ directory for published content
|
|
238
|
+
* - CLAUDE.md with brand guidelines template
|
|
239
|
+
* - NOSLOP.md with tool documentation
|
|
240
|
+
*
|
|
241
|
+
* @param cwd - Directory to initialize (defaults to process.cwd())
|
|
242
|
+
* @param projectName - Optional project name for CLAUDE.md header
|
|
243
|
+
*/
|
|
244
|
+
export function initProject(cwd = process.cwd(), projectName) {
|
|
245
|
+
const postsDir = path.join(cwd, 'posts');
|
|
246
|
+
const draftsDir = path.join(cwd, 'drafts');
|
|
247
|
+
const noslopFile = path.join(cwd, 'NOSLOP.md');
|
|
248
|
+
const claudeFile = path.join(cwd, 'CLAUDE.md');
|
|
249
|
+
// Create directories
|
|
250
|
+
if (!fs.existsSync(postsDir)) {
|
|
251
|
+
fs.mkdirSync(postsDir, { recursive: true });
|
|
252
|
+
}
|
|
253
|
+
if (!fs.existsSync(draftsDir)) {
|
|
254
|
+
fs.mkdirSync(draftsDir, { recursive: true });
|
|
255
|
+
}
|
|
256
|
+
// Create NOSLOP.md (tool documentation)
|
|
257
|
+
fs.writeFileSync(noslopFile, NOSLOP_TEMPLATE);
|
|
258
|
+
// Create CLAUDE.md (brand content)
|
|
259
|
+
let claudeContent = CLAUDE_TEMPLATE;
|
|
260
|
+
if (projectName) {
|
|
261
|
+
claudeContent = claudeContent.replace('# Content Guide', `# ${projectName} Content Guide`);
|
|
262
|
+
}
|
|
263
|
+
fs.writeFileSync(claudeFile, claudeContent);
|
|
264
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { ensureNoslopMd, initProject, NOSLOP_TEMPLATE, CLAUDE_TEMPLATE } from './templates.js';
|
|
6
|
+
describe('templates.ts', () => {
|
|
7
|
+
let testDir;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'noslop-templates-'));
|
|
10
|
+
});
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
13
|
+
});
|
|
14
|
+
describe('ensureNoslopMd', () => {
|
|
15
|
+
it('creates NOSLOP.md if it does not exist', () => {
|
|
16
|
+
const noslopPath = path.join(testDir, 'NOSLOP.md');
|
|
17
|
+
expect(fs.existsSync(noslopPath)).toBe(false);
|
|
18
|
+
ensureNoslopMd(testDir);
|
|
19
|
+
expect(fs.existsSync(noslopPath)).toBe(true);
|
|
20
|
+
const content = fs.readFileSync(noslopPath, 'utf-8');
|
|
21
|
+
expect(content).toBe(NOSLOP_TEMPLATE);
|
|
22
|
+
});
|
|
23
|
+
it('overwrites existing NOSLOP.md', () => {
|
|
24
|
+
const noslopPath = path.join(testDir, 'NOSLOP.md');
|
|
25
|
+
fs.writeFileSync(noslopPath, 'old content');
|
|
26
|
+
ensureNoslopMd(testDir);
|
|
27
|
+
const content = fs.readFileSync(noslopPath, 'utf-8');
|
|
28
|
+
expect(content).toBe(NOSLOP_TEMPLATE);
|
|
29
|
+
expect(content).not.toBe('old content');
|
|
30
|
+
});
|
|
31
|
+
it('uses current working directory by default', () => {
|
|
32
|
+
const originalCwd = process.cwd();
|
|
33
|
+
try {
|
|
34
|
+
process.chdir(testDir);
|
|
35
|
+
ensureNoslopMd();
|
|
36
|
+
expect(fs.existsSync(path.join(testDir, 'NOSLOP.md'))).toBe(true);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
process.chdir(originalCwd);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('initProject', () => {
|
|
44
|
+
it('creates drafts directory', () => {
|
|
45
|
+
initProject(testDir);
|
|
46
|
+
expect(fs.existsSync(path.join(testDir, 'drafts'))).toBe(true);
|
|
47
|
+
expect(fs.statSync(path.join(testDir, 'drafts')).isDirectory()).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it('creates posts directory', () => {
|
|
50
|
+
initProject(testDir);
|
|
51
|
+
expect(fs.existsSync(path.join(testDir, 'posts'))).toBe(true);
|
|
52
|
+
expect(fs.statSync(path.join(testDir, 'posts')).isDirectory()).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('creates NOSLOP.md with template content', () => {
|
|
55
|
+
initProject(testDir);
|
|
56
|
+
const noslopPath = path.join(testDir, 'NOSLOP.md');
|
|
57
|
+
expect(fs.existsSync(noslopPath)).toBe(true);
|
|
58
|
+
const content = fs.readFileSync(noslopPath, 'utf-8');
|
|
59
|
+
expect(content).toBe(NOSLOP_TEMPLATE);
|
|
60
|
+
});
|
|
61
|
+
it('creates CLAUDE.md with template content', () => {
|
|
62
|
+
initProject(testDir);
|
|
63
|
+
const claudePath = path.join(testDir, 'CLAUDE.md');
|
|
64
|
+
expect(fs.existsSync(claudePath)).toBe(true);
|
|
65
|
+
const content = fs.readFileSync(claudePath, 'utf-8');
|
|
66
|
+
expect(content).toBe(CLAUDE_TEMPLATE);
|
|
67
|
+
});
|
|
68
|
+
it('uses project name in CLAUDE.md if provided', () => {
|
|
69
|
+
initProject(testDir, 'My Awesome Project');
|
|
70
|
+
const claudePath = path.join(testDir, 'CLAUDE.md');
|
|
71
|
+
const content = fs.readFileSync(claudePath, 'utf-8');
|
|
72
|
+
expect(content).toContain('# My Awesome Project Content Guide');
|
|
73
|
+
expect(content).not.toContain('# Content Guide');
|
|
74
|
+
});
|
|
75
|
+
it('does not overwrite existing directories', () => {
|
|
76
|
+
// Create drafts with a file inside
|
|
77
|
+
const draftsDir = path.join(testDir, 'drafts');
|
|
78
|
+
fs.mkdirSync(draftsDir);
|
|
79
|
+
fs.writeFileSync(path.join(draftsDir, 'existing.txt'), 'existing content');
|
|
80
|
+
initProject(testDir);
|
|
81
|
+
// Verify the existing file is still there
|
|
82
|
+
expect(fs.existsSync(path.join(draftsDir, 'existing.txt'))).toBe(true);
|
|
83
|
+
const content = fs.readFileSync(path.join(draftsDir, 'existing.txt'), 'utf-8');
|
|
84
|
+
expect(content).toBe('existing content');
|
|
85
|
+
});
|
|
86
|
+
it('creates all files in a single call', () => {
|
|
87
|
+
initProject(testDir, 'Test Project');
|
|
88
|
+
// Verify all expected files and directories exist
|
|
89
|
+
expect(fs.existsSync(path.join(testDir, 'drafts'))).toBe(true);
|
|
90
|
+
expect(fs.existsSync(path.join(testDir, 'posts'))).toBe(true);
|
|
91
|
+
expect(fs.existsSync(path.join(testDir, 'NOSLOP.md'))).toBe(true);
|
|
92
|
+
expect(fs.existsSync(path.join(testDir, 'CLAUDE.md'))).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe('templates', () => {
|
|
96
|
+
it('NOSLOP_TEMPLATE contains essential sections', () => {
|
|
97
|
+
expect(NOSLOP_TEMPLATE).toContain('# noslop');
|
|
98
|
+
expect(NOSLOP_TEMPLATE).toContain('## Commands');
|
|
99
|
+
expect(NOSLOP_TEMPLATE).toContain('## Folder Structure');
|
|
100
|
+
expect(NOSLOP_TEMPLATE).toContain('## Post File Format');
|
|
101
|
+
expect(NOSLOP_TEMPLATE).toContain('## TUI Keyboard Shortcuts');
|
|
102
|
+
});
|
|
103
|
+
it('CLAUDE_TEMPLATE contains essential sections', () => {
|
|
104
|
+
expect(CLAUDE_TEMPLATE).toContain('# Content Guide');
|
|
105
|
+
expect(CLAUDE_TEMPLATE).toContain('## Brand Voice');
|
|
106
|
+
expect(CLAUDE_TEMPLATE).toContain('## Platform Guidelines');
|
|
107
|
+
expect(CLAUDE_TEMPLATE).toContain('## Key Messaging');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
package/dist/tui.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderTUI(): void;
|