knowns 0.8.6 → 0.8.7
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 +34 -31
- package/dist/index.js +975 -387
- package/dist/mcp/server.js +399 -54
- package/dist/ui/assets/index-BANrBoru.css +1 -0
- package/dist/ui/assets/{index-VYsw6Uus.js → index-CruKONTP.js} +4 -4
- package/dist/ui/assets/logo-BkDQ9x4a.png +0 -0
- package/dist/ui/index.html +4 -3
- package/dist/ui/logo.png +0 -0
- package/package.json +1 -1
- package/dist/ui/assets/index-CcZnlUm-.css +0 -1
package/dist/index.js
CHANGED
|
@@ -43475,68 +43475,166 @@ import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile2 } from
|
|
|
43475
43475
|
import { dirname, join as join3 } from "node:path";
|
|
43476
43476
|
var import_prompts = __toESM(require_prompts3(), 1);
|
|
43477
43477
|
|
|
43478
|
-
// src/templates/guidelines/
|
|
43479
|
-
var
|
|
43478
|
+
// src/templates/guidelines/cli/commands-reference.md
|
|
43479
|
+
var commands_reference_default = '# Commands Reference\n\n## task create\n\n```bash\nknowns task create <title> [options]\n```\n\n| Flag | Short | Purpose |\n| --------------- | ----- | --------------------------------- |\n| `--description` | `-d` | Task description |\n| `--ac` | | Acceptance criterion (repeatable) |\n| `--labels` | `-l` | Comma-separated labels |\n| `--assignee` | `-a` | Assign to user \u26A0\uFE0F |\n| `--priority` | | low/medium/high |\n| `--status` | `-s` | Initial status |\n| `--parent` | | Parent task ID (raw ID only!) |\n\n**\u26A0\uFE0F `-a` = assignee, NOT acceptance criteria! Use `--ac` for AC.**\n\n---\n\n## task edit\n\n```bash\nknowns task edit <id> [options]\n```\n\n| Flag | Short | Purpose |\n| ---------------- | ----- | ------------------------ |\n| `--title` | `-t` | Change title |\n| `--description` | `-d` | Change description |\n| `--status` | `-s` | Change status |\n| `--priority` | | Change priority |\n| `--labels` | `-l` | Set labels |\n| `--assignee` | `-a` | Assign user \u26A0\uFE0F |\n| `--parent` | | Move to parent |\n| `--ac` | | Add acceptance criterion |\n| `--check-ac` | | Mark AC done (1-indexed) |\n| `--uncheck-ac` | | Unmark AC (1-indexed) |\n| `--remove-ac` | | Delete AC (1-indexed) |\n| `--plan` | | Set implementation plan |\n| `--notes` | | Replace notes |\n| `--append-notes` | | Add to notes |\n\n**\u26A0\uFE0F `-a` = assignee, NOT acceptance criteria! Use `--ac` for AC.**\n\n---\n\n## task view/list\n\n```bash\nknowns task <id> --plain # View single task\nknowns task list --plain # List all\nknowns task list --status in-progress --plain\nknowns task list --assignee @me --plain\nknowns task list --tree --plain # Tree hierarchy\n```\n\n---\n\n## doc create\n\n```bash\nknowns doc create <title> [options]\n```\n\n| Flag | Short | Purpose |\n| --------------- | ----- | -------------------- |\n| `--description` | `-d` | Description |\n| `--tags` | `-t` | Comma-separated tags |\n| `--folder` | `-f` | Folder path |\n\n### Document Structure Best Practice\n\nWhen creating/editing docs, use clear heading structure for `--toc` and `--section` to work properly:\n\n```markdown\n# Main Title (H1 - only one)\n\n## 1. Overview\n\nBrief introduction...\n\n## 2. Installation\n\nStep-by-step guide...\n\n## 3. Configuration\n\n### 3.1 Basic Config\n\n...\n\n### 3.2 Advanced Config\n\n...\n\n## 4. API Reference\n\n...\n```\n\n**Writing rules:**\n\n- Use numbered headings (`## 1. Overview`) for easy `--section "1"` access\n- Keep H1 for title only, use H2 for main sections\n- Use H3 for subsections within H2\n- Each section should be self-contained (readable without context)\n\n**Reading workflow:**\n\n```bash\n# Step 1: Check size first\nknowns doc <path> --info --plain\n# \u2192 If <2000 tokens: read directly with --plain\n# \u2192 If >2000 tokens: continue to step 2\n\n# Step 2: Get table of contents\nknowns doc <path> --toc --plain\n\n# Step 3: Read specific section\nknowns doc <path> --section "2" --plain\n```\n\n---\n\n## doc edit\n\n```bash\nknowns doc edit <name> [options]\n```\n\n| Flag | Short | Purpose |\n| ---------------- | ----- | ----------------------------------------- |\n| `--title` | `-t` | Change title |\n| `--description` | `-d` | Change description |\n| `--tags` | | Set tags |\n| `--content` | `-c` | Replace content (or section if --section) |\n| `--append` | `-a` | Append content \u26A0\uFE0F |\n| `--section` | | Target section to replace (use with -c) |\n| `--content-file` | | Content from file |\n| `--append-file` | | Append from file |\n\n**\u26A0\uFE0F In doc edit, `-a` = append content, NOT assignee!**\n\n### Section Edit (Context-Efficient)\n\nReplace only a specific section instead of entire document:\n\n```bash\n# Step 1: View TOC to find section\nknowns doc readme --toc --plain\n\n# Step 2: Edit only that section\nknowns doc edit readme --section "2. Installation" -c "New content here..."\nknowns doc edit readme --section "2" -c "New content..." # By number works too\n```\n\nThis reduces context usage significantly - no need to read/write entire document.\n\n---\n\n## doc view/list\n\n```bash\nknowns doc <path> --plain # View single doc\nknowns doc list --plain # List all\nknowns doc list --tag api --plain # Filter by tag\n```\n\n### Large Documents (--info, --toc, --section)\n\nFor large documents, check size first with `--info`, then use `--toc` and `--section`:\n\n```bash\n# Step 1: Check document size and token count\nknowns doc readme --info --plain\n# Output: Size: 42,461 chars (~12,132 tokens) | Headings: 83\n# Recommendation: Document is large. Use --toc first, then --section.\n\n# Step 2: View table of contents\nknowns doc readme --toc --plain\n\n# Step 3: Read specific section by title or number\nknowns doc readme --section "5. Sync" --plain\nknowns doc readme --section "3" --plain\n```\n\n**Decision flow:**\n\n- `--info` \u2192 Check size (~tokens) \u2192 If >2000 tokens, use --toc/--section\n- `--toc` \u2192 Get heading list \u2192 Choose section to read\n- `--section` \u2192 Read only what you need\n\n---\n\n## time\n\n```bash\nknowns time start <id> # REQUIRED when taking task\nknowns time stop # REQUIRED when completing\nknowns time pause\nknowns time resume\nknowns time status\nknowns time add <id> <duration> -n "Note" -d "2025-01-01"\n```\n\n---\n\n## search\n\n```bash\nknowns search "query" --plain\nknowns search "auth" --type task --plain\nknowns search "api" --type doc --plain\nknowns search "bug" --type task --status in-progress --priority high --plain\n```\n\n---\n\n## Multi-line Input (Bash/Zsh)\n\n```bash\nknowns task edit <id> --plan $\'1. Step\\n2. Step\\n3. Step\'\n```\n';
|
|
43480
|
+
|
|
43481
|
+
// src/templates/guidelines/cli/common-mistakes.md
|
|
43482
|
+
var common_mistakes_default = '# Common Mistakes\n\n## \u26A0\uFE0F CRITICAL: The -a Flag\n\n| Command | `-a` Means | NOT This! |\n|---------|------------|-----------|\n| `task create/edit` | `--assignee` | ~~acceptance criteria~~ |\n| `doc edit` | `--append` | ~~assignee~~ |\n\n```bash\n# \u274C WRONG (sets assignee to garbage!)\nknowns task edit 35 -a "Criterion text"\n\n# \u2705 CORRECT (use --ac)\nknowns task edit 35 --ac "Criterion text"\n```\n\n---\n\n## Quick Reference\n\n| \u274C DON\'T | \u2705 DO |\n|----------|-------|\n| Edit .md files directly | Use CLI commands |\n| `-a "criterion"` | `--ac "criterion"` |\n| `--parent task-48` | `--parent 48` (raw ID) |\n| `--plain` with create/edit | `--plain` only for view/list |\n| Check AC before work done | Check AC AFTER work done |\n| Code before plan approval | Wait for user approval |\n| Code before reading docs | Read docs FIRST |\n| Skip time tracking | Always `time start`/`stop` |\n| Ignore task refs | Follow ALL `@.knowns/...` refs |\n\n---\n\n## Error Recovery\n\n| Problem | Solution |\n|---------|----------|\n| Set assignee to AC text | `knowns task edit <id> -a @me` |\n| Forgot to stop timer | `knowns time add <id> <duration>` |\n| Checked AC too early | `knowns task edit <id> --uncheck-ac N` |\n| Task not found | `knowns task list --plain` |\n';
|
|
43483
|
+
|
|
43484
|
+
// src/templates/guidelines/cli/context-optimization.md
|
|
43485
|
+
var context_optimization_default = '# Context Optimization\n\nOptimize your context usage to work more efficiently within token limits.\n\n---\n\n## Output Format\n\n```bash\n# \u274C Verbose output\nknowns task 42 --json\n\n# \u2705 Compact output (always use --plain)\nknowns task 42 --plain\n```\n\n---\n\n## Search Before Read\n\n```bash\n# \u274C Reading all docs to find info\nknowns doc "doc1" --plain\nknowns doc "doc2" --plain\nknowns doc "doc3" --plain\n\n# \u2705 Search first, then read only relevant docs\nknowns search "authentication" --type doc --plain\nknowns doc "security-patterns" --plain # Only the relevant one\n```\n\n---\n\n## Selective File Reading\n\n```bash\n# \u274C Reading entire large file\nRead file (2000+ lines)\n\n# \u2705 Read specific sections\nRead file with offset=100 limit=50\n```\n\n---\n\n## Large Documents (--info, --toc, --section)\n\nFor large documents, check size first with `--info`:\n\n```bash\n# \u274C Reading entire large document (may be truncated)\nknowns doc readme --plain\n\n# \u2705 Step 1: Check document size first\nknowns doc readme --info --plain\n# Output: Size: 42,461 chars (~12,132 tokens) | Headings: 83\n\n# \u2705 Step 2: View table of contents (if >2000 tokens)\nknowns doc readme --toc --plain\n\n# \u2705 Step 3: Read only the section you need\nknowns doc readme --section "3. Config" --plain\n```\n\n**Decision flow:** `--info` \u2192 check tokens \u2192 if >2000, use `--toc` then `--section`\n\n---\n\n## Compact Notes\n\n```bash\n# \u274C Verbose notes\nknowns task edit 42 --append-notes "I have successfully completed the implementation of the authentication middleware which validates JWT tokens and handles refresh logic..."\n\n# \u2705 Compact notes\nknowns task edit 42 --append-notes "\u2713 Auth middleware + JWT validation done"\n```\n\n---\n\n## Avoid Redundant Operations\n\n| Don\'t | Do Instead |\n| -------------------------------- | --------------------------- |\n| Re-read files already in context | Reference from memory |\n| List tasks/docs multiple times | List once, remember results |\n| Quote entire file contents | Summarize key points |\n| Repeat full error messages | Reference error briefly |\n\n---\n\n## Efficient Workflow\n\n| Phase | Context-Efficient Approach |\n| -------------- | ------------------------------ |\n| **Research** | Search \u2192 Read only matches |\n| **Planning** | Brief plan, not detailed prose |\n| **Coding** | Read only files being modified |\n| **Notes** | Bullet points, not paragraphs |\n| **Completion** | Summary, not full log |\n\n---\n\n## Quick Rules\n\n1. **Always `--plain`** - Never use `--json` unless specifically needed\n2. **Search first** - Don\'t read all docs hoping to find info\n3. **Read selectively** - Use offset/limit for large files\n4. **Use --info first** - Check doc size before reading, then --toc/--section if needed\n5. **Write concise** - Compact notes, not essays\n6. **Don\'t repeat** - Reference context already loaded\n7. **Summarize** - Key points, not full quotes\n';
|
|
43480
43486
|
|
|
43481
|
-
// src/templates/guidelines/
|
|
43482
|
-
var
|
|
43487
|
+
// src/templates/guidelines/cli/core-rules.md
|
|
43488
|
+
var core_rules_default = '# Core Rules\n\nYou MUST follow these rules. If you cannot follow any rule, stop and ask for guidance before proceeding.\n\n---\n\n## \u{1F3AF} The Golden Rule\n\n**If you want to change ANYTHING in a task or doc, use CLI commands or MCP tools. NEVER edit .md files directly.**\n\nWhy? Direct file editing breaks metadata synchronization, Git tracking, and relationships.\n\n---\n\n## \u26A0\uFE0F CRITICAL: The -a Flag Confusion\n\nThe `-a` flag means DIFFERENT things in different commands:\n\n| Command | `-a` Means | NOT This! |\n|---------|------------|-----------|\n| `task create` | `--assignee` (assign user) | ~~acceptance criteria~~ |\n| `task edit` | `--assignee` (assign user) | ~~acceptance criteria~~ |\n| `doc edit` | `--append` (append content) | ~~assignee~~ |\n\n### Acceptance Criteria: Use --ac\n\n```bash\n# \u274C WRONG: -a is assignee, NOT acceptance criteria!\nknowns task edit 35 -a "- [ ] Criterion" # Sets assignee to garbage!\nknowns task create "Title" -a "Criterion" # Sets assignee to garbage!\n\n# \u2705 CORRECT: Use --ac for acceptance criteria\nknowns task edit 35 --ac "Criterion one"\nknowns task edit 35 --ac "Criterion two"\nknowns task create "Title" --ac "Criterion one" --ac "Criterion two"\n```\n\n---\n\n## Core Principles\n\n| Rule | Description |\n|------|-------------|\n| **CLI/MCP Only** | Use commands for ALL operations. NEVER edit .md files directly |\n| **Docs First** | Read project docs BEFORE planning or coding |\n| **Time Tracking** | Always start timer when taking task, stop when done |\n| **Plan Approval** | Share plan with user, WAIT for approval before coding |\n| **Check AC After Work** | Only mark acceptance criteria done AFTER completing the work |\n\n---\n\n## The --plain Flag\n\n**ONLY for view/list/search commands (NOT create/edit):**\n\n```bash\n# \u2705 CORRECT\nknowns task <id> --plain\nknowns task list --plain\nknowns doc "path" --plain\nknowns doc list --plain\nknowns search "query" --plain\n\n# \u274C WRONG (create/edit don\'t support --plain)\nknowns task create "Title" --plain # ERROR!\nknowns task edit <id> -s done --plain # ERROR!\nknowns doc create "Title" --plain # ERROR!\nknowns doc edit "name" -c "..." --plain # ERROR!\n```\n\n---\n\n## Reference System\n\n| Context | Task Format | Doc Format |\n|---------|-------------|------------|\n| **Writing** (input) | `@task-<id>` | `@doc/<path>` |\n| **Reading** (output) | `@.knowns/tasks/task-<id>` | `@.knowns/docs/<path>.md` |\n\nFollow refs recursively until complete context gathered.\n\n---\n\n## Task IDs\n\n| Format | Example | Notes |\n|--------|---------|-------|\n| Sequential | `48`, `49` | Legacy numeric |\n| Hierarchical | `48.1`, `48.2` | Legacy subtasks |\n| Random | `qkh5ne` | Current (6-char) |\n\n**CRITICAL:** Use raw ID for `--parent`:\n```bash\n# \u2705 CORRECT\nknowns task create "Title" --parent 48\n\n# \u274C WRONG\nknowns task create "Title" --parent task-48\n```\n\n---\n\n## Status & Priority\n\n| Status | When |\n|--------|------|\n| `todo` | Not started (default) |\n| `in-progress` | Currently working |\n| `in-review` | PR submitted |\n| `blocked` | Waiting on dependency |\n| `done` | All criteria met |\n\n| Priority | Level |\n|----------|-------|\n| `low` | Nice-to-have |\n| `medium` | Normal (default) |\n| `high` | Urgent |\n';
|
|
43483
43489
|
|
|
43484
|
-
// src/templates/guidelines/workflow-completion.md
|
|
43490
|
+
// src/templates/guidelines/cli/workflow-completion.md
|
|
43485
43491
|
var workflow_completion_default = '# Task Completion\n\n## Definition of Done\n\nA task is **Done** when ALL of these are complete:\n\n| Requirement | Command |\n|-------------|---------|\n| All AC checked | `knowns task edit <id> --check-ac N` |\n| Notes added | `knowns task edit <id> --notes "Summary"` |\n| Timer stopped | `knowns time stop` |\n| Status = done | `knowns task edit <id> -s done` |\n| Tests pass | Run test suite |\n\n---\n\n## Completion Steps\n\n```bash\n# 1. Verify all AC are checked\nknowns task <id> --plain\n\n# 2. Add implementation notes\nknowns task edit <id> --notes $\'## Summary\nWhat was done and key decisions.\'\n\n# 3. Stop timer (REQUIRED!)\nknowns time stop\n\n# 4. Mark done\nknowns task edit <id> -s done\n```\n\n---\n\n## Post-Completion Changes\n\nIf user requests changes after task is done:\n\n```bash\nknowns task edit <id> -s in-progress # Reopen\nknowns time start <id> # Restart timer\nknowns task edit <id> --ac "Fix: description"\nknowns task edit <id> --append-notes "\u{1F504} Reopened: reason"\n# Complete work, then follow completion steps again\n```\n\n---\n\n## Checklist\n\n- [ ] All AC checked (`--check-ac`)\n- [ ] Notes added (`--notes`)\n- [ ] Timer stopped (`time stop`)\n- [ ] Tests pass\n- [ ] Status = done (`-s done`)\n';
|
|
43486
43492
|
|
|
43487
|
-
// src/templates/guidelines/workflow-creation.md
|
|
43493
|
+
// src/templates/guidelines/cli/workflow-creation.md
|
|
43488
43494
|
var workflow_creation_default = '# Task Creation\n\n## Before Creating\n\n```bash\n# Search for existing tasks first\nknowns search "keyword" --type task --plain\n```\n\n---\n\n## Create Task\n\n```bash\nknowns task create "Clear title (WHAT)" \\\n -d "Description (WHY)" \\\n --ac "Outcome 1" \\\n --ac "Outcome 2" \\\n --priority medium \\\n -l "labels"\n```\n\n---\n\n## Quality Guidelines\n\n### Title\n| \u274C Bad | \u2705 Good |\n|--------|---------|\n| Do auth stuff | Add JWT authentication |\n| Fix bug | Fix login timeout |\n\n### Description\nExplain WHY. Include doc refs: `@doc/security-patterns`\n\n### Acceptance Criteria\n**Outcome-focused, NOT implementation steps:**\n\n| \u274C Bad | \u2705 Good |\n|--------|---------|\n| Add handleLogin() function | User can login |\n| Use bcrypt | Passwords are hashed |\n| Add try-catch | Errors return proper HTTP codes |\n\n---\n\n## Subtasks\n\n```bash\nknowns task create "Parent task"\nknowns task create "Subtask" --parent 48 # Raw ID only!\n```\n\n---\n\n## Anti-Patterns\n\n- \u274C Too many AC in one task \u2192 Split into multiple tasks\n- \u274C Implementation steps as AC \u2192 Write outcomes instead\n- \u274C Skip search \u2192 Always check existing tasks first\n';
|
|
43489
43495
|
|
|
43490
|
-
// src/templates/guidelines/workflow-execution.md
|
|
43496
|
+
// src/templates/guidelines/cli/workflow-execution.md
|
|
43491
43497
|
var workflow_execution_default = '# Task Execution\n\n## Step 1: Take Task\n\n```bash\nknowns task edit <id> -s in-progress -a @me\nknowns time start <id> # REQUIRED!\n```\n\n---\n\n## Step 2: Research\n\n```bash\n# Read task and follow ALL refs\nknowns task <id> --plain\n# @.knowns/docs/xxx.md \u2192 knowns doc "xxx" --plain\n# @.knowns/tasks/task-YY \u2192 knowns task YY --plain\n\n# Search related docs\nknowns search "keyword" --type doc --plain\n\n# Check similar done tasks\nknowns search "keyword" --type task --status done --plain\n```\n\n---\n\n## Step 3: Plan (BEFORE coding!)\n\n```bash\nknowns task edit <id> --plan $\'1. Research (see @doc/xxx)\n2. Implement\n3. Test\n4. Document\'\n```\n\n**\u26A0\uFE0F Share plan with user. WAIT for approval before coding.**\n\n---\n\n## Step 4: Implement\n\n```bash\n# Check AC only AFTER work is done\nknowns task edit <id> --check-ac 1\nknowns task edit <id> --append-notes "\u2713 Done: feature X"\n```\n\n---\n\n## Scope Changes\n\nIf new requirements emerge during work:\n\n```bash\n# Small: Add to current task\nknowns task edit <id> --ac "New requirement"\nknowns task edit <id> --append-notes "\u26A0\uFE0F Scope updated: reason"\n\n# Large: Ask user first, then create follow-up\nknowns task create "Follow-up: feature" -d "From task <id>"\n```\n\n**\u26A0\uFE0F Don\'t silently expand scope. Ask user first.**\n\n---\n\n## Key Rules\n\n1. **Plan before code** - Capture approach first\n2. **Wait for approval** - Don\'t start without OK\n3. **Check AC after work** - Not before\n4. **Ask on scope changes** - Don\'t expand silently\n';
|
|
43492
43498
|
|
|
43493
|
-
// src/templates/guidelines/
|
|
43494
|
-
var
|
|
43499
|
+
// src/templates/guidelines/cli/index.ts
|
|
43500
|
+
var CLI_CORE_RULES = core_rules_default.trim();
|
|
43501
|
+
var CLI_COMMANDS_REFERENCE = commands_reference_default.trim();
|
|
43502
|
+
var CLI_WORKFLOW_CREATION = workflow_creation_default.trim();
|
|
43503
|
+
var CLI_WORKFLOW_EXECUTION = workflow_execution_default.trim();
|
|
43504
|
+
var CLI_WORKFLOW_COMPLETION = workflow_completion_default.trim();
|
|
43505
|
+
var CLI_COMMON_MISTAKES = common_mistakes_default.trim();
|
|
43506
|
+
var CLI_CONTEXT_OPTIMIZATION = context_optimization_default.trim();
|
|
43507
|
+
var CLIGuidelines = {
|
|
43508
|
+
// Core rules - always needed
|
|
43509
|
+
core: CLI_CORE_RULES,
|
|
43510
|
+
// Commands reference
|
|
43511
|
+
commands: CLI_COMMANDS_REFERENCE,
|
|
43512
|
+
// Workflow stages
|
|
43513
|
+
workflow: {
|
|
43514
|
+
creation: CLI_WORKFLOW_CREATION,
|
|
43515
|
+
execution: CLI_WORKFLOW_EXECUTION,
|
|
43516
|
+
completion: CLI_WORKFLOW_COMPLETION
|
|
43517
|
+
},
|
|
43518
|
+
// Common mistakes
|
|
43519
|
+
mistakes: CLI_COMMON_MISTAKES,
|
|
43520
|
+
// Context optimization
|
|
43521
|
+
contextOptimization: CLI_CONTEXT_OPTIMIZATION,
|
|
43522
|
+
/**
|
|
43523
|
+
* Get full CLI guidelines (all sections combined)
|
|
43524
|
+
*/
|
|
43525
|
+
getFull(withMarkers2 = false) {
|
|
43526
|
+
const content = [
|
|
43527
|
+
CLI_CORE_RULES,
|
|
43528
|
+
"---",
|
|
43529
|
+
CLI_CONTEXT_OPTIMIZATION,
|
|
43530
|
+
"---",
|
|
43531
|
+
CLI_COMMANDS_REFERENCE,
|
|
43532
|
+
"---",
|
|
43533
|
+
CLI_WORKFLOW_CREATION,
|
|
43534
|
+
"---",
|
|
43535
|
+
CLI_WORKFLOW_EXECUTION,
|
|
43536
|
+
"---",
|
|
43537
|
+
CLI_WORKFLOW_COMPLETION,
|
|
43538
|
+
"---",
|
|
43539
|
+
CLI_COMMON_MISTAKES
|
|
43540
|
+
].join("\n\n");
|
|
43541
|
+
if (withMarkers2) {
|
|
43542
|
+
return `<!-- KNOWNS GUIDELINES START -->
|
|
43543
|
+
${content}
|
|
43544
|
+
<!-- KNOWNS GUIDELINES END -->`;
|
|
43545
|
+
}
|
|
43546
|
+
return content;
|
|
43547
|
+
},
|
|
43548
|
+
/**
|
|
43549
|
+
* Get compact CLI guidelines (core + context optimization + mistakes only)
|
|
43550
|
+
*/
|
|
43551
|
+
getCompact() {
|
|
43552
|
+
return [CLI_CORE_RULES, "---", CLI_CONTEXT_OPTIMIZATION, "---", CLI_COMMON_MISTAKES].join("\n\n");
|
|
43553
|
+
},
|
|
43554
|
+
/**
|
|
43555
|
+
* Get CLI guidelines for specific workflow stage
|
|
43556
|
+
*/
|
|
43557
|
+
getForStage(stage) {
|
|
43558
|
+
const sections = [CLI_CORE_RULES, "---", CLI_CONTEXT_OPTIMIZATION, "---"];
|
|
43559
|
+
switch (stage) {
|
|
43560
|
+
case "creation":
|
|
43561
|
+
sections.push(CLI_WORKFLOW_CREATION);
|
|
43562
|
+
break;
|
|
43563
|
+
case "execution":
|
|
43564
|
+
sections.push(CLI_WORKFLOW_EXECUTION);
|
|
43565
|
+
sections.push("---", CLI_COMMANDS_REFERENCE);
|
|
43566
|
+
break;
|
|
43567
|
+
case "completion":
|
|
43568
|
+
sections.push(CLI_WORKFLOW_COMPLETION);
|
|
43569
|
+
break;
|
|
43570
|
+
}
|
|
43571
|
+
sections.push("---", CLI_COMMON_MISTAKES);
|
|
43572
|
+
return sections.join("\n\n");
|
|
43573
|
+
}
|
|
43574
|
+
};
|
|
43495
43575
|
|
|
43496
|
-
// src/templates/guidelines/
|
|
43497
|
-
var
|
|
43576
|
+
// src/templates/guidelines/mcp/commands-reference.md
|
|
43577
|
+
var commands_reference_default2 = '# MCP Tools Reference\n\n## mcp**knowns**create_task\n\nCreate a new task.\n\n```json\n{\n "title": "Task title",\n "description": "Task description",\n "status": "todo",\n "priority": "medium",\n "labels": ["label1", "label2"],\n "assignee": "@me",\n "parent": "parent-task-id"\n}\n```\n\n| Parameter | Required | Description |\n| ------------- | -------- | --------------------------------------- |\n| `title` | Yes | Task title |\n| `description` | No | Task description |\n| `status` | No | todo/in-progress/in-review/blocked/done |\n| `priority` | No | low/medium/high |\n| `labels` | No | Array of labels |\n| `assignee` | No | Assignee (use @me for self) |\n| `parent` | No | Parent task ID for subtasks |\n\n**Note:** Acceptance criteria must be added via `mcp__knowns__update_task` after creation.\n\n---\n\n## mcp**knowns**update_task\n\nUpdate task fields.\n\n```json\n{\n "taskId": "abc123",\n "title": "New title",\n "description": "New description",\n "status": "in-progress",\n "priority": "high",\n "labels": ["updated"],\n "assignee": "@me"\n}\n```\n\n| Parameter | Required | Description |\n| ------------- | -------- | ----------------- |\n| `taskId` | Yes | Task ID to update |\n| `title` | No | New title |\n| `description` | No | New description |\n| `status` | No | New status |\n| `priority` | No | New priority |\n| `labels` | No | New labels array |\n| `assignee` | No | New assignee |\n\n**Note:** For acceptance criteria, implementation plan, and notes - use CLI commands or edit task file directly through knowns CLI.\n\n---\n\n## mcp**knowns**get_task\n\nGet a task by ID.\n\n```json\n{\n "taskId": "abc123"\n}\n```\n\n---\n\n## mcp**knowns**list_tasks\n\nList tasks with optional filters.\n\n```json\n{\n "status": "in-progress",\n "priority": "high",\n "assignee": "@me",\n "label": "bug"\n}\n```\n\nAll parameters are optional filters.\n\n---\n\n## mcp**knowns**search_tasks\n\nSearch tasks by query string.\n\n```json\n{\n "query": "authentication"\n}\n```\n\n---\n\n## mcp**knowns**get_doc\n\nGet a documentation file by path.\n\n```json\n{\n "path": "README"\n}\n```\n\nPath can be filename or folder/filename (without .md extension).\n\n### Large Documents (info, toc, section)\n\nFor large documents, check size first with `info`, then use `toc` and `section`:\n\n```json\n// Step 1: Check document size and token count\n{\n "path": "readme",\n "info": true\n}\n// Response: { stats: { chars: 42461, estimatedTokens: 12132, headingCount: 83 }, recommendation: "..." }\n\n// Step 2: Get table of contents\n{\n "path": "readme",\n "toc": true\n}\n\n// Step 3: Read specific section by title or number\n{\n "path": "readme",\n "section": "5. Sync"\n}\n```\n\n| Parameter | Description |\n| --------- | -------------------------------------------------------- |\n| `info` | Set `true` to get stats (size, tokens, headings) only |\n| `toc` | Set `true` to get table of contents only |\n| `section` | Section title or number to read (e.g., "5. Sync" or "3") |\n\n**Decision flow:**\n\n- `info: true` \u2192 Check estimatedTokens \u2192 If >2000, use toc/section\n- `toc: true` \u2192 Get heading list \u2192 Choose section to read\n- `section: "X"` \u2192 Read only what you need\n\n---\n\n## mcp**knowns**list_docs\n\nList all documentation files.\n\n```json\n{\n "tag": "api"\n}\n```\n\nOptional `tag` parameter to filter by tag.\n\n---\n\n## mcp**knowns**create_doc\n\nCreate a new documentation file.\n\n```json\n{\n "title": "Doc Title",\n "description": "Doc description",\n "tags": ["tag1", "tag2"],\n "folder": "guides",\n "content": "Initial content"\n}\n```\n\n### Document Structure Best Practice\n\nWhen creating/updating docs, use clear heading structure for `toc` and `section` to work properly:\n\n```markdown\n# Main Title (H1 - only one)\n\n## 1. Overview\n\nBrief introduction...\n\n## 2. Installation\n\nStep-by-step guide...\n\n## 3. Configuration\n\n### 3.1 Basic Config\n\n...\n\n### 3.2 Advanced Config\n\n...\n\n## 4. API Reference\n\n...\n```\n\n**Writing rules:**\n\n- Use numbered headings (`## 1. Overview`) for easy `section: "1"` access\n- Keep H1 for title only, use H2 for main sections\n- Use H3 for subsections within H2\n- Each section should be self-contained (readable without context)\n\n**Reading workflow:**\n\n```json\n// Step 1: Check size first\n{ "path": "<path>", "info": true }\n// \u2192 If estimatedTokens <2000: read directly (no options)\n// \u2192 If estimatedTokens >2000: continue to step 2\n\n// Step 2: Get table of contents\n{ "path": "<path>", "toc": true }\n\n// Step 3: Read specific section\n{ "path": "<path>", "section": "2" }\n```\n\n---\n\n## mcp**knowns**update_doc\n\nUpdate an existing documentation file.\n\n```json\n{\n "path": "README",\n "title": "New Title",\n "description": "New description",\n "tags": ["new", "tags"],\n "content": "Replace content",\n "appendContent": "Append to existing"\n}\n```\n\nUse either `content` (replace) or `appendContent` (append), not both.\n\n### Section Edit (Context-Efficient)\n\nReplace only a specific section instead of entire document:\n\n```json\n// Step 1: View TOC to find section\n{ "path": "readme", "toc": true }\n\n// Step 2: Edit only that section\n{\n "path": "readme",\n "section": "2. Installation",\n "content": "New content here..."\n}\n```\n\nThis reduces context usage significantly - no need to read/write entire document.\n\n---\n\n## mcp**knowns**search_docs\n\nSearch documentation by query.\n\n```json\n{\n "query": "authentication",\n "tag": "api"\n}\n```\n\n---\n\n## mcp**knowns**start_time\n\nStart time tracking for a task.\n\n```json\n{\n "taskId": "abc123"\n}\n```\n\n---\n\n## mcp**knowns**stop_time\n\nStop time tracking.\n\n```json\n{\n "taskId": "abc123"\n}\n```\n\n---\n\n## mcp**knowns**add_time\n\nManually add a time entry.\n\n```json\n{\n "taskId": "abc123",\n "duration": "2h30m",\n "note": "Optional note",\n "date": "2025-01-15"\n}\n```\n\n---\n\n## mcp**knowns**get_time_report\n\nGet time tracking report.\n\n```json\n{\n "from": "2025-01-01",\n "to": "2025-01-31",\n "groupBy": "task"\n}\n```\n\n`groupBy` can be: task, label, or status.\n\n---\n\n## mcp**knowns**get_board\n\nGet current board state with tasks grouped by status.\n\n```json\n{}\n```\n\nNo parameters required.\n';
|
|
43498
43578
|
|
|
43499
|
-
// src/templates/guidelines/
|
|
43500
|
-
var
|
|
43501
|
-
|
|
43502
|
-
|
|
43503
|
-
var
|
|
43504
|
-
|
|
43505
|
-
|
|
43506
|
-
var
|
|
43507
|
-
|
|
43579
|
+
// src/templates/guidelines/mcp/common-mistakes.md
|
|
43580
|
+
var common_mistakes_default2 = "# Common Mistakes (MCP)\n\n## Quick Reference\n\n| DON'T | DO |\n|-------|-----|\n| Edit .md files directly | Use MCP tools |\n| Skip time tracking | Always `start_time`/`stop_time` |\n| Check AC before work done | Check AC AFTER work done |\n| Code before plan approval | Wait for user approval |\n| Code before reading docs | Read docs FIRST |\n| Ignore task refs | Follow ALL `@.knowns/...` refs |\n| Use wrong task ID format | Use raw ID string |\n\n---\n\n## MCP vs CLI Usage\n\nSome operations require CLI (not available in MCP):\n\n| Operation | Tool |\n|-----------|------|\n| Add acceptance criteria | CLI: `--ac` |\n| Check/uncheck AC | CLI: `--check-ac`, `--uncheck-ac` |\n| Set implementation plan | CLI: `--plan` |\n| Add/append notes | CLI: `--notes`, `--append-notes` |\n| Create/update task basic fields | MCP tools |\n| Time tracking | MCP tools |\n| Read tasks/docs | MCP tools |\n| Search | MCP tools |\n\n---\n\n## Error Recovery\n\n| Problem | Solution |\n|---------|----------|\n| Forgot to stop timer | `mcp__knowns__add_time` with duration |\n| Wrong status | `mcp__knowns__update_task` to fix |\n| Task not found | `mcp__knowns__list_tasks` to find ID |\n| Need to uncheck AC | CLI: `knowns task edit <id> --uncheck-ac N` |\n";
|
|
43581
|
+
|
|
43582
|
+
// src/templates/guidelines/mcp/context-optimization.md
|
|
43583
|
+
var context_optimization_default2 = '# Context Optimization (MCP)\n\nOptimize your context usage to work more efficiently within token limits.\n\n---\n\n## Search Before Read\n\n```json\n// DON\'T: Read all docs hoping to find info\nmcp__knowns__get_doc({ "path": "doc1" })\nmcp__knowns__get_doc({ "path": "doc2" })\nmcp__knowns__get_doc({ "path": "doc3" })\n\n// DO: Search first, then read only relevant docs\nmcp__knowns__search_docs({ "query": "authentication" })\nmcp__knowns__get_doc({ "path": "security-patterns" }) // Only the relevant one\n```\n\n---\n\n## Use Filters\n\n```json\n// DON\'T: List all tasks then filter manually\nmcp__knowns__list_tasks({})\n\n// DO: Use filters in the query\nmcp__knowns__list_tasks({\n "status": "in-progress",\n "assignee": "@me"\n})\n```\n\n---\n\n## Large Documents (info, toc, section)\n\nFor large documents, check size first with `info`:\n\n```json\n// DON\'T: Read entire large document (may be truncated)\nmcp__knowns__get_doc({ "path": "readme" })\n\n// DO: Step 1 - Check document size first\nmcp__knowns__get_doc({ "path": "readme", "info": true })\n// Response: { stats: { estimatedTokens: 12132 }, recommendation: "..." }\n\n// DO: Step 2 - Get table of contents (if >2000 tokens)\nmcp__knowns__get_doc({ "path": "readme", "toc": true })\n\n// DO: Step 3 - Read only the section you need\nmcp__knowns__get_doc({ "path": "readme", "section": "3. Config" })\n```\n\n**Decision flow:** `info: true` \u2192 check tokens \u2192 if >2000, use `toc` then `section`\n\n---\n\n## Compact Notes\n\n```bash\n# DON\'T: Verbose notes\nknowns task edit 42 --append-notes "I have successfully completed the implementation..."\n\n# DO: Compact notes\nknowns task edit 42 --append-notes "Done: Auth middleware + JWT validation"\n```\n\n---\n\n## Avoid Redundant Operations\n\n| Don\'t | Do Instead |\n| ------------------------------------- | --------------------------- |\n| Re-read tasks/docs already in context | Reference from memory |\n| List tasks/docs multiple times | List once, remember results |\n| Fetch same task repeatedly | Cache the result |\n\n---\n\n## Efficient Workflow\n\n| Phase | Context-Efficient Approach |\n| -------------- | ------------------------------ |\n| **Research** | Search -> Read only matches |\n| **Planning** | Brief plan, not detailed prose |\n| **Coding** | Read only files being modified |\n| **Notes** | Bullet points, not paragraphs |\n| **Completion** | Summary, not full log |\n\n---\n\n## Quick Rules\n\n1. **Search first** - Don\'t read all docs hoping to find info\n2. **Use filters** - Don\'t list everything then filter manually\n3. **Read selectively** - Only fetch what you need\n4. **Use info first** - Check doc size before reading, then toc/section if needed\n5. **Write concise** - Compact notes, not essays\n6. **Don\'t repeat** - Reference context already loaded\n7. **Summarize** - Key points, not full quotes\n';
|
|
43584
|
+
|
|
43585
|
+
// src/templates/guidelines/mcp/core-rules.md
|
|
43586
|
+
var core_rules_default2 = "# Core Rules (MCP)\n\nYou MUST follow these rules. If you cannot follow any rule, stop and ask for guidance before proceeding.\n\n---\n\n## The Golden Rule\n\n**If you want to change ANYTHING in a task or doc, use MCP tools. NEVER edit .md files directly.**\n\nWhy? Direct file editing breaks metadata synchronization, Git tracking, and relationships.\n\n---\n\n## Core Principles\n\n| Rule | Description |\n|------|-------------|\n| **MCP Tools Only** | Use MCP tools for ALL operations. NEVER edit .md files directly |\n| **Docs First** | Read project docs BEFORE planning or coding |\n| **Time Tracking** | Always start timer when taking task, stop when done |\n| **Plan Approval** | Share plan with user, WAIT for approval before coding |\n| **Check AC After Work** | Only mark acceptance criteria done AFTER completing the work |\n\n---\n\n## Reference System\n\n| Context | Task Format | Doc Format |\n|---------|-------------|------------|\n| **Writing** (input) | `@task-<id>` | `@doc/<path>` |\n| **Reading** (output) | `@.knowns/tasks/task-<id>` | `@.knowns/docs/<path>.md` |\n\nFollow refs recursively until complete context gathered.\n\n---\n\n## Task IDs\n\n| Format | Example | Notes |\n|--------|---------|-------|\n| Sequential | `48`, `49` | Legacy numeric |\n| Hierarchical | `48.1`, `48.2` | Legacy subtasks |\n| Random | `qkh5ne` | Current (6-char) |\n\n**CRITICAL:** Use raw ID (string) for all MCP tool calls.\n\n---\n\n## Status & Priority\n\n| Status | When |\n|--------|------|\n| `todo` | Not started (default) |\n| `in-progress` | Currently working |\n| `in-review` | PR submitted |\n| `blocked` | Waiting on dependency |\n| `done` | All criteria met |\n\n| Priority | Level |\n|----------|-------|\n| `low` | Nice-to-have |\n| `medium` | Normal (default) |\n| `high` | Urgent |\n";
|
|
43587
|
+
|
|
43588
|
+
// src/templates/guidelines/mcp/workflow-completion.md
|
|
43589
|
+
var workflow_completion_default2 = '# Task Completion (MCP)\n\n## Definition of Done\n\nA task is **Done** when ALL of these are complete:\n\n| Requirement | How |\n|-------------|-----|\n| All AC checked | CLI: `knowns task edit <id> --check-ac N` |\n| Notes added | CLI: `knowns task edit <id> --notes "Summary"` |\n| Timer stopped | MCP: `mcp__knowns__stop_time` |\n| Status = done | MCP: `mcp__knowns__update_task` |\n| Tests pass | Run test suite |\n\n---\n\n## Completion Steps\n\n```json\n// 1. Verify all AC are checked\nmcp__knowns__get_task({ "taskId": "abc123" })\n```\n\n```bash\n# 2. Add implementation notes (use CLI)\nknowns task edit abc123 --notes $\'## Summary\nWhat was done and key decisions.\'\n```\n\n```json\n// 3. Stop timer (REQUIRED!)\nmcp__knowns__stop_time({ "taskId": "abc123" })\n\n// 4. Mark done\nmcp__knowns__update_task({\n "taskId": "abc123",\n "status": "done"\n})\n```\n\n---\n\n## Post-Completion Changes\n\nIf user requests changes after task is done:\n\n```json\n// 1. Reopen task\nmcp__knowns__update_task({\n "taskId": "abc123",\n "status": "in-progress"\n})\n\n// 2. Restart timer\nmcp__knowns__start_time({ "taskId": "abc123" })\n```\n\n```bash\n# 3. Add AC for the fix\nknowns task edit abc123 --ac "Fix: description"\nknowns task edit abc123 --append-notes "Reopened: reason"\n```\n\nThen follow completion steps again.\n\n---\n\n## Checklist\n\n- [ ] All AC checked (CLI `--check-ac`)\n- [ ] Notes added (CLI `--notes`)\n- [ ] Timer stopped (`mcp__knowns__stop_time`)\n- [ ] Tests pass\n- [ ] Status = done (`mcp__knowns__update_task`)\n';
|
|
43590
|
+
|
|
43591
|
+
// src/templates/guidelines/mcp/workflow-creation.md
|
|
43592
|
+
var workflow_creation_default2 = '# Task Creation (MCP)\n\n## Before Creating\n\n```json\n// Search for existing tasks first\nmcp__knowns__search_tasks({ "query": "keyword" })\n```\n\n---\n\n## Create Task\n\n```json\nmcp__knowns__create_task({\n "title": "Clear title (WHAT)",\n "description": "Description (WHY). Related: @doc/security-patterns",\n "priority": "medium",\n "labels": ["feature", "auth"]\n})\n```\n\n**Note:** Add acceptance criteria after creation using CLI:\n```bash\nknowns task edit <id> --ac "Outcome 1" --ac "Outcome 2"\n```\n\n---\n\n## Quality Guidelines\n\n### Title\n| Bad | Good |\n|-----|------|\n| Do auth stuff | Add JWT authentication |\n| Fix bug | Fix login timeout |\n\n### Description\nExplain WHY. Include doc refs: `@doc/security-patterns`\n\n### Acceptance Criteria\n**Outcome-focused, NOT implementation steps:**\n\n| Bad | Good |\n|-----|------|\n| Add handleLogin() function | User can login |\n| Use bcrypt | Passwords are hashed |\n| Add try-catch | Errors return proper HTTP codes |\n\n---\n\n## Subtasks\n\n```json\n// Create parent first\nmcp__knowns__create_task({ "title": "Parent task" })\n\n// Then create subtask with parent ID\nmcp__knowns__create_task({\n "title": "Subtask",\n "parent": "parent-task-id"\n})\n```\n\n---\n\n## Anti-Patterns\n\n- Too many AC in one task -> Split into multiple tasks\n- Implementation steps as AC -> Write outcomes instead\n- Skip search -> Always check existing tasks first\n';
|
|
43593
|
+
|
|
43594
|
+
// src/templates/guidelines/mcp/workflow-execution.md
|
|
43595
|
+
var workflow_execution_default2 = '# Task Execution (MCP)\n\n## Step 1: Take Task\n\n```json\n// Update status and assignee\nmcp__knowns__update_task({\n "taskId": "abc123",\n "status": "in-progress",\n "assignee": "@me"\n})\n\n// Start timer (REQUIRED!)\nmcp__knowns__start_time({ "taskId": "abc123" })\n```\n\n---\n\n## Step 2: Research\n\n```json\n// Read task and follow ALL refs\nmcp__knowns__get_task({ "taskId": "abc123" })\n\n// @.knowns/docs/xxx.md -> read the doc\nmcp__knowns__get_doc({ "path": "xxx" })\n\n// @.knowns/tasks/task-YY -> read the task\nmcp__knowns__get_task({ "taskId": "YY" })\n\n// Search related docs\nmcp__knowns__search_docs({ "query": "keyword" })\n\n// Check similar done tasks\nmcp__knowns__list_tasks({ "status": "done" })\n```\n\n---\n\n## Step 3: Plan (BEFORE coding!)\n\nUse CLI for implementation plan:\n```bash\nknowns task edit <id> --plan $\'1. Research (see @doc/xxx)\n2. Implement\n3. Test\n4. Document\'\n```\n\n**Share plan with user. WAIT for approval before coding.**\n\n---\n\n## Step 4: Implement\n\nUse CLI for checking acceptance criteria:\n```bash\n# Check AC only AFTER work is done\nknowns task edit <id> --check-ac 1\nknowns task edit <id> --append-notes "Done: feature X"\n```\n\n---\n\n## Scope Changes\n\nIf new requirements emerge during work:\n\n```bash\n# Small: Add to current task\nknowns task edit <id> --ac "New requirement"\nknowns task edit <id> --append-notes "Scope updated: reason"\n\n# Large: Ask user first, then create follow-up\n```\n\n```json\nmcp__knowns__create_task({\n "title": "Follow-up: feature",\n "description": "From task <id>"\n})\n```\n\n**Don\'t silently expand scope. Ask user first.**\n\n---\n\n## Key Rules\n\n1. **Plan before code** - Capture approach first\n2. **Wait for approval** - Don\'t start without OK\n3. **Check AC after work** - Not before\n4. **Ask on scope changes** - Don\'t expand silently\n';
|
|
43596
|
+
|
|
43597
|
+
// src/templates/guidelines/mcp/index.ts
|
|
43598
|
+
var MCP_CORE_RULES = core_rules_default2.trim();
|
|
43599
|
+
var MCP_COMMANDS_REFERENCE = commands_reference_default2.trim();
|
|
43600
|
+
var MCP_WORKFLOW_CREATION = workflow_creation_default2.trim();
|
|
43601
|
+
var MCP_WORKFLOW_EXECUTION = workflow_execution_default2.trim();
|
|
43602
|
+
var MCP_WORKFLOW_COMPLETION = workflow_completion_default2.trim();
|
|
43603
|
+
var MCP_COMMON_MISTAKES = common_mistakes_default2.trim();
|
|
43604
|
+
var MCP_CONTEXT_OPTIMIZATION = context_optimization_default2.trim();
|
|
43605
|
+
var MCPGuidelines = {
|
|
43508
43606
|
// Core rules - always needed
|
|
43509
|
-
core:
|
|
43607
|
+
core: MCP_CORE_RULES,
|
|
43510
43608
|
// Commands reference
|
|
43511
|
-
commands:
|
|
43609
|
+
commands: MCP_COMMANDS_REFERENCE,
|
|
43512
43610
|
// Workflow stages
|
|
43513
43611
|
workflow: {
|
|
43514
|
-
creation:
|
|
43515
|
-
execution:
|
|
43516
|
-
completion:
|
|
43612
|
+
creation: MCP_WORKFLOW_CREATION,
|
|
43613
|
+
execution: MCP_WORKFLOW_EXECUTION,
|
|
43614
|
+
completion: MCP_WORKFLOW_COMPLETION
|
|
43517
43615
|
},
|
|
43518
43616
|
// Common mistakes
|
|
43519
|
-
mistakes:
|
|
43617
|
+
mistakes: MCP_COMMON_MISTAKES,
|
|
43520
43618
|
// Context optimization
|
|
43521
|
-
contextOptimization:
|
|
43619
|
+
contextOptimization: MCP_CONTEXT_OPTIMIZATION,
|
|
43522
43620
|
/**
|
|
43523
|
-
* Get full guidelines (all sections combined)
|
|
43621
|
+
* Get full MCP guidelines (all sections combined)
|
|
43524
43622
|
*/
|
|
43525
43623
|
getFull(withMarkers2 = false) {
|
|
43526
43624
|
const content = [
|
|
43527
|
-
|
|
43625
|
+
MCP_CORE_RULES,
|
|
43528
43626
|
"---",
|
|
43529
|
-
|
|
43627
|
+
MCP_CONTEXT_OPTIMIZATION,
|
|
43530
43628
|
"---",
|
|
43531
|
-
|
|
43629
|
+
MCP_COMMANDS_REFERENCE,
|
|
43532
43630
|
"---",
|
|
43533
|
-
|
|
43631
|
+
MCP_WORKFLOW_CREATION,
|
|
43534
43632
|
"---",
|
|
43535
|
-
|
|
43633
|
+
MCP_WORKFLOW_EXECUTION,
|
|
43536
43634
|
"---",
|
|
43537
|
-
|
|
43635
|
+
MCP_WORKFLOW_COMPLETION,
|
|
43538
43636
|
"---",
|
|
43539
|
-
|
|
43637
|
+
MCP_COMMON_MISTAKES
|
|
43540
43638
|
].join("\n\n");
|
|
43541
43639
|
if (withMarkers2) {
|
|
43542
43640
|
return `<!-- KNOWNS GUIDELINES START -->
|
|
@@ -43546,33 +43644,43 @@ ${content}
|
|
|
43546
43644
|
return content;
|
|
43547
43645
|
},
|
|
43548
43646
|
/**
|
|
43549
|
-
* Get compact guidelines (core + context optimization + mistakes only)
|
|
43647
|
+
* Get compact MCP guidelines (core + context optimization + mistakes only)
|
|
43550
43648
|
*/
|
|
43551
43649
|
getCompact() {
|
|
43552
|
-
return [
|
|
43650
|
+
return [MCP_CORE_RULES, "---", MCP_CONTEXT_OPTIMIZATION, "---", MCP_COMMON_MISTAKES].join("\n\n");
|
|
43553
43651
|
},
|
|
43554
43652
|
/**
|
|
43555
|
-
* Get guidelines for specific workflow stage
|
|
43653
|
+
* Get MCP guidelines for specific workflow stage
|
|
43556
43654
|
*/
|
|
43557
43655
|
getForStage(stage) {
|
|
43558
|
-
const sections = [
|
|
43656
|
+
const sections = [MCP_CORE_RULES, "---", MCP_CONTEXT_OPTIMIZATION, "---"];
|
|
43559
43657
|
switch (stage) {
|
|
43560
43658
|
case "creation":
|
|
43561
|
-
sections.push(
|
|
43659
|
+
sections.push(MCP_WORKFLOW_CREATION);
|
|
43562
43660
|
break;
|
|
43563
43661
|
case "execution":
|
|
43564
|
-
sections.push(
|
|
43565
|
-
sections.push("---",
|
|
43662
|
+
sections.push(MCP_WORKFLOW_EXECUTION);
|
|
43663
|
+
sections.push("---", MCP_COMMANDS_REFERENCE);
|
|
43566
43664
|
break;
|
|
43567
43665
|
case "completion":
|
|
43568
|
-
sections.push(
|
|
43666
|
+
sections.push(MCP_WORKFLOW_COMPLETION);
|
|
43569
43667
|
break;
|
|
43570
43668
|
}
|
|
43571
|
-
sections.push("---",
|
|
43669
|
+
sections.push("---", MCP_COMMON_MISTAKES);
|
|
43572
43670
|
return sections.join("\n\n");
|
|
43573
43671
|
}
|
|
43574
43672
|
};
|
|
43575
43673
|
|
|
43674
|
+
// src/templates/guidelines/index.ts
|
|
43675
|
+
var Guidelines = CLIGuidelines;
|
|
43676
|
+
var CORE_RULES = CLIGuidelines.core;
|
|
43677
|
+
var COMMANDS_REFERENCE = CLIGuidelines.commands;
|
|
43678
|
+
var WORKFLOW_CREATION = CLIGuidelines.workflow.creation;
|
|
43679
|
+
var WORKFLOW_EXECUTION = CLIGuidelines.workflow.execution;
|
|
43680
|
+
var WORKFLOW_COMPLETION = CLIGuidelines.workflow.completion;
|
|
43681
|
+
var COMMON_MISTAKES = CLIGuidelines.mistakes;
|
|
43682
|
+
var CONTEXT_OPTIMIZATION = CLIGuidelines.contextOptimization;
|
|
43683
|
+
|
|
43576
43684
|
// src/templates/instruction/cli.md
|
|
43577
43685
|
var cli_default = '# Knowns Project\n\nThis project uses **Knowns CLI** for task and documentation management.\n\n## Before Starting\n\nRun this command to get usage guidelines:\n\n```bash\nknowns agents guideline\n```\n\nYou MUST call this at session start and follow every rule it outputs.\n\n## Context-Specific Guidelines\n\nGet guidelines for specific workflow stages:\n\n```bash\n# Full guidelines (all sections)\nknowns agents guideline --full\n\n# Compact (core rules + common mistakes)\nknowns agents guideline --compact\n\n# By workflow stage\nknowns agents guideline --stage creation # Creating tasks\nknowns agents guideline --stage execution # Implementing tasks\nknowns agents guideline --stage completion # Completing tasks\n\n# Individual sections\nknowns agents guideline --core # Core rules only\nknowns agents guideline --commands # Commands reference\nknowns agents guideline --mistakes # Common mistakes\n```\n\n## Quick Commands\n\n```bash\nknowns task list --plain # List tasks\nknowns task <id> --plain # View task\nknowns doc list --plain # List docs\nknowns doc "<path>" --plain # View doc\nknowns search "query" --plain # Search\n```\n\n**Important:** Always read the guidelines before working on tasks.\n';
|
|
43578
43686
|
|
|
@@ -43598,13 +43706,17 @@ var INSTRUCTION_FILES = [
|
|
|
43598
43706
|
{ path: "CLAUDE.md", name: "Claude Code", selected: true },
|
|
43599
43707
|
{ path: "AGENTS.md", name: "Agent SDK", selected: true },
|
|
43600
43708
|
{ path: "GEMINI.md", name: "Gemini", selected: false },
|
|
43601
|
-
{
|
|
43709
|
+
{
|
|
43710
|
+
path: ".github/copilot-instructions.md",
|
|
43711
|
+
name: "GitHub Copilot",
|
|
43712
|
+
selected: false
|
|
43713
|
+
}
|
|
43602
43714
|
];
|
|
43603
43715
|
function getGuidelines(type, variant = "general") {
|
|
43604
43716
|
if (variant === "instruction") {
|
|
43605
43717
|
return type === "mcp" ? MCP_INSTRUCTION : CLI_INSTRUCTION;
|
|
43606
43718
|
}
|
|
43607
|
-
return Guidelines.getFull(true);
|
|
43719
|
+
return type === "mcp" ? MCPGuidelines.getFull(true) : Guidelines.getFull(true);
|
|
43608
43720
|
}
|
|
43609
43721
|
async function updateInstructionFile(filePath, guidelines) {
|
|
43610
43722
|
const fullPath = join3(PROJECT_ROOT, filePath);
|
|
@@ -43635,111 +43747,113 @@ ${guidelines}
|
|
|
43635
43747
|
await writeFile2(fullPath, newContent, "utf-8");
|
|
43636
43748
|
return { success: true, action: "updated" };
|
|
43637
43749
|
}
|
|
43638
|
-
var agentsCommand = new Command("agents").description("Manage agent instruction files (CLAUDE.md, GEMINI.md, etc.)").enablePositionalOptions().passThroughOptions().option("--update-instructions", "Update agent instruction files (non-interactive)").option("--type <type>", "Guidelines type: cli or mcp", "cli").option("--files <files>", "Comma-separated list of files to update").action(
|
|
43639
|
-
|
|
43640
|
-
|
|
43641
|
-
|
|
43642
|
-
|
|
43643
|
-
|
|
43644
|
-
|
|
43645
|
-
|
|
43646
|
-
|
|
43647
|
-
|
|
43648
|
-
|
|
43649
|
-
|
|
43650
|
-
|
|
43651
|
-
|
|
43652
|
-
|
|
43750
|
+
var agentsCommand = new Command("agents").description("Manage agent instruction files (CLAUDE.md, GEMINI.md, etc.)").enablePositionalOptions().passThroughOptions().option("--update-instructions", "Update agent instruction files (non-interactive)").option("--type <type>", "Guidelines type: cli or mcp", "cli").option("--files <files>", "Comma-separated list of files to update").action(
|
|
43751
|
+
async (options2) => {
|
|
43752
|
+
try {
|
|
43753
|
+
if (options2.updateInstructions) {
|
|
43754
|
+
const type = options2.type === "mcp" ? "mcp" : "cli";
|
|
43755
|
+
const variant = "general";
|
|
43756
|
+
const guidelines2 = getGuidelines(type, variant);
|
|
43757
|
+
let filesToUpdate = INSTRUCTION_FILES;
|
|
43758
|
+
if (options2.files) {
|
|
43759
|
+
const requestedFiles = options2.files.split(",").map((f) => f.trim());
|
|
43760
|
+
filesToUpdate = INSTRUCTION_FILES.filter(
|
|
43761
|
+
(f) => requestedFiles.includes(f.path) || requestedFiles.includes(f.name)
|
|
43762
|
+
);
|
|
43763
|
+
}
|
|
43764
|
+
const label2 = `${type.toUpperCase()}`;
|
|
43765
|
+
console.log(source_default.bold(`
|
|
43653
43766
|
Updating agent instruction files (${label2})...
|
|
43654
43767
|
`));
|
|
43655
|
-
|
|
43656
|
-
|
|
43657
|
-
|
|
43658
|
-
|
|
43659
|
-
|
|
43660
|
-
|
|
43661
|
-
|
|
43662
|
-
|
|
43663
|
-
|
|
43664
|
-
|
|
43665
|
-
|
|
43666
|
-
|
|
43667
|
-
|
|
43668
|
-
|
|
43669
|
-
|
|
43670
|
-
|
|
43671
|
-
|
|
43672
|
-
|
|
43673
|
-
|
|
43674
|
-
|
|
43675
|
-
|
|
43676
|
-
|
|
43677
|
-
|
|
43678
|
-
|
|
43679
|
-
|
|
43680
|
-
|
|
43681
|
-
|
|
43682
|
-
|
|
43683
|
-
|
|
43684
|
-
|
|
43685
|
-
|
|
43686
|
-
|
|
43687
|
-
|
|
43688
|
-
|
|
43689
|
-
|
|
43690
|
-
|
|
43691
|
-
|
|
43692
|
-
|
|
43693
|
-
|
|
43694
|
-
|
|
43695
|
-
|
|
43696
|
-
|
|
43697
|
-
|
|
43698
|
-
|
|
43699
|
-
|
|
43700
|
-
|
|
43701
|
-
|
|
43702
|
-
|
|
43703
|
-
|
|
43704
|
-
|
|
43705
|
-
|
|
43706
|
-
|
|
43707
|
-
|
|
43708
|
-
|
|
43709
|
-
|
|
43710
|
-
|
|
43711
|
-
|
|
43712
|
-
|
|
43713
|
-
|
|
43714
|
-
|
|
43715
|
-
|
|
43716
|
-
|
|
43717
|
-
|
|
43718
|
-
|
|
43719
|
-
|
|
43720
|
-
|
|
43721
|
-
|
|
43722
|
-
|
|
43723
|
-
|
|
43724
|
-
|
|
43725
|
-
|
|
43726
|
-
|
|
43727
|
-
|
|
43728
|
-
|
|
43729
|
-
|
|
43730
|
-
|
|
43731
|
-
|
|
43732
|
-
|
|
43733
|
-
|
|
43734
|
-
|
|
43768
|
+
await updateFiles(filesToUpdate, guidelines2);
|
|
43769
|
+
return;
|
|
43770
|
+
}
|
|
43771
|
+
console.log(source_default.bold("\n\u{1F916} Agent Instructions Manager\n"));
|
|
43772
|
+
const typeResponse = await (0, import_prompts.default)({
|
|
43773
|
+
type: "select",
|
|
43774
|
+
name: "type",
|
|
43775
|
+
message: "Select guidelines type:",
|
|
43776
|
+
choices: [
|
|
43777
|
+
{
|
|
43778
|
+
title: "CLI",
|
|
43779
|
+
value: "cli",
|
|
43780
|
+
description: "CLI commands (knowns task edit, knowns doc view, etc.)"
|
|
43781
|
+
},
|
|
43782
|
+
{
|
|
43783
|
+
title: "MCP",
|
|
43784
|
+
value: "mcp",
|
|
43785
|
+
description: "MCP tools (mcp__knowns__update_task, etc.)"
|
|
43786
|
+
}
|
|
43787
|
+
],
|
|
43788
|
+
initial: 0
|
|
43789
|
+
});
|
|
43790
|
+
if (!typeResponse.type) {
|
|
43791
|
+
console.log(source_default.yellow("\n\u26A0\uFE0F Cancelled"));
|
|
43792
|
+
return;
|
|
43793
|
+
}
|
|
43794
|
+
const variantResponse = await (0, import_prompts.default)({
|
|
43795
|
+
type: "select",
|
|
43796
|
+
name: "variant",
|
|
43797
|
+
message: "Select variant:",
|
|
43798
|
+
choices: [
|
|
43799
|
+
{
|
|
43800
|
+
title: "Full (Recommended)",
|
|
43801
|
+
value: "general",
|
|
43802
|
+
description: "Complete guidelines embedded in file"
|
|
43803
|
+
},
|
|
43804
|
+
{
|
|
43805
|
+
title: "Minimal",
|
|
43806
|
+
value: "instruction",
|
|
43807
|
+
description: "Just tells AI to call `knowns agents guideline` for rules"
|
|
43808
|
+
}
|
|
43809
|
+
],
|
|
43810
|
+
initial: 0
|
|
43811
|
+
});
|
|
43812
|
+
if (!variantResponse.variant) {
|
|
43813
|
+
console.log(source_default.yellow("\n\u26A0\uFE0F Cancelled"));
|
|
43814
|
+
return;
|
|
43815
|
+
}
|
|
43816
|
+
const filesResponse = await (0, import_prompts.default)({
|
|
43817
|
+
type: "multiselect",
|
|
43818
|
+
name: "files",
|
|
43819
|
+
message: "Select agent files to update:",
|
|
43820
|
+
choices: INSTRUCTION_FILES.map((f) => ({
|
|
43821
|
+
title: `${f.name} (${f.path})`,
|
|
43822
|
+
value: f,
|
|
43823
|
+
selected: f.selected
|
|
43824
|
+
})),
|
|
43825
|
+
hint: "- Space to select. Return to submit"
|
|
43826
|
+
});
|
|
43827
|
+
if (!filesResponse.files || filesResponse.files.length === 0) {
|
|
43828
|
+
console.log(source_default.yellow("\n\u26A0\uFE0F No files selected"));
|
|
43829
|
+
return;
|
|
43830
|
+
}
|
|
43831
|
+
const variantLabel = variantResponse.variant === "instruction" ? " (minimal)" : " (full)";
|
|
43832
|
+
const label = `${typeResponse.type.toUpperCase()}${variantLabel}`;
|
|
43833
|
+
const confirmResponse = await (0, import_prompts.default)({
|
|
43834
|
+
type: "confirm",
|
|
43835
|
+
name: "confirm",
|
|
43836
|
+
message: `Update ${filesResponse.files.length} file(s) with ${label} guidelines?`,
|
|
43837
|
+
initial: true
|
|
43838
|
+
});
|
|
43839
|
+
if (!confirmResponse.confirm) {
|
|
43840
|
+
console.log(source_default.yellow("\n\u26A0\uFE0F Cancelled"));
|
|
43841
|
+
return;
|
|
43842
|
+
}
|
|
43843
|
+
const guidelines = getGuidelines(
|
|
43844
|
+
typeResponse.type,
|
|
43845
|
+
variantResponse.variant
|
|
43846
|
+
);
|
|
43847
|
+
console.log(source_default.bold(`
|
|
43735
43848
|
Updating files with ${label} guidelines...
|
|
43736
43849
|
`));
|
|
43737
|
-
|
|
43738
|
-
|
|
43739
|
-
|
|
43740
|
-
|
|
43850
|
+
await updateFiles(filesResponse.files, guidelines);
|
|
43851
|
+
} catch (error48) {
|
|
43852
|
+
console.error(source_default.red("Error:"), error48 instanceof Error ? error48.message : String(error48));
|
|
43853
|
+
process.exit(1);
|
|
43854
|
+
}
|
|
43741
43855
|
}
|
|
43742
|
-
|
|
43856
|
+
);
|
|
43743
43857
|
async function updateFiles(files, guidelines) {
|
|
43744
43858
|
let createdCount = 0;
|
|
43745
43859
|
let appendedCount = 0;
|
|
@@ -43890,18 +44004,26 @@ async function createMcpJsonFile(projectRoot) {
|
|
|
43890
44004
|
console.log(source_default.green("\u2713 Created .mcp.json for Claude Code MCP auto-discovery"));
|
|
43891
44005
|
}
|
|
43892
44006
|
}
|
|
43893
|
-
async function
|
|
44007
|
+
async function updateGitignore(projectRoot, mode) {
|
|
43894
44008
|
const { appendFileSync, readFileSync: readFileSync4, writeFileSync: writeFileSync3 } = await import("node:fs");
|
|
43895
44009
|
const gitignorePath = join4(projectRoot, ".gitignore");
|
|
43896
|
-
const
|
|
44010
|
+
const patterns = {
|
|
44011
|
+
"git-ignored": `
|
|
43897
44012
|
# knowns (ignore all except docs)
|
|
43898
44013
|
.knowns/*
|
|
43899
44014
|
!.knowns/docs/
|
|
43900
44015
|
!.knowns/docs/**
|
|
43901
|
-
|
|
44016
|
+
`,
|
|
44017
|
+
none: `
|
|
44018
|
+
# knowns (ignore entire folder)
|
|
44019
|
+
.knowns/
|
|
44020
|
+
`
|
|
44021
|
+
};
|
|
44022
|
+
const knownsIgnorePattern = patterns[mode];
|
|
44023
|
+
const checkPattern = mode === "none" ? ".knowns/" : ".knowns/*";
|
|
43902
44024
|
if (existsSync2(gitignorePath)) {
|
|
43903
44025
|
const content = readFileSync4(gitignorePath, "utf-8");
|
|
43904
|
-
if (content.includes(
|
|
44026
|
+
if (content.includes(checkPattern)) {
|
|
43905
44027
|
console.log(source_default.gray(" .gitignore already has knowns pattern"));
|
|
43906
44028
|
return;
|
|
43907
44029
|
}
|
|
@@ -43943,6 +44065,11 @@ async function runWizard() {
|
|
|
43943
44065
|
title: "Git Ignored (personal use)",
|
|
43944
44066
|
value: "git-ignored",
|
|
43945
44067
|
description: "Only docs tracked, tasks/config ignored"
|
|
44068
|
+
},
|
|
44069
|
+
{
|
|
44070
|
+
title: "None (ignore all)",
|
|
44071
|
+
value: "none",
|
|
44072
|
+
description: "Entire .knowns/ folder ignored by git"
|
|
43946
44073
|
}
|
|
43947
44074
|
],
|
|
43948
44075
|
initial: 0
|
|
@@ -43953,8 +44080,16 @@ async function runWizard() {
|
|
|
43953
44080
|
name: "guidelinesType",
|
|
43954
44081
|
message: "AI Guidelines type",
|
|
43955
44082
|
choices: [
|
|
43956
|
-
{
|
|
43957
|
-
|
|
44083
|
+
{
|
|
44084
|
+
title: "CLI",
|
|
44085
|
+
value: "cli",
|
|
44086
|
+
description: "Use CLI commands (knowns task edit, knowns doc view)"
|
|
44087
|
+
},
|
|
44088
|
+
{
|
|
44089
|
+
title: "MCP",
|
|
44090
|
+
value: "mcp",
|
|
44091
|
+
description: "Use MCP tools (mcp__knowns__update_task, etc.)"
|
|
44092
|
+
}
|
|
43958
44093
|
],
|
|
43959
44094
|
initial: 0
|
|
43960
44095
|
// CLI
|
|
@@ -44026,8 +44161,8 @@ var initCommand = new Command("init").description("Initialize .knowns/ folder in
|
|
|
44026
44161
|
agentFiles: INSTRUCTION_FILES.filter((f) => f.selected)
|
|
44027
44162
|
};
|
|
44028
44163
|
}
|
|
44029
|
-
if (config2.gitTrackingMode === "git-ignored") {
|
|
44030
|
-
await
|
|
44164
|
+
if (config2.gitTrackingMode === "git-ignored" || config2.gitTrackingMode === "none") {
|
|
44165
|
+
await updateGitignore(projectRoot, config2.gitTrackingMode);
|
|
44031
44166
|
}
|
|
44032
44167
|
if (config2.guidelinesType === "mcp") {
|
|
44033
44168
|
await createMcpJsonFile(projectRoot);
|
|
@@ -47743,6 +47878,159 @@ var browserCommand = new Command("browser").description("Open web UI for task ma
|
|
|
47743
47878
|
import { existsSync as existsSync14 } from "node:fs";
|
|
47744
47879
|
import { mkdir as mkdir7, readFile as readFile11, readdir as readdir5, writeFile as writeFile8 } from "node:fs/promises";
|
|
47745
47880
|
import { join as join17 } from "node:path";
|
|
47881
|
+
|
|
47882
|
+
// src/utils/markdown-toc.ts
|
|
47883
|
+
function extractToc(markdown) {
|
|
47884
|
+
const lines = markdown.split("\n");
|
|
47885
|
+
const toc = [];
|
|
47886
|
+
for (let i = 0; i < lines.length; i++) {
|
|
47887
|
+
const line = lines[i];
|
|
47888
|
+
const match = line.match(/^(#{1,6})\s+(.+)$/);
|
|
47889
|
+
if (match) {
|
|
47890
|
+
const level = match[1].length;
|
|
47891
|
+
const title = match[2].trim();
|
|
47892
|
+
const slug = slugify(title);
|
|
47893
|
+
toc.push({ level, title, slug, line: i + 1 });
|
|
47894
|
+
}
|
|
47895
|
+
}
|
|
47896
|
+
return toc;
|
|
47897
|
+
}
|
|
47898
|
+
function formatToc(toc, options2) {
|
|
47899
|
+
const { indent = true, showLine = false } = options2 || {};
|
|
47900
|
+
return toc.map((entry) => {
|
|
47901
|
+
const indentation = indent ? " ".repeat(entry.level - 1) : "";
|
|
47902
|
+
const prefix = indent ? "- " : `${"#".repeat(entry.level)} `;
|
|
47903
|
+
const lineInfo = showLine ? ` (line ${entry.line})` : "";
|
|
47904
|
+
return `${indentation}${prefix}${entry.title}${lineInfo}`;
|
|
47905
|
+
}).join("\n");
|
|
47906
|
+
}
|
|
47907
|
+
function extractSection(markdown, sectionTitle) {
|
|
47908
|
+
const lines = markdown.split("\n");
|
|
47909
|
+
const normalizedTarget = normalizeTitle(sectionTitle);
|
|
47910
|
+
let startLine = -1;
|
|
47911
|
+
let startLevel = 0;
|
|
47912
|
+
let endLine = lines.length;
|
|
47913
|
+
for (let i = 0; i < lines.length; i++) {
|
|
47914
|
+
const line = lines[i];
|
|
47915
|
+
const match = line.match(/^(#{1,6})\s+(.+)$/);
|
|
47916
|
+
if (match) {
|
|
47917
|
+
const level = match[1].length;
|
|
47918
|
+
const title = match[2].trim();
|
|
47919
|
+
if (startLine === -1) {
|
|
47920
|
+
if (normalizeTitle(title) === normalizedTarget || matchesPartial(title, sectionTitle)) {
|
|
47921
|
+
startLine = i;
|
|
47922
|
+
startLevel = level;
|
|
47923
|
+
}
|
|
47924
|
+
} else {
|
|
47925
|
+
if (level <= startLevel) {
|
|
47926
|
+
endLine = i;
|
|
47927
|
+
break;
|
|
47928
|
+
}
|
|
47929
|
+
}
|
|
47930
|
+
}
|
|
47931
|
+
}
|
|
47932
|
+
if (startLine === -1) {
|
|
47933
|
+
return null;
|
|
47934
|
+
}
|
|
47935
|
+
return lines.slice(startLine, endLine).join("\n").trim();
|
|
47936
|
+
}
|
|
47937
|
+
function replaceSection(markdown, sectionTitle, newContent) {
|
|
47938
|
+
const lines = markdown.split("\n");
|
|
47939
|
+
const normalizedTarget = normalizeTitle(sectionTitle);
|
|
47940
|
+
let startLine = -1;
|
|
47941
|
+
let startLevel = 0;
|
|
47942
|
+
let endLine = lines.length;
|
|
47943
|
+
let originalHeading = "";
|
|
47944
|
+
for (let i = 0; i < lines.length; i++) {
|
|
47945
|
+
const line = lines[i];
|
|
47946
|
+
const match = line.match(/^(#{1,6})\s+(.+)$/);
|
|
47947
|
+
if (match) {
|
|
47948
|
+
const level = match[1].length;
|
|
47949
|
+
const title = match[2].trim();
|
|
47950
|
+
if (startLine === -1) {
|
|
47951
|
+
if (normalizeTitle(title) === normalizedTarget || matchesPartial(title, sectionTitle)) {
|
|
47952
|
+
startLine = i;
|
|
47953
|
+
startLevel = level;
|
|
47954
|
+
originalHeading = line;
|
|
47955
|
+
}
|
|
47956
|
+
} else {
|
|
47957
|
+
if (level <= startLevel) {
|
|
47958
|
+
endLine = i;
|
|
47959
|
+
break;
|
|
47960
|
+
}
|
|
47961
|
+
}
|
|
47962
|
+
}
|
|
47963
|
+
}
|
|
47964
|
+
if (startLine === -1) {
|
|
47965
|
+
return null;
|
|
47966
|
+
}
|
|
47967
|
+
const beforeSection = lines.slice(0, startLine);
|
|
47968
|
+
const afterSection = lines.slice(endLine);
|
|
47969
|
+
const newSection = `${originalHeading}
|
|
47970
|
+
|
|
47971
|
+
${newContent.trim()}`;
|
|
47972
|
+
return [...beforeSection, newSection, ...afterSection].join("\n");
|
|
47973
|
+
}
|
|
47974
|
+
function slugify(title) {
|
|
47975
|
+
return title.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
|
|
47976
|
+
}
|
|
47977
|
+
function normalizeTitle(title) {
|
|
47978
|
+
return title.toLowerCase().replace(/[^\w\s]/g, "").replace(/\s+/g, " ").trim();
|
|
47979
|
+
}
|
|
47980
|
+
function calculateDocStats(markdown) {
|
|
47981
|
+
const chars = markdown.length;
|
|
47982
|
+
const words = markdown.split(/\s+/).filter((w) => w.length > 0).length;
|
|
47983
|
+
const lines = markdown.split("\n").length;
|
|
47984
|
+
const toc = extractToc(markdown);
|
|
47985
|
+
const headingCount = toc.length;
|
|
47986
|
+
const estimatedTokens = Math.ceil(chars / 3.5);
|
|
47987
|
+
return {
|
|
47988
|
+
chars,
|
|
47989
|
+
words,
|
|
47990
|
+
lines,
|
|
47991
|
+
estimatedTokens,
|
|
47992
|
+
headingCount
|
|
47993
|
+
};
|
|
47994
|
+
}
|
|
47995
|
+
function formatDocStats(stats, title) {
|
|
47996
|
+
const lines = [
|
|
47997
|
+
`Document: ${title}`,
|
|
47998
|
+
"=".repeat(50),
|
|
47999
|
+
"",
|
|
48000
|
+
`Size: ${stats.chars.toLocaleString()} chars (~${stats.estimatedTokens.toLocaleString()} tokens)`,
|
|
48001
|
+
`Words: ${stats.words.toLocaleString()}`,
|
|
48002
|
+
`Lines: ${stats.lines.toLocaleString()}`,
|
|
48003
|
+
`Headings: ${stats.headingCount}`,
|
|
48004
|
+
""
|
|
48005
|
+
];
|
|
48006
|
+
if (stats.estimatedTokens > 4e3) {
|
|
48007
|
+
lines.push("Recommendation: Document is large. Use --toc first, then --section.");
|
|
48008
|
+
} else if (stats.estimatedTokens > 2e3) {
|
|
48009
|
+
lines.push("Recommendation: Consider using --toc and --section for specific info.");
|
|
48010
|
+
} else {
|
|
48011
|
+
lines.push("Recommendation: Document is small enough to read directly.");
|
|
48012
|
+
}
|
|
48013
|
+
return lines.join("\n");
|
|
48014
|
+
}
|
|
48015
|
+
function matchesPartial(title, search) {
|
|
48016
|
+
const normalizedTitle = normalizeTitle(title);
|
|
48017
|
+
const normalizedSearch = normalizeTitle(search);
|
|
48018
|
+
if (normalizedTitle === normalizedSearch) return true;
|
|
48019
|
+
if (normalizedTitle.startsWith(normalizedSearch)) return true;
|
|
48020
|
+
const numMatch = search.match(/^(\d+)\.?\s*(.*)$/);
|
|
48021
|
+
if (numMatch) {
|
|
48022
|
+
const [, num, rest] = numMatch;
|
|
48023
|
+
const titleNumMatch = title.match(/^(\d+)\.?\s*(.*)$/);
|
|
48024
|
+
if (titleNumMatch && titleNumMatch[1] === num) {
|
|
48025
|
+
if (!rest || normalizeTitle(titleNumMatch[2]).startsWith(normalizeTitle(rest))) {
|
|
48026
|
+
return true;
|
|
48027
|
+
}
|
|
48028
|
+
}
|
|
48029
|
+
}
|
|
48030
|
+
return false;
|
|
48031
|
+
}
|
|
48032
|
+
|
|
48033
|
+
// src/commands/doc.ts
|
|
47746
48034
|
var import_gray_matter6 = __toESM(require_gray_matter(), 1);
|
|
47747
48035
|
var DOCS_DIR = join17(process.cwd(), ".knowns", "docs");
|
|
47748
48036
|
async function getAllMdFiles(dir, basePath = "") {
|
|
@@ -47794,51 +48082,56 @@ async function resolveDocPath(name) {
|
|
|
47794
48082
|
}
|
|
47795
48083
|
return { filepath, filename };
|
|
47796
48084
|
}
|
|
47797
|
-
var createCommand3 = new Command("create").description("Create a new documentation file").argument("<title>", "Document title").option("-d, --description <text>", "Document description").option("-t, --tags <tags>", "Comma-separated tags").option("-f, --folder <path>", "Folder path (e.g., guides, patterns/auth)").option("--plain", "Plain text output for AI").action(
|
|
47798
|
-
|
|
47799
|
-
|
|
47800
|
-
|
|
47801
|
-
|
|
47802
|
-
|
|
47803
|
-
|
|
47804
|
-
|
|
47805
|
-
|
|
47806
|
-
|
|
47807
|
-
|
|
47808
|
-
|
|
47809
|
-
|
|
47810
|
-
|
|
47811
|
-
|
|
47812
|
-
|
|
47813
|
-
|
|
48085
|
+
var createCommand3 = new Command("create").description("Create a new documentation file").argument("<title>", "Document title").option("-d, --description <text>", "Document description").option("-t, --tags <tags>", "Comma-separated tags").option("-f, --folder <path>", "Folder path (e.g., guides, patterns/auth)").option("--plain", "Plain text output for AI").action(
|
|
48086
|
+
async (title, options2) => {
|
|
48087
|
+
try {
|
|
48088
|
+
await ensureDocsDir();
|
|
48089
|
+
const filename = `${titleToFilename(title)}.md`;
|
|
48090
|
+
let targetDir = DOCS_DIR;
|
|
48091
|
+
let relativePath = filename;
|
|
48092
|
+
if (options2.folder) {
|
|
48093
|
+
const folderPath = options2.folder.replace(/^\/|\/$/g, "");
|
|
48094
|
+
targetDir = join17(DOCS_DIR, folderPath);
|
|
48095
|
+
relativePath = join17(folderPath, filename);
|
|
48096
|
+
if (!existsSync14(targetDir)) {
|
|
48097
|
+
await mkdir7(targetDir, { recursive: true });
|
|
48098
|
+
}
|
|
48099
|
+
}
|
|
48100
|
+
const filepath = join17(targetDir, filename);
|
|
48101
|
+
if (existsSync14(filepath)) {
|
|
48102
|
+
console.error(source_default.red(`\u2717 Document already exists: ${relativePath}`));
|
|
48103
|
+
process.exit(1);
|
|
48104
|
+
}
|
|
48105
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
48106
|
+
const metadata = {
|
|
48107
|
+
title,
|
|
48108
|
+
createdAt: now,
|
|
48109
|
+
updatedAt: now
|
|
48110
|
+
};
|
|
48111
|
+
if (options2.description) {
|
|
48112
|
+
metadata.description = normalizeRefs(options2.description);
|
|
48113
|
+
}
|
|
48114
|
+
if (options2.tags) {
|
|
48115
|
+
metadata.tags = options2.tags.split(",").map((t) => t.trim());
|
|
48116
|
+
}
|
|
48117
|
+
const content = import_gray_matter6.default.stringify("# Content\n\nWrite your documentation here.\n", metadata);
|
|
48118
|
+
await writeFile8(filepath, content, "utf-8");
|
|
48119
|
+
await notifyDocUpdate(relativePath);
|
|
48120
|
+
if (options2.plain) {
|
|
48121
|
+
console.log(`Created: ${relativePath}`);
|
|
48122
|
+
} else {
|
|
48123
|
+
console.log(source_default.green(`\u2713 Created documentation: ${source_default.bold(relativePath)}`));
|
|
48124
|
+
console.log(source_default.gray(` Location: ${filepath}`));
|
|
48125
|
+
}
|
|
48126
|
+
} catch (error48) {
|
|
48127
|
+
console.error(
|
|
48128
|
+
source_default.red("Error creating documentation:"),
|
|
48129
|
+
error48 instanceof Error ? error48.message : String(error48)
|
|
48130
|
+
);
|
|
47814
48131
|
process.exit(1);
|
|
47815
48132
|
}
|
|
47816
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
47817
|
-
const metadata = {
|
|
47818
|
-
title,
|
|
47819
|
-
createdAt: now,
|
|
47820
|
-
updatedAt: now
|
|
47821
|
-
};
|
|
47822
|
-
if (options2.description) {
|
|
47823
|
-
metadata.description = normalizeRefs(options2.description);
|
|
47824
|
-
}
|
|
47825
|
-
if (options2.tags) {
|
|
47826
|
-
metadata.tags = options2.tags.split(",").map((t) => t.trim());
|
|
47827
|
-
}
|
|
47828
|
-
const content = import_gray_matter6.default.stringify("# Content\n\nWrite your documentation here.\n", metadata);
|
|
47829
|
-
await writeFile8(filepath, content, "utf-8");
|
|
47830
|
-
await notifyDocUpdate(relativePath);
|
|
47831
|
-
if (options2.plain) {
|
|
47832
|
-
console.log(`Created: ${relativePath}`);
|
|
47833
|
-
} else {
|
|
47834
|
-
console.log(source_default.green(`\u2713 Created documentation: ${source_default.bold(relativePath)}`));
|
|
47835
|
-
console.log(source_default.gray(` Location: ${filepath}`));
|
|
47836
|
-
}
|
|
47837
|
-
} catch (error48) {
|
|
47838
|
-
console.error(source_default.red("Error creating documentation:"), error48 instanceof Error ? error48.message : String(error48));
|
|
47839
|
-
process.exit(1);
|
|
47840
48133
|
}
|
|
47841
|
-
|
|
48134
|
+
);
|
|
47842
48135
|
var listCommand2 = new Command("list").description("List all documentation files").argument("[path]", "Filter by path (e.g., 'guides/' or 'patterns/')").option("--plain", "Plain text output for AI").option("-t, --tag <tag>", "Filter by tag").action(async (path, options2) => {
|
|
47843
48136
|
try {
|
|
47844
48137
|
await ensureDocsDir();
|
|
@@ -47961,115 +48254,197 @@ Documentation (${filteredDocs.length})
|
|
|
47961
48254
|
process.exit(1);
|
|
47962
48255
|
}
|
|
47963
48256
|
});
|
|
47964
|
-
var viewCommand2 = new Command("view").description("View a documentation file").argument("<name>", "Document name (filename or title or path)").option("--plain", "Plain text output for AI").
|
|
47965
|
-
|
|
47966
|
-
|
|
47967
|
-
|
|
47968
|
-
|
|
47969
|
-
|
|
47970
|
-
|
|
47971
|
-
|
|
47972
|
-
|
|
47973
|
-
if (!existsSync14(filepath)) {
|
|
47974
|
-
const allFiles = await getAllMdFiles(DOCS_DIR);
|
|
47975
|
-
const searchName = name.toLowerCase().replace(/\.md$/, "");
|
|
47976
|
-
const matchingFile = allFiles.find((file3) => {
|
|
47977
|
-
const fileNameOnly = file3.toLowerCase().replace(/\.md$/, "");
|
|
47978
|
-
const fileBaseName = file3.split("/").pop()?.toLowerCase().replace(/\.md$/, "");
|
|
47979
|
-
return fileNameOnly === searchName || fileBaseName === searchName || file3 === name;
|
|
47980
|
-
});
|
|
47981
|
-
if (matchingFile) {
|
|
47982
|
-
filename = matchingFile;
|
|
47983
|
-
filepath = join17(DOCS_DIR, matchingFile);
|
|
48257
|
+
var viewCommand2 = new Command("view").description("View a documentation file").argument("<name>", "Document name (filename or title or path)").option("--plain", "Plain text output for AI").option("--info", "Show document stats (size, tokens, headings) without content").option("--toc", "Show table of contents only").option("--section <title>", "Show specific section by heading title or number (e.g., '2. Overview' or '2')").action(
|
|
48258
|
+
async (name, options2) => {
|
|
48259
|
+
try {
|
|
48260
|
+
await ensureDocsDir();
|
|
48261
|
+
let filename = name.endsWith(".md") ? name : `${name}.md`;
|
|
48262
|
+
let filepath = join17(DOCS_DIR, filename);
|
|
48263
|
+
if (!existsSync14(filepath)) {
|
|
48264
|
+
filename = `${titleToFilename(name)}.md`;
|
|
48265
|
+
filepath = join17(DOCS_DIR, filename);
|
|
47984
48266
|
}
|
|
47985
|
-
|
|
47986
|
-
|
|
47987
|
-
|
|
47988
|
-
|
|
47989
|
-
|
|
47990
|
-
|
|
47991
|
-
|
|
47992
|
-
|
|
47993
|
-
|
|
47994
|
-
|
|
47995
|
-
|
|
47996
|
-
|
|
47997
|
-
console.log(`File: ${projectRoot}/.knowns/docs/${filename}`);
|
|
47998
|
-
console.log();
|
|
47999
|
-
console.log(metadata.title);
|
|
48000
|
-
console.log(titleBorder);
|
|
48001
|
-
console.log();
|
|
48002
|
-
console.log(`Created: ${metadata.createdAt}`);
|
|
48003
|
-
console.log(`Updated: ${metadata.updatedAt}`);
|
|
48004
|
-
if (metadata.tags && metadata.tags.length > 0) {
|
|
48005
|
-
console.log(`Tags: ${metadata.tags.join(", ")}`);
|
|
48267
|
+
if (!existsSync14(filepath)) {
|
|
48268
|
+
const allFiles = await getAllMdFiles(DOCS_DIR);
|
|
48269
|
+
const searchName = name.toLowerCase().replace(/\.md$/, "");
|
|
48270
|
+
const matchingFile = allFiles.find((file3) => {
|
|
48271
|
+
const fileNameOnly = file3.toLowerCase().replace(/\.md$/, "");
|
|
48272
|
+
const fileBaseName = file3.split("/").pop()?.toLowerCase().replace(/\.md$/, "");
|
|
48273
|
+
return fileNameOnly === searchName || fileBaseName === searchName || file3 === name;
|
|
48274
|
+
});
|
|
48275
|
+
if (matchingFile) {
|
|
48276
|
+
filename = matchingFile;
|
|
48277
|
+
filepath = join17(DOCS_DIR, matchingFile);
|
|
48278
|
+
}
|
|
48006
48279
|
}
|
|
48007
|
-
if (
|
|
48008
|
-
console.
|
|
48009
|
-
|
|
48010
|
-
console.log(border);
|
|
48011
|
-
console.log(metadata.description);
|
|
48280
|
+
if (!existsSync14(filepath)) {
|
|
48281
|
+
console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
|
|
48282
|
+
process.exit(1);
|
|
48012
48283
|
}
|
|
48013
|
-
|
|
48014
|
-
|
|
48015
|
-
|
|
48016
|
-
|
|
48017
|
-
|
|
48018
|
-
|
|
48019
|
-
|
|
48020
|
-
|
|
48021
|
-
|
|
48022
|
-
|
|
48023
|
-
|
|
48024
|
-
|
|
48025
|
-
|
|
48284
|
+
const fileContent = await readFile11(filepath, "utf-8");
|
|
48285
|
+
const { data, content } = (0, import_gray_matter6.default)(fileContent);
|
|
48286
|
+
const metadata = data;
|
|
48287
|
+
if (options2.info) {
|
|
48288
|
+
const stats = calculateDocStats(content);
|
|
48289
|
+
if (options2.plain) {
|
|
48290
|
+
console.log(formatDocStats(stats, metadata.title));
|
|
48291
|
+
} else {
|
|
48292
|
+
console.log(source_default.bold(`
|
|
48293
|
+
\u{1F4CA} ${metadata.title} - Document Info
|
|
48294
|
+
`));
|
|
48295
|
+
console.log(
|
|
48296
|
+
`Size: ${source_default.cyan(stats.chars.toLocaleString())} chars (~${source_default.yellow(stats.estimatedTokens.toLocaleString())} tokens)`
|
|
48297
|
+
);
|
|
48298
|
+
console.log(`Words: ${stats.words.toLocaleString()}`);
|
|
48299
|
+
console.log(`Lines: ${stats.lines.toLocaleString()}`);
|
|
48300
|
+
console.log(`Headings: ${stats.headingCount}`);
|
|
48301
|
+
console.log();
|
|
48302
|
+
if (stats.estimatedTokens > 4e3) {
|
|
48303
|
+
console.log(source_default.yellow("\u26A0 Document is large. Use --toc first, then --section."));
|
|
48304
|
+
} else if (stats.estimatedTokens > 2e3) {
|
|
48305
|
+
console.log(source_default.gray("Consider using --toc and --section for specific info."));
|
|
48306
|
+
} else {
|
|
48307
|
+
console.log(source_default.green("\u2713 Document is small enough to read directly."));
|
|
48308
|
+
}
|
|
48309
|
+
console.log();
|
|
48026
48310
|
}
|
|
48027
|
-
|
|
48028
|
-
|
|
48311
|
+
return;
|
|
48312
|
+
}
|
|
48313
|
+
if (options2.toc) {
|
|
48314
|
+
const toc = extractToc(content);
|
|
48315
|
+
if (toc.length === 0) {
|
|
48316
|
+
console.log(options2.plain ? "No headings found." : source_default.yellow("No headings found in this document."));
|
|
48317
|
+
return;
|
|
48029
48318
|
}
|
|
48030
|
-
|
|
48031
|
-
|
|
48032
|
-
|
|
48319
|
+
if (options2.plain) {
|
|
48320
|
+
console.log(`Table of Contents: ${metadata.title}`);
|
|
48321
|
+
console.log("=".repeat(50));
|
|
48322
|
+
console.log();
|
|
48323
|
+
toc.forEach((entry, index) => {
|
|
48324
|
+
const indent = " ".repeat(entry.level - 1);
|
|
48325
|
+
console.log(`${indent}${index + 1}. ${entry.title}`);
|
|
48326
|
+
});
|
|
48327
|
+
console.log();
|
|
48328
|
+
console.log("Use --section <number or title> to view a specific section.");
|
|
48329
|
+
} else {
|
|
48330
|
+
console.log(source_default.bold(`
|
|
48331
|
+
\u{1F4C4} ${metadata.title} - Table of Contents
|
|
48332
|
+
`));
|
|
48333
|
+
console.log(formatToc(toc));
|
|
48334
|
+
console.log(source_default.gray("\nUse --section <number or title> to view a specific section."));
|
|
48033
48335
|
}
|
|
48034
|
-
|
|
48035
|
-
linksToAdd.push({
|
|
48036
|
-
original: fullMatch,
|
|
48037
|
-
resolved: resolvedPath
|
|
48038
|
-
});
|
|
48039
|
-
}
|
|
48040
|
-
for (const { original, resolved } of linksToAdd) {
|
|
48041
|
-
enhancedContent = enhancedContent.replace(original, resolved);
|
|
48336
|
+
return;
|
|
48042
48337
|
}
|
|
48043
|
-
|
|
48044
|
-
|
|
48045
|
-
|
|
48046
|
-
|
|
48047
|
-
|
|
48048
|
-
|
|
48338
|
+
if (options2.section) {
|
|
48339
|
+
const sectionContent = extractSection(content, options2.section);
|
|
48340
|
+
if (!sectionContent) {
|
|
48341
|
+
console.error(
|
|
48342
|
+
options2.plain ? `Section not found: ${options2.section}` : source_default.red(`\u2717 Section not found: ${options2.section}`)
|
|
48343
|
+
);
|
|
48344
|
+
console.log(
|
|
48345
|
+
options2.plain ? "Use --toc to see available sections." : source_default.gray("Use --toc to see available sections.")
|
|
48346
|
+
);
|
|
48347
|
+
process.exit(1);
|
|
48348
|
+
}
|
|
48349
|
+
if (options2.plain) {
|
|
48350
|
+
console.log(`File: ${process.cwd()}/.knowns/docs/${filename}`);
|
|
48351
|
+
console.log(`Section: ${options2.section}`);
|
|
48352
|
+
console.log("=".repeat(50));
|
|
48353
|
+
console.log();
|
|
48354
|
+
console.log(sectionContent);
|
|
48355
|
+
} else {
|
|
48356
|
+
console.log(source_default.bold(`
|
|
48357
|
+
\u{1F4C4} ${metadata.title} - Section
|
|
48358
|
+
`));
|
|
48359
|
+
console.log(sectionContent);
|
|
48360
|
+
console.log();
|
|
48361
|
+
}
|
|
48362
|
+
return;
|
|
48049
48363
|
}
|
|
48050
|
-
|
|
48051
|
-
|
|
48052
|
-
|
|
48364
|
+
if (options2.plain) {
|
|
48365
|
+
const border = "-".repeat(50);
|
|
48366
|
+
const titleBorder = "=".repeat(50);
|
|
48367
|
+
const projectRoot = process.cwd();
|
|
48368
|
+
console.log(`File: ${projectRoot}/.knowns/docs/${filename}`);
|
|
48369
|
+
console.log();
|
|
48370
|
+
console.log(metadata.title);
|
|
48371
|
+
console.log(titleBorder);
|
|
48372
|
+
console.log();
|
|
48373
|
+
console.log(`Created: ${metadata.createdAt}`);
|
|
48374
|
+
console.log(`Updated: ${metadata.updatedAt}`);
|
|
48375
|
+
if (metadata.tags && metadata.tags.length > 0) {
|
|
48376
|
+
console.log(`Tags: ${metadata.tags.join(", ")}`);
|
|
48377
|
+
}
|
|
48378
|
+
if (metadata.description) {
|
|
48379
|
+
console.log();
|
|
48380
|
+
console.log("Description:");
|
|
48381
|
+
console.log(border);
|
|
48382
|
+
console.log(metadata.description);
|
|
48383
|
+
}
|
|
48384
|
+
console.log();
|
|
48385
|
+
console.log("Content:");
|
|
48386
|
+
console.log(border);
|
|
48387
|
+
const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
48388
|
+
let enhancedContent = content.trimEnd();
|
|
48389
|
+
const linksToAdd = [];
|
|
48390
|
+
let match;
|
|
48391
|
+
while ((match = linkPattern.exec(content)) !== null) {
|
|
48392
|
+
const _linkText = match[1];
|
|
48393
|
+
const linkTarget = match[2];
|
|
48394
|
+
const fullMatch = match[0];
|
|
48395
|
+
if (linkTarget.startsWith("http://") || linkTarget.startsWith("https://")) {
|
|
48396
|
+
continue;
|
|
48397
|
+
}
|
|
48398
|
+
if (linkTarget.startsWith("../")) {
|
|
48399
|
+
continue;
|
|
48400
|
+
}
|
|
48401
|
+
let resolvedFilename = linkTarget.replace(/^\.\//, "");
|
|
48402
|
+
if (!resolvedFilename.endsWith(".md")) {
|
|
48403
|
+
resolvedFilename = `${resolvedFilename}.md`;
|
|
48404
|
+
}
|
|
48405
|
+
const resolvedPath = `@.knowns/docs/${resolvedFilename}`;
|
|
48406
|
+
linksToAdd.push({
|
|
48407
|
+
original: fullMatch,
|
|
48408
|
+
resolved: resolvedPath
|
|
48409
|
+
});
|
|
48410
|
+
}
|
|
48411
|
+
for (const { original, resolved } of linksToAdd) {
|
|
48412
|
+
enhancedContent = enhancedContent.replace(original, resolved);
|
|
48413
|
+
}
|
|
48414
|
+
const knownProjectRoot = findProjectRoot();
|
|
48415
|
+
if (knownProjectRoot) {
|
|
48416
|
+
const fileStore2 = new FileStore(knownProjectRoot);
|
|
48417
|
+
const allTasks = await fileStore2.getAllTasks();
|
|
48418
|
+
const taskMap = buildTaskMap(allTasks);
|
|
48419
|
+
enhancedContent = transformMentionsToRefs(enhancedContent, taskMap);
|
|
48420
|
+
}
|
|
48421
|
+
console.log(enhancedContent);
|
|
48422
|
+
} else {
|
|
48423
|
+
console.log(source_default.bold(`
|
|
48053
48424
|
\u{1F4C4} ${metadata.title}
|
|
48054
48425
|
`));
|
|
48055
|
-
|
|
48056
|
-
|
|
48426
|
+
if (metadata.description) {
|
|
48427
|
+
console.log(source_default.gray(metadata.description));
|
|
48428
|
+
console.log();
|
|
48429
|
+
}
|
|
48430
|
+
if (metadata.tags && metadata.tags.length > 0) {
|
|
48431
|
+
console.log(source_default.gray(`Tags: ${metadata.tags.join(", ")}`));
|
|
48432
|
+
}
|
|
48433
|
+
console.log(source_default.gray(`Updated: ${new Date(metadata.updatedAt).toLocaleString()}`));
|
|
48434
|
+
console.log(source_default.gray("-".repeat(60)));
|
|
48435
|
+
console.log(content);
|
|
48057
48436
|
console.log();
|
|
48058
48437
|
}
|
|
48059
|
-
|
|
48060
|
-
|
|
48061
|
-
|
|
48062
|
-
|
|
48063
|
-
|
|
48064
|
-
|
|
48065
|
-
console.log();
|
|
48438
|
+
} catch (error48) {
|
|
48439
|
+
console.error(
|
|
48440
|
+
source_default.red("Error viewing documentation:"),
|
|
48441
|
+
error48 instanceof Error ? error48.message : String(error48)
|
|
48442
|
+
);
|
|
48443
|
+
process.exit(1);
|
|
48066
48444
|
}
|
|
48067
|
-
} catch (error48) {
|
|
48068
|
-
console.error(source_default.red("Error viewing documentation:"), error48 instanceof Error ? error48.message : String(error48));
|
|
48069
|
-
process.exit(1);
|
|
48070
48445
|
}
|
|
48071
|
-
|
|
48072
|
-
var editCommand2 = new Command("edit").description("Edit a documentation file (metadata and content)").argument("<name>", "Document name or path (e.g., guides/my-doc)").option("-t, --title <text>", "New title").option("-d, --description <text>", "New description").option("--tags <tags>", "Comma-separated tags").option("-c, --content <text>", "Replace content").option("-a, --append <text>", "Append to content").option("--content-file <path>", "Replace content with file contents").option("--append-file <path>", "Append file contents to document").option("--plain", "Plain text output for AI").action(
|
|
48446
|
+
);
|
|
48447
|
+
var editCommand2 = new Command("edit").description("Edit a documentation file (metadata and content)").argument("<name>", "Document name or path (e.g., guides/my-doc)").option("-t, --title <text>", "New title").option("-d, --description <text>", "New description").option("--tags <tags>", "Comma-separated tags").option("-c, --content <text>", "Replace content (or section content if --section used)").option("-a, --append <text>", "Append to content").option("--section <title>", "Target section to replace (use with -c)").option("--content-file <path>", "Replace content with file contents").option("--append-file <path>", "Append file contents to document").option("--plain", "Plain text output for AI").action(
|
|
48073
48448
|
async (name, options2) => {
|
|
48074
48449
|
try {
|
|
48075
48450
|
await ensureDocsDir();
|
|
@@ -48124,6 +48499,18 @@ var editCommand2 = new Command("edit").description("Edit a documentation file (m
|
|
|
48124
48499
|
|
|
48125
48500
|
${normalizeRefs(fileData)}`;
|
|
48126
48501
|
sourceFile = options2.appendFile;
|
|
48502
|
+
} else if (options2.section && options2.content) {
|
|
48503
|
+
const result = replaceSection(content, options2.section, normalizeRefs(options2.content));
|
|
48504
|
+
if (!result) {
|
|
48505
|
+
console.error(
|
|
48506
|
+
options2.plain ? `Section not found: ${options2.section}` : source_default.red(`\u2717 Section not found: ${options2.section}`)
|
|
48507
|
+
);
|
|
48508
|
+
console.log(
|
|
48509
|
+
options2.plain ? "Use 'knowns doc <path> --toc --plain' to see available sections." : source_default.gray("Use 'knowns doc <path> --toc --plain' to see available sections.")
|
|
48510
|
+
);
|
|
48511
|
+
process.exit(1);
|
|
48512
|
+
}
|
|
48513
|
+
updatedContent = result;
|
|
48127
48514
|
} else if (options2.content) {
|
|
48128
48515
|
updatedContent = normalizeRefs(options2.content);
|
|
48129
48516
|
} else if (options2.append) {
|
|
@@ -48136,11 +48523,17 @@ ${normalizeRefs(options2.append)}`;
|
|
|
48136
48523
|
await notifyDocUpdate(filename);
|
|
48137
48524
|
if (options2.plain) {
|
|
48138
48525
|
console.log(`Updated: ${filename}`);
|
|
48526
|
+
if (options2.section) {
|
|
48527
|
+
console.log(`Section: ${options2.section}`);
|
|
48528
|
+
}
|
|
48139
48529
|
if (sourceFile) {
|
|
48140
48530
|
console.log(`Content from: ${sourceFile}`);
|
|
48141
48531
|
}
|
|
48142
48532
|
} else {
|
|
48143
48533
|
console.log(source_default.green(`\u2713 Updated documentation: ${source_default.bold(filename)}`));
|
|
48534
|
+
if (options2.section) {
|
|
48535
|
+
console.log(source_default.gray(` Section: ${options2.section}`));
|
|
48536
|
+
}
|
|
48144
48537
|
if (sourceFile) {
|
|
48145
48538
|
console.log(source_default.gray(` Content from: ${sourceFile}`));
|
|
48146
48539
|
}
|
|
@@ -48432,100 +48825,182 @@ ${afterSection.trimStart()}`;
|
|
|
48432
48825
|
process.exit(1);
|
|
48433
48826
|
}
|
|
48434
48827
|
});
|
|
48435
|
-
var docCommand = new Command("doc").description("Manage documentation").argument("[name]", "Document name (shorthand for 'doc view <name>')").option("--plain", "Plain text output for AI").
|
|
48436
|
-
|
|
48437
|
-
|
|
48438
|
-
|
|
48439
|
-
|
|
48440
|
-
try {
|
|
48441
|
-
const resolved = await resolveDocPath(name);
|
|
48442
|
-
if (!resolved) {
|
|
48443
|
-
console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
|
|
48444
|
-
process.exit(1);
|
|
48828
|
+
var docCommand = new Command("doc").description("Manage documentation").argument("[name]", "Document name (shorthand for 'doc view <name>')").option("--plain", "Plain text output for AI").option("--info", "Show document stats (size, tokens, headings) without content").option("--toc", "Show table of contents only").option("--section <title>", "Show specific section by heading title or number").enablePositionalOptions().action(
|
|
48829
|
+
async (name, options2) => {
|
|
48830
|
+
if (!name) {
|
|
48831
|
+
docCommand.help();
|
|
48832
|
+
return;
|
|
48445
48833
|
}
|
|
48446
|
-
|
|
48447
|
-
|
|
48448
|
-
|
|
48449
|
-
|
|
48450
|
-
|
|
48451
|
-
const border = "-".repeat(50);
|
|
48452
|
-
const titleBorder = "=".repeat(50);
|
|
48453
|
-
const projectRoot = process.cwd();
|
|
48454
|
-
console.log(`File: ${projectRoot}/.knowns/docs/${filename}`);
|
|
48455
|
-
console.log();
|
|
48456
|
-
console.log(metadata.title);
|
|
48457
|
-
console.log(titleBorder);
|
|
48458
|
-
console.log();
|
|
48459
|
-
console.log(`Created: ${metadata.createdAt}`);
|
|
48460
|
-
console.log(`Updated: ${metadata.updatedAt}`);
|
|
48461
|
-
if (metadata.tags && metadata.tags.length > 0) {
|
|
48462
|
-
console.log(`Tags: ${metadata.tags.join(", ")}`);
|
|
48463
|
-
}
|
|
48464
|
-
if (metadata.description) {
|
|
48465
|
-
console.log();
|
|
48466
|
-
console.log("Description:");
|
|
48467
|
-
console.log(border);
|
|
48468
|
-
console.log(metadata.description);
|
|
48834
|
+
try {
|
|
48835
|
+
const resolved = await resolveDocPath(name);
|
|
48836
|
+
if (!resolved) {
|
|
48837
|
+
console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
|
|
48838
|
+
process.exit(1);
|
|
48469
48839
|
}
|
|
48470
|
-
|
|
48471
|
-
|
|
48472
|
-
|
|
48473
|
-
const
|
|
48474
|
-
|
|
48475
|
-
|
|
48476
|
-
|
|
48477
|
-
|
|
48478
|
-
|
|
48479
|
-
|
|
48480
|
-
|
|
48481
|
-
|
|
48482
|
-
|
|
48840
|
+
const { filepath, filename } = resolved;
|
|
48841
|
+
const fileContent = await readFile11(filepath, "utf-8");
|
|
48842
|
+
const { data, content } = (0, import_gray_matter6.default)(fileContent);
|
|
48843
|
+
const metadata = data;
|
|
48844
|
+
if (options2.info) {
|
|
48845
|
+
const stats = calculateDocStats(content);
|
|
48846
|
+
if (options2.plain) {
|
|
48847
|
+
console.log(formatDocStats(stats, metadata.title));
|
|
48848
|
+
} else {
|
|
48849
|
+
console.log(source_default.bold(`
|
|
48850
|
+
\u{1F4CA} ${metadata.title} - Document Info
|
|
48851
|
+
`));
|
|
48852
|
+
console.log(
|
|
48853
|
+
`Size: ${source_default.cyan(stats.chars.toLocaleString())} chars (~${source_default.yellow(stats.estimatedTokens.toLocaleString())} tokens)`
|
|
48854
|
+
);
|
|
48855
|
+
console.log(`Words: ${stats.words.toLocaleString()}`);
|
|
48856
|
+
console.log(`Lines: ${stats.lines.toLocaleString()}`);
|
|
48857
|
+
console.log(`Headings: ${stats.headingCount}`);
|
|
48858
|
+
console.log();
|
|
48859
|
+
if (stats.estimatedTokens > 4e3) {
|
|
48860
|
+
console.log(source_default.yellow("\u26A0 Document is large. Use --toc first, then --section."));
|
|
48861
|
+
} else if (stats.estimatedTokens > 2e3) {
|
|
48862
|
+
console.log(source_default.gray("Consider using --toc and --section for specific info."));
|
|
48863
|
+
} else {
|
|
48864
|
+
console.log(source_default.green("\u2713 Document is small enough to read directly."));
|
|
48865
|
+
}
|
|
48866
|
+
console.log();
|
|
48483
48867
|
}
|
|
48484
|
-
|
|
48485
|
-
|
|
48868
|
+
return;
|
|
48869
|
+
}
|
|
48870
|
+
if (options2.toc) {
|
|
48871
|
+
const toc = extractToc(content);
|
|
48872
|
+
if (toc.length === 0) {
|
|
48873
|
+
console.log(options2.plain ? "No headings found." : source_default.yellow("No headings found in this document."));
|
|
48874
|
+
return;
|
|
48486
48875
|
}
|
|
48487
|
-
|
|
48488
|
-
|
|
48489
|
-
|
|
48876
|
+
if (options2.plain) {
|
|
48877
|
+
console.log(`Table of Contents: ${metadata.title}`);
|
|
48878
|
+
console.log("=".repeat(50));
|
|
48879
|
+
console.log();
|
|
48880
|
+
toc.forEach((entry, index) => {
|
|
48881
|
+
const indent = " ".repeat(entry.level - 1);
|
|
48882
|
+
console.log(`${indent}${index + 1}. ${entry.title}`);
|
|
48883
|
+
});
|
|
48884
|
+
console.log();
|
|
48885
|
+
console.log("Use --section <number or title> to view a specific section.");
|
|
48886
|
+
} else {
|
|
48887
|
+
console.log(source_default.bold(`
|
|
48888
|
+
\u{1F4C4} ${metadata.title} - Table of Contents
|
|
48889
|
+
`));
|
|
48890
|
+
console.log(formatToc(toc));
|
|
48891
|
+
console.log(source_default.gray("\nUse --section <number or title> to view a specific section."));
|
|
48490
48892
|
}
|
|
48491
|
-
|
|
48492
|
-
linksToAdd.push({
|
|
48493
|
-
original: fullMatch,
|
|
48494
|
-
resolved: resolvedPath
|
|
48495
|
-
});
|
|
48496
|
-
}
|
|
48497
|
-
for (const { original, resolved: resolved2 } of linksToAdd) {
|
|
48498
|
-
enhancedContent = enhancedContent.replace(original, resolved2);
|
|
48893
|
+
return;
|
|
48499
48894
|
}
|
|
48500
|
-
|
|
48501
|
-
|
|
48502
|
-
|
|
48503
|
-
|
|
48504
|
-
|
|
48505
|
-
|
|
48895
|
+
if (options2.section) {
|
|
48896
|
+
const sectionContent = extractSection(content, options2.section);
|
|
48897
|
+
if (!sectionContent) {
|
|
48898
|
+
console.error(
|
|
48899
|
+
options2.plain ? `Section not found: ${options2.section}` : source_default.red(`\u2717 Section not found: ${options2.section}`)
|
|
48900
|
+
);
|
|
48901
|
+
console.log(
|
|
48902
|
+
options2.plain ? "Use --toc to see available sections." : source_default.gray("Use --toc to see available sections.")
|
|
48903
|
+
);
|
|
48904
|
+
process.exit(1);
|
|
48905
|
+
}
|
|
48906
|
+
if (options2.plain) {
|
|
48907
|
+
console.log(`File: ${process.cwd()}/.knowns/docs/${filename}`);
|
|
48908
|
+
console.log(`Section: ${options2.section}`);
|
|
48909
|
+
console.log("=".repeat(50));
|
|
48910
|
+
console.log();
|
|
48911
|
+
console.log(sectionContent);
|
|
48912
|
+
} else {
|
|
48913
|
+
console.log(source_default.bold(`
|
|
48914
|
+
\u{1F4C4} ${metadata.title} - Section
|
|
48915
|
+
`));
|
|
48916
|
+
console.log(sectionContent);
|
|
48917
|
+
console.log();
|
|
48918
|
+
}
|
|
48919
|
+
return;
|
|
48506
48920
|
}
|
|
48507
|
-
|
|
48508
|
-
|
|
48509
|
-
|
|
48921
|
+
if (options2.plain) {
|
|
48922
|
+
const border = "-".repeat(50);
|
|
48923
|
+
const titleBorder = "=".repeat(50);
|
|
48924
|
+
const projectRoot = process.cwd();
|
|
48925
|
+
console.log(`File: ${projectRoot}/.knowns/docs/${filename}`);
|
|
48926
|
+
console.log();
|
|
48927
|
+
console.log(metadata.title);
|
|
48928
|
+
console.log(titleBorder);
|
|
48929
|
+
console.log();
|
|
48930
|
+
console.log(`Created: ${metadata.createdAt}`);
|
|
48931
|
+
console.log(`Updated: ${metadata.updatedAt}`);
|
|
48932
|
+
if (metadata.tags && metadata.tags.length > 0) {
|
|
48933
|
+
console.log(`Tags: ${metadata.tags.join(", ")}`);
|
|
48934
|
+
}
|
|
48935
|
+
if (metadata.description) {
|
|
48936
|
+
console.log();
|
|
48937
|
+
console.log("Description:");
|
|
48938
|
+
console.log(border);
|
|
48939
|
+
console.log(metadata.description);
|
|
48940
|
+
}
|
|
48941
|
+
console.log();
|
|
48942
|
+
console.log("Content:");
|
|
48943
|
+
console.log(border);
|
|
48944
|
+
const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
48945
|
+
let enhancedContent = content.trimEnd();
|
|
48946
|
+
const linksToAdd = [];
|
|
48947
|
+
let match;
|
|
48948
|
+
while ((match = linkPattern.exec(content)) !== null) {
|
|
48949
|
+
const _linkText = match[1];
|
|
48950
|
+
const linkTarget = match[2];
|
|
48951
|
+
const fullMatch = match[0];
|
|
48952
|
+
if (linkTarget.startsWith("http://") || linkTarget.startsWith("https://")) {
|
|
48953
|
+
continue;
|
|
48954
|
+
}
|
|
48955
|
+
if (linkTarget.startsWith("../")) {
|
|
48956
|
+
continue;
|
|
48957
|
+
}
|
|
48958
|
+
let resolvedFilename = linkTarget.replace(/^\.\//, "");
|
|
48959
|
+
if (!resolvedFilename.endsWith(".md")) {
|
|
48960
|
+
resolvedFilename = `${resolvedFilename}.md`;
|
|
48961
|
+
}
|
|
48962
|
+
const resolvedPath = `@.knowns/docs/${resolvedFilename}`;
|
|
48963
|
+
linksToAdd.push({
|
|
48964
|
+
original: fullMatch,
|
|
48965
|
+
resolved: resolvedPath
|
|
48966
|
+
});
|
|
48967
|
+
}
|
|
48968
|
+
for (const { original, resolved: resolved2 } of linksToAdd) {
|
|
48969
|
+
enhancedContent = enhancedContent.replace(original, resolved2);
|
|
48970
|
+
}
|
|
48971
|
+
const knownProjectRoot = findProjectRoot();
|
|
48972
|
+
if (knownProjectRoot) {
|
|
48973
|
+
const fileStore2 = new FileStore(knownProjectRoot);
|
|
48974
|
+
const allTasks = await fileStore2.getAllTasks();
|
|
48975
|
+
const taskMap = buildTaskMap(allTasks);
|
|
48976
|
+
enhancedContent = transformMentionsToRefs(enhancedContent, taskMap);
|
|
48977
|
+
}
|
|
48978
|
+
console.log(enhancedContent);
|
|
48979
|
+
} else {
|
|
48980
|
+
console.log(source_default.bold(`
|
|
48510
48981
|
\u{1F4C4} ${metadata.title}
|
|
48511
48982
|
`));
|
|
48512
|
-
|
|
48513
|
-
|
|
48983
|
+
if (metadata.description) {
|
|
48984
|
+
console.log(source_default.gray(metadata.description));
|
|
48985
|
+
console.log();
|
|
48986
|
+
}
|
|
48987
|
+
if (metadata.tags && metadata.tags.length > 0) {
|
|
48988
|
+
console.log(source_default.gray(`Tags: ${metadata.tags.join(", ")}`));
|
|
48989
|
+
}
|
|
48990
|
+
console.log(source_default.gray(`Updated: ${new Date(metadata.updatedAt).toLocaleString()}`));
|
|
48991
|
+
console.log(source_default.gray("-".repeat(60)));
|
|
48992
|
+
console.log(content);
|
|
48514
48993
|
console.log();
|
|
48515
48994
|
}
|
|
48516
|
-
|
|
48517
|
-
|
|
48518
|
-
|
|
48519
|
-
|
|
48520
|
-
|
|
48521
|
-
|
|
48522
|
-
console.log();
|
|
48995
|
+
} catch (error48) {
|
|
48996
|
+
console.error(
|
|
48997
|
+
source_default.red("Error viewing documentation:"),
|
|
48998
|
+
error48 instanceof Error ? error48.message : String(error48)
|
|
48999
|
+
);
|
|
49000
|
+
process.exit(1);
|
|
48523
49001
|
}
|
|
48524
|
-
} catch (error48) {
|
|
48525
|
-
console.error(source_default.red("Error viewing documentation:"), error48 instanceof Error ? error48.message : String(error48));
|
|
48526
|
-
process.exit(1);
|
|
48527
49002
|
}
|
|
48528
|
-
|
|
49003
|
+
);
|
|
48529
49004
|
docCommand.addCommand(createCommand3);
|
|
48530
49005
|
docCommand.addCommand(listCommand2);
|
|
48531
49006
|
docCommand.addCommand(viewCommand2);
|
|
@@ -49194,7 +49669,7 @@ __export(util_exports, {
|
|
|
49194
49669
|
required: () => required,
|
|
49195
49670
|
safeExtend: () => safeExtend,
|
|
49196
49671
|
shallowClone: () => shallowClone,
|
|
49197
|
-
slugify: () =>
|
|
49672
|
+
slugify: () => slugify2,
|
|
49198
49673
|
stringifyPrimitive: () => stringifyPrimitive,
|
|
49199
49674
|
uint8ArrayToBase64: () => uint8ArrayToBase64,
|
|
49200
49675
|
uint8ArrayToBase64url: () => uint8ArrayToBase64url,
|
|
@@ -49335,7 +49810,7 @@ function randomString(length = 10) {
|
|
|
49335
49810
|
function esc(str2) {
|
|
49336
49811
|
return JSON.stringify(str2);
|
|
49337
49812
|
}
|
|
49338
|
-
function
|
|
49813
|
+
function slugify2(input) {
|
|
49339
49814
|
return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
49340
49815
|
}
|
|
49341
49816
|
var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {
|
|
@@ -59069,7 +59544,7 @@ function _toUpperCase() {
|
|
|
59069
59544
|
}
|
|
59070
59545
|
// @__NO_SIDE_EFFECTS__
|
|
59071
59546
|
function _slugify() {
|
|
59072
|
-
return /* @__PURE__ */ _overwrite((input) =>
|
|
59547
|
+
return /* @__PURE__ */ _overwrite((input) => slugify2(input));
|
|
59073
59548
|
}
|
|
59074
59549
|
// @__NO_SIDE_EFFECTS__
|
|
59075
59550
|
function _array(Class2, element, params) {
|
|
@@ -70196,8 +70671,14 @@ var listDocsSchema = external_exports.object({
|
|
|
70196
70671
|
tag: external_exports.string().optional()
|
|
70197
70672
|
});
|
|
70198
70673
|
var getDocSchema = external_exports.object({
|
|
70199
|
-
path: external_exports.string()
|
|
70674
|
+
path: external_exports.string(),
|
|
70200
70675
|
// Document path (filename or folder/filename)
|
|
70676
|
+
info: external_exports.boolean().optional(),
|
|
70677
|
+
// Return document stats (size, tokens, headings) without content
|
|
70678
|
+
toc: external_exports.boolean().optional(),
|
|
70679
|
+
// Return table of contents only
|
|
70680
|
+
section: external_exports.string().optional()
|
|
70681
|
+
// Return specific section by heading title or number
|
|
70201
70682
|
});
|
|
70202
70683
|
var createDocSchema = external_exports.object({
|
|
70203
70684
|
title: external_exports.string(),
|
|
@@ -70214,8 +70695,10 @@ var updateDocSchema = external_exports.object({
|
|
|
70214
70695
|
description: external_exports.string().optional(),
|
|
70215
70696
|
content: external_exports.string().optional(),
|
|
70216
70697
|
tags: external_exports.array(external_exports.string()).optional(),
|
|
70217
|
-
appendContent: external_exports.string().optional()
|
|
70698
|
+
appendContent: external_exports.string().optional(),
|
|
70218
70699
|
// Append to existing content
|
|
70700
|
+
section: external_exports.string().optional()
|
|
70701
|
+
// Target section to replace (use with content)
|
|
70219
70702
|
});
|
|
70220
70703
|
var searchDocsSchema = external_exports.object({
|
|
70221
70704
|
query: external_exports.string(),
|
|
@@ -70234,13 +70717,25 @@ var docTools = [
|
|
|
70234
70717
|
},
|
|
70235
70718
|
{
|
|
70236
70719
|
name: "get_doc",
|
|
70237
|
-
description: "Get a documentation file by path
|
|
70720
|
+
description: "Get a documentation file by path. Use 'info: true' first to check size, then 'toc: true' for table of contents, then 'section' to read specific parts.",
|
|
70238
70721
|
inputSchema: {
|
|
70239
70722
|
type: "object",
|
|
70240
70723
|
properties: {
|
|
70241
70724
|
path: {
|
|
70242
70725
|
type: "string",
|
|
70243
70726
|
description: "Document path (e.g., 'readme', 'guides/setup', 'conventions/naming.md')"
|
|
70727
|
+
},
|
|
70728
|
+
info: {
|
|
70729
|
+
type: "boolean",
|
|
70730
|
+
description: "Return document stats (size, tokens, headings) without content. Use this first to decide how to read."
|
|
70731
|
+
},
|
|
70732
|
+
toc: {
|
|
70733
|
+
type: "boolean",
|
|
70734
|
+
description: "Return table of contents only (list of headings). Use this first for large documents."
|
|
70735
|
+
},
|
|
70736
|
+
section: {
|
|
70737
|
+
type: "string",
|
|
70738
|
+
description: "Return specific section by heading title or number (e.g., '2. Overview' or '2'). Use after viewing TOC."
|
|
70244
70739
|
}
|
|
70245
70740
|
},
|
|
70246
70741
|
required: ["path"]
|
|
@@ -70270,7 +70765,7 @@ var docTools = [
|
|
|
70270
70765
|
},
|
|
70271
70766
|
{
|
|
70272
70767
|
name: "update_doc",
|
|
70273
|
-
description: "Update an existing documentation file",
|
|
70768
|
+
description: "Update an existing documentation file. Use 'section' with 'content' to replace only a specific section.",
|
|
70274
70769
|
inputSchema: {
|
|
70275
70770
|
type: "object",
|
|
70276
70771
|
properties: {
|
|
@@ -70280,7 +70775,10 @@ var docTools = [
|
|
|
70280
70775
|
},
|
|
70281
70776
|
title: { type: "string", description: "New title" },
|
|
70282
70777
|
description: { type: "string", description: "New description" },
|
|
70283
|
-
content: {
|
|
70778
|
+
content: {
|
|
70779
|
+
type: "string",
|
|
70780
|
+
description: "Replace content (or section content if 'section' is specified)"
|
|
70781
|
+
},
|
|
70284
70782
|
tags: {
|
|
70285
70783
|
type: "array",
|
|
70286
70784
|
items: { type: "string" },
|
|
@@ -70289,6 +70787,10 @@ var docTools = [
|
|
|
70289
70787
|
appendContent: {
|
|
70290
70788
|
type: "string",
|
|
70291
70789
|
description: "Append to existing content"
|
|
70790
|
+
},
|
|
70791
|
+
section: {
|
|
70792
|
+
type: "string",
|
|
70793
|
+
description: "Target section to replace by heading title or number (use with 'content')"
|
|
70292
70794
|
}
|
|
70293
70795
|
},
|
|
70294
70796
|
required: ["path"]
|
|
@@ -70401,6 +70903,70 @@ async function handleGetDoc(args2) {
|
|
|
70401
70903
|
const fileContent = await readFile14(resolved.filepath, "utf-8");
|
|
70402
70904
|
const { data, content } = (0, import_gray_matter8.default)(fileContent);
|
|
70403
70905
|
const metadata = data;
|
|
70906
|
+
if (input.info) {
|
|
70907
|
+
const stats = calculateDocStats(content);
|
|
70908
|
+
let recommendation;
|
|
70909
|
+
if (stats.estimatedTokens > 4e3) {
|
|
70910
|
+
recommendation = "Document is large. Use 'toc: true' first, then 'section' to read specific parts.";
|
|
70911
|
+
} else if (stats.estimatedTokens > 2e3) {
|
|
70912
|
+
recommendation = "Consider using 'toc: true' and 'section' for specific info.";
|
|
70913
|
+
} else {
|
|
70914
|
+
recommendation = "Document is small enough to read directly.";
|
|
70915
|
+
}
|
|
70916
|
+
return successResponse({
|
|
70917
|
+
doc: {
|
|
70918
|
+
path: resolved.filename.replace(/\.md$/, ""),
|
|
70919
|
+
title: metadata.title,
|
|
70920
|
+
stats: {
|
|
70921
|
+
chars: stats.chars,
|
|
70922
|
+
words: stats.words,
|
|
70923
|
+
lines: stats.lines,
|
|
70924
|
+
estimatedTokens: stats.estimatedTokens,
|
|
70925
|
+
headingCount: stats.headingCount
|
|
70926
|
+
},
|
|
70927
|
+
recommendation
|
|
70928
|
+
}
|
|
70929
|
+
});
|
|
70930
|
+
}
|
|
70931
|
+
if (input.toc) {
|
|
70932
|
+
const toc = extractToc(content);
|
|
70933
|
+
if (toc.length === 0) {
|
|
70934
|
+
return successResponse({
|
|
70935
|
+
doc: {
|
|
70936
|
+
path: resolved.filename.replace(/\.md$/, ""),
|
|
70937
|
+
title: metadata.title,
|
|
70938
|
+
toc: [],
|
|
70939
|
+
message: "No headings found in this document."
|
|
70940
|
+
}
|
|
70941
|
+
});
|
|
70942
|
+
}
|
|
70943
|
+
return successResponse({
|
|
70944
|
+
doc: {
|
|
70945
|
+
path: resolved.filename.replace(/\.md$/, ""),
|
|
70946
|
+
title: metadata.title,
|
|
70947
|
+
toc: toc.map((entry, index) => ({
|
|
70948
|
+
index: index + 1,
|
|
70949
|
+
level: entry.level,
|
|
70950
|
+
title: entry.title
|
|
70951
|
+
})),
|
|
70952
|
+
hint: "Use 'section' parameter with a heading title or number to read specific content."
|
|
70953
|
+
}
|
|
70954
|
+
});
|
|
70955
|
+
}
|
|
70956
|
+
if (input.section) {
|
|
70957
|
+
const sectionContent = extractSection(content, input.section);
|
|
70958
|
+
if (!sectionContent) {
|
|
70959
|
+
return errorResponse(`Section not found: ${input.section}. Use 'toc: true' to see available sections.`);
|
|
70960
|
+
}
|
|
70961
|
+
return successResponse({
|
|
70962
|
+
doc: {
|
|
70963
|
+
path: resolved.filename.replace(/\.md$/, ""),
|
|
70964
|
+
title: metadata.title,
|
|
70965
|
+
section: input.section,
|
|
70966
|
+
content: sectionContent
|
|
70967
|
+
}
|
|
70968
|
+
});
|
|
70969
|
+
}
|
|
70404
70970
|
return successResponse({
|
|
70405
70971
|
doc: {
|
|
70406
70972
|
path: resolved.filename.replace(/\.md$/, ""),
|
|
@@ -70471,11 +71037,21 @@ async function handleUpdateDoc(args2) {
|
|
|
70471
71037
|
if (input.tags) metadata.tags = input.tags;
|
|
70472
71038
|
metadata.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
70473
71039
|
let updatedContent = content;
|
|
70474
|
-
|
|
71040
|
+
let sectionUpdated;
|
|
71041
|
+
if (input.section && input.content) {
|
|
71042
|
+
const result = replaceSection(content, input.section, input.content);
|
|
71043
|
+
if (!result) {
|
|
71044
|
+
return errorResponse(
|
|
71045
|
+
`Section not found: ${input.section}. Use 'toc: true' with get_doc to see available sections.`
|
|
71046
|
+
);
|
|
71047
|
+
}
|
|
71048
|
+
updatedContent = result;
|
|
71049
|
+
sectionUpdated = input.section;
|
|
71050
|
+
} else if (input.content) {
|
|
70475
71051
|
updatedContent = input.content;
|
|
70476
71052
|
}
|
|
70477
71053
|
if (input.appendContent) {
|
|
70478
|
-
updatedContent = `${
|
|
71054
|
+
updatedContent = `${updatedContent.trimEnd()}
|
|
70479
71055
|
|
|
70480
71056
|
${input.appendContent}`;
|
|
70481
71057
|
}
|
|
@@ -70483,13 +71059,14 @@ ${input.appendContent}`;
|
|
|
70483
71059
|
await writeFile10(resolved.filepath, newFileContent, "utf-8");
|
|
70484
71060
|
await notifyDocUpdate(resolved.filename);
|
|
70485
71061
|
return successResponse({
|
|
70486
|
-
message: `Updated documentation: ${resolved.filename}`,
|
|
71062
|
+
message: sectionUpdated ? `Updated section "${sectionUpdated}" in ${resolved.filename}` : `Updated documentation: ${resolved.filename}`,
|
|
70487
71063
|
doc: {
|
|
70488
71064
|
path: resolved.filename.replace(/\.md$/, ""),
|
|
70489
71065
|
title: metadata.title,
|
|
70490
71066
|
description: metadata.description,
|
|
70491
71067
|
tags: metadata.tags,
|
|
70492
|
-
updatedAt: metadata.updatedAt
|
|
71068
|
+
updatedAt: metadata.updatedAt,
|
|
71069
|
+
...sectionUpdated && { section: sectionUpdated }
|
|
70493
71070
|
}
|
|
70494
71071
|
});
|
|
70495
71072
|
}
|
|
@@ -70558,7 +71135,18 @@ var guidelineTools = [
|
|
|
70558
71135
|
];
|
|
70559
71136
|
async function handleGetGuideline(args2) {
|
|
70560
71137
|
const input = getGuidelineSchema.parse(args2 || {});
|
|
70561
|
-
|
|
71138
|
+
let guidelines;
|
|
71139
|
+
switch (input.type) {
|
|
71140
|
+
case "mcp":
|
|
71141
|
+
guidelines = MCPGuidelines.getFull();
|
|
71142
|
+
break;
|
|
71143
|
+
case "cli":
|
|
71144
|
+
guidelines = Guidelines.getFull();
|
|
71145
|
+
break;
|
|
71146
|
+
default:
|
|
71147
|
+
guidelines = MCPGuidelines.getFull();
|
|
71148
|
+
break;
|
|
71149
|
+
}
|
|
70562
71150
|
return {
|
|
70563
71151
|
content: [
|
|
70564
71152
|
{
|
|
@@ -71016,7 +71604,7 @@ async function notifyCliUpdate(options2) {
|
|
|
71016
71604
|
// package.json
|
|
71017
71605
|
var package_default = {
|
|
71018
71606
|
name: "knowns",
|
|
71019
|
-
version: "0.8.
|
|
71607
|
+
version: "0.8.7",
|
|
71020
71608
|
description: "AI-native task and documentation management for dev teams",
|
|
71021
71609
|
module: "index.ts",
|
|
71022
71610
|
type: "module",
|
|
@@ -71147,7 +71735,7 @@ var BANNER = `
|
|
|
71147
71735
|
function showBanner() {
|
|
71148
71736
|
console.log(source_default.cyan(BANNER));
|
|
71149
71737
|
console.log(source_default.bold(" Knowns CLI") + source_default.gray(` v${package_default.version}`));
|
|
71150
|
-
console.log(source_default.gray(' "
|
|
71738
|
+
console.log(source_default.gray(' "What your AI should have knowns."'));
|
|
71151
71739
|
console.log();
|
|
71152
71740
|
console.log(source_default.gray(" Open-source CLI for dev teams"));
|
|
71153
71741
|
console.log(source_default.gray(" Tasks \u2022 Time \u2022 Docs \u2022 Sync"));
|