knowns 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/index.js +489 -220
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2] - 2024-12-26
9
+
10
+ ### Added
11
+ - New `src/constants/knowns-guidelines.ts` file containing system prompt as TypeScript constant
12
+ - Auto-sync of Knowns guidelines to AI instruction files during `knowns init`
13
+ - Third step in "Next steps" output: "Update AI instructions: knowns agents --update-instructions"
14
+
15
+ ### Changed
16
+ - Refactored `agents` command to use bundled constant instead of reading from CLAUDE.md
17
+ - CLAUDE.md is now a target file (not source) - gets updated like other AI instruction files
18
+ - Exported `updateInstructionFile()` and `INSTRUCTION_FILES` from agents.ts for reusability
19
+ - System prompt now bundled into binary, eliminating file I/O during sync
20
+
21
+ ### Improved
22
+ - Faster agent instruction updates (no file reads required)
23
+ - More reliable init process - new projects get AI instructions automatically
24
+ - Simplified architecture: single source of truth for guidelines in codebase
25
+
8
26
  ## [0.1.1] - 2024-12-26
9
27
 
10
28
  ### Added
@@ -51,5 +69,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
51
69
  - CLAUDE.md with complete guidelines for AI agents
52
70
  - Example workflows and patterns
53
71
 
72
+ [0.1.2]: https://github.com/knowns-dev/knowns/compare/v0.1.1...v0.1.2
54
73
  [0.1.1]: https://github.com/knowns-dev/knowns/compare/v0.1.0...v0.1.1
55
74
  [0.1.0]: https://github.com/knowns-dev/knowns/releases/tag/v0.1.0
package/dist/index.js CHANGED
@@ -5341,8 +5341,8 @@ var require_commander = __commonJS((exports) => {
5341
5341
  });
5342
5342
 
5343
5343
  // src/commands/init.ts
5344
- import { existsSync } from "fs";
5345
- import { join as join3 } from "path";
5344
+ import { existsSync as existsSync2 } from "fs";
5345
+ import { join as join4 } from "path";
5346
5346
 
5347
5347
  // src/storage/file-store.ts
5348
5348
  import { mkdir as mkdir2, readdir } from "fs/promises";
@@ -6506,12 +6506,381 @@ var {
6506
6506
  Help
6507
6507
  } = import__.default;
6508
6508
 
6509
+ // src/constants/knowns-guidelines.ts
6510
+ var KNOWNS_GUIDELINES = `<!-- KNOWNS GUIDELINES START -->
6511
+ # Knowns CLI Guidelines
6512
+
6513
+ ## Core Principle
6514
+
6515
+ **NEVER edit .md files directly. ALL operations MUST use CLI commands.**
6516
+
6517
+ ---
6518
+
6519
+ ## Project Structure
6520
+
6521
+ \`\`\`
6522
+ .knowns/
6523
+ \u251C\u2500\u2500 tasks/ # Task files: task-<id> - <title>.md
6524
+ \u251C\u2500\u2500 docs/ # Documentation (supports nested folders)
6525
+ \u2514\u2500\u2500 decisions/ # Architecture decision records
6526
+ \`\`\`
6527
+
6528
+ ---
6529
+
6530
+ ## Task Management
6531
+
6532
+ ### Task Lifecycle
6533
+
6534
+ 1. **Create** \u2192 \`knowns task create "Title" -d "Description" --ac "Criterion 1" --ac "Criterion 2"\`
6535
+ 2. **Start** \u2192 \`knowns task edit <id> -s "In Progress" -a @yourself\`
6536
+ 3. **Work** \u2192 Check acceptance criteria as you complete them
6537
+ 4. **Complete** \u2192 Mark status as Done after all criteria met
6538
+
6539
+ ### Critical Commands
6540
+
6541
+ \`\`\`bash
6542
+ # View task (always use --plain for AI)
6543
+ knowns task view <id> --plain
6544
+
6545
+ # List tasks
6546
+ knowns task list --plain
6547
+ knowns task list -s "In Progress" --plain
6548
+
6549
+ # Search tasks/docs
6550
+ knowns search "query" --plain
6551
+ knowns search "query" --type task --plain
6552
+
6553
+ # Edit task
6554
+ knowns task edit <id> -s "In Progress" -a @agent
6555
+ knowns task edit <id> -t "New Title"
6556
+ knowns task edit <id> -d "Description"
6557
+
6558
+ # Acceptance criteria
6559
+ knowns task edit <id> --ac "New criterion"
6560
+ knowns task edit <id> --check-ac 1
6561
+ knowns task edit <id> --check-ac 1 --check-ac 2 --check-ac 3
6562
+ knowns task edit <id> --uncheck-ac 2
6563
+ knowns task edit <id> --remove-ac 3
6564
+
6565
+ # Implementation
6566
+ knowns task edit <id> --plan $'1. Step one\\n2. Step two'
6567
+ knowns task edit <id> --notes "Implementation summary"
6568
+ knowns task edit <id> --append-notes $'Additional note\\nAnother line'
6569
+ \`\`\`
6570
+
6571
+ ### Multi-line Input (Shell-specific)
6572
+
6573
+ **Bash/Zsh** - Use \`$'...\\n...'\`:
6574
+ \`\`\`bash
6575
+ knowns task edit 42 --desc $'Line 1\\nLine 2\\n\\nLine 3'
6576
+ knowns task edit 42 --plan $'1. First\\n2. Second'
6577
+ knowns task edit 42 --notes $'Done A\\nDoing B'
6578
+ \`\`\`
6579
+
6580
+ **PowerShell** - Use backtick-n:
6581
+ \`\`\`powershell
6582
+ knowns task edit 42 --notes "Line1\`nLine2"
6583
+ \`\`\`
6584
+
6585
+ **Portable** - Use printf:
6586
+ \`\`\`bash
6587
+ knowns task edit 42 --notes "$(printf 'Line1\\nLine2')"
6588
+ \`\`\`
6589
+
6590
+ ---
6591
+
6592
+ ## Task Workflow
6593
+
6594
+ ### Step 1: Take Task
6595
+ \`\`\`bash
6596
+ knowns task edit <id> -s "In Progress" -a @yourself
6597
+ \`\`\`
6598
+
6599
+ ### Step 2: Create Plan
6600
+ \`\`\`bash
6601
+ knowns task edit <id> --plan $'1. Research\\n2. Implement\\n3. Test'
6602
+ \`\`\`
6603
+
6604
+ **IMPORTANT**: Share plan with user and wait for approval before coding.
6605
+
6606
+ ### Step 3: Implementation
6607
+ Write code, then check acceptance criteria:
6608
+ \`\`\`bash
6609
+ knowns task edit <id> --check-ac 1 --check-ac 2 --check-ac 3
6610
+ \`\`\`
6611
+
6612
+ ### Step 4: Add Notes (PR Description)
6613
+ \`\`\`bash
6614
+ knowns task edit <id> --notes $'Implemented using X pattern\\nUpdated tests\\nReady for review'
6615
+ \`\`\`
6616
+
6617
+ Or append progressively:
6618
+ \`\`\`bash
6619
+ knowns task edit <id> --append-notes "Completed feature X"
6620
+ knowns task edit <id> --append-notes "Added tests"
6621
+ \`\`\`
6622
+
6623
+ ### Step 5: Complete
6624
+ \`\`\`bash
6625
+ knowns task edit <id> -s Done
6626
+ \`\`\`
6627
+
6628
+ ---
6629
+
6630
+ ## Definition of Done
6631
+
6632
+ Task is Done ONLY when ALL items are complete:
6633
+
6634
+ **Via CLI:**
6635
+ 1. All acceptance criteria checked: \`--check-ac <index>\`
6636
+ 2. Implementation notes added: \`--notes "..."\`
6637
+ 3. Status set to Done: \`-s Done\`
6638
+
6639
+ **Via Code:**
6640
+ 4. Tests pass
6641
+ 5. Documentation updated
6642
+ 6. Code reviewed
6643
+ 7. No regressions
6644
+
6645
+ ---
6646
+
6647
+ ## Documentation Management
6648
+
6649
+ ### Commands
6650
+
6651
+ \`\`\`bash
6652
+ # List all docs (includes nested folders)
6653
+ knowns doc list --plain
6654
+
6655
+ # View document
6656
+ knowns doc view <name> --plain
6657
+ knowns doc view patterns/guards --plain
6658
+ knowns doc view patterns/guards.md --plain
6659
+
6660
+ # Create document
6661
+ knowns doc create "Title" -d "Description" -t "tag1,tag2"
6662
+
6663
+ # Edit metadata
6664
+ knowns doc edit <name> -t "New Title" -d "New Description"
6665
+ \`\`\`
6666
+
6667
+ ### Document Links
6668
+
6669
+ In \`--plain\` mode, markdown links are replaced with resolved paths:
6670
+ - \`[guards.md](./patterns/guards.md)\` \u2192 \`@.knowns/docs/patterns/guards.md\`
6671
+
6672
+ ---
6673
+
6674
+ ## Task Structure
6675
+
6676
+ ### Title
6677
+ Brief, clear summary of the task.
6678
+
6679
+ ### Description
6680
+ Explains WHY and WHAT (not HOW). Provides context.
6681
+
6682
+ ### Acceptance Criteria
6683
+ **Outcome-oriented**, testable, user-focused criteria.
6684
+
6685
+ Good:
6686
+ - "User can login with valid credentials"
6687
+ - "System processes 1000 requests/sec without errors"
6688
+
6689
+ Bad:
6690
+ - "Add function handleLogin() in auth.ts" (implementation detail)
6691
+
6692
+ ### Implementation Plan (added during work)
6693
+ **HOW** to solve the task. Added AFTER taking the task, BEFORE coding.
6694
+
6695
+ ### Implementation Notes (PR description)
6696
+ Summary of what was done, suitable for PR. Added AFTER completion.
6697
+
6698
+ ---
6699
+
6700
+ ## Common Mistakes
6701
+
6702
+ | Wrong | Right |
6703
+ |-------|-------|
6704
+ | Edit .md files directly | Use \`knowns task edit\` |
6705
+ | Change \`- [ ]\` to \`- [x]\` in file | Use \`--check-ac <index>\` |
6706
+ | Add plan during creation | Add plan when starting work |
6707
+ | Mark Done without all criteria | Check ALL criteria first |
6708
+
6709
+ ---
6710
+
6711
+ ## Search
6712
+
6713
+ \`\`\`bash
6714
+ # Search everything
6715
+ knowns search "auth" --plain
6716
+
6717
+ # Search tasks only
6718
+ knowns search "login" --type task --plain
6719
+
6720
+ # Search with filters
6721
+ knowns search "api" --status "In Progress" --plain
6722
+ knowns search "bug" --priority high --plain
6723
+ \`\`\`
6724
+
6725
+ ---
6726
+
6727
+ ## Required Patterns
6728
+
6729
+ ### When Starting Task
6730
+ \`\`\`bash
6731
+ # Step 1: Assign and set in progress
6732
+ knowns task edit <id> -s "In Progress" -a @yourself
6733
+
6734
+ # Step 2: Add implementation plan
6735
+ knowns task edit <id> --plan $'1. Research codebase\\n2. Implement\\n3. Test'
6736
+
6737
+ # Step 3: Share plan with user, WAIT for approval
6738
+ # Step 4: Start coding only after approval
6739
+ \`\`\`
6740
+
6741
+ ### When Completing Task
6742
+ \`\`\`bash
6743
+ # Step 1: Check all acceptance criteria
6744
+ knowns task edit <id> --check-ac 1 --check-ac 2 --check-ac 3
6745
+
6746
+ # Step 2: Add implementation notes (PR description)
6747
+ knowns task edit <id> --notes $'Summary of changes\\nTesting approach\\nFollow-up needed'
6748
+
6749
+ # Step 3: Mark as done
6750
+ knowns task edit <id> -s Done
6751
+ \`\`\`
6752
+
6753
+ ### Only Implement What's In Acceptance Criteria
6754
+ If you need to do more:
6755
+ 1. Update AC first: \`knowns task edit <id> --ac "New requirement"\`
6756
+ 2. Or create new task: \`knowns task create "Additional feature"\`
6757
+
6758
+ ---
6759
+
6760
+ ## Tips
6761
+
6762
+ - Always use \`--plain\` flag for AI-readable output
6763
+ - AC flags accept multiple values: \`--check-ac 1 --check-ac 2\`
6764
+ - Mixed operations work: \`--check-ac 1 --uncheck-ac 2 --remove-ac 3\`
6765
+ - Use \`$'...\\n...'\` for multi-line input in Bash/Zsh
6766
+ - Related docs show as \`@.knowns/docs/path/to/file.md\` in plain mode
6767
+
6768
+ ---
6769
+
6770
+ ## Full Help
6771
+
6772
+ \`\`\`bash
6773
+ knowns --help
6774
+ knowns task --help
6775
+ knowns doc --help
6776
+ knowns search --help
6777
+ \`\`\`
6778
+ <!-- KNOWNS GUIDELINES END -->
6779
+ `;
6780
+
6781
+ // src/commands/agents.ts
6782
+ import { existsSync } from "fs";
6783
+ import { mkdir as mkdir3, readFile, writeFile } from "fs/promises";
6784
+ import { dirname, join as join3 } from "path";
6785
+ var PROJECT_ROOT = process.cwd();
6786
+ var INSTRUCTION_FILES = [
6787
+ { path: "CLAUDE.md", name: "Claude Code" },
6788
+ { path: "AGENTS.md", name: "Agent SDK" },
6789
+ { path: "GEMINI.md", name: "Gemini" },
6790
+ { path: ".github/copilot-instructions.md", name: "GitHub Copilot" }
6791
+ ];
6792
+ async function updateInstructionFile(filePath, guidelines) {
6793
+ const fullPath = join3(PROJECT_ROOT, filePath);
6794
+ const startMarker = "<!-- KNOWNS GUIDELINES START -->";
6795
+ const endMarker = "<!-- KNOWNS GUIDELINES END -->";
6796
+ const dir = dirname(fullPath);
6797
+ if (!existsSync(dir)) {
6798
+ await mkdir3(dir, { recursive: true });
6799
+ }
6800
+ if (!existsSync(fullPath)) {
6801
+ await writeFile(fullPath, guidelines, "utf-8");
6802
+ return { success: true, action: "created" };
6803
+ }
6804
+ const content = await readFile(fullPath, "utf-8");
6805
+ const startIndex = content.indexOf(startMarker);
6806
+ const endIndex = content.indexOf(endMarker);
6807
+ if (startIndex === -1 || endIndex === -1) {
6808
+ const newContent2 = `${content.trimEnd()}
6809
+
6810
+ ${guidelines}
6811
+ `;
6812
+ await writeFile(fullPath, newContent2, "utf-8");
6813
+ return { success: true, action: "appended" };
6814
+ }
6815
+ const before = content.substring(0, startIndex);
6816
+ const after = content.substring(endIndex + endMarker.length);
6817
+ const newContent = before + guidelines + after;
6818
+ await writeFile(fullPath, newContent, "utf-8");
6819
+ return { success: true, action: "updated" };
6820
+ }
6821
+ var updateInstructionsCommand = new Command("agents").description("Manage agent instruction files").option("--update-instructions", "Update agent instruction files").action(async (options2) => {
6822
+ if (!options2.updateInstructions) {
6823
+ console.log(source_default.yellow("No action specified. Use --update-instructions to update files."));
6824
+ console.log(source_default.gray(`
6825
+ Example: knowns agents --update-instructions`));
6826
+ return;
6827
+ }
6828
+ try {
6829
+ console.log(source_default.bold(`
6830
+ Updating agent instruction files...
6831
+ `));
6832
+ let createdCount = 0;
6833
+ let appendedCount = 0;
6834
+ let updatedCount = 0;
6835
+ let errorCount = 0;
6836
+ for (const file of INSTRUCTION_FILES) {
6837
+ try {
6838
+ const result = await updateInstructionFile(file.path, KNOWNS_GUIDELINES);
6839
+ if (result.success) {
6840
+ if (result.action === "created") {
6841
+ createdCount++;
6842
+ console.log(source_default.green(`\u2713 Created ${file.name}: ${file.path}`));
6843
+ } else if (result.action === "appended") {
6844
+ appendedCount++;
6845
+ console.log(source_default.cyan(`\u2713 Appended ${file.name}: ${file.path}`));
6846
+ } else {
6847
+ updatedCount++;
6848
+ console.log(source_default.green(`\u2713 Updated ${file.name}: ${file.path}`));
6849
+ }
6850
+ }
6851
+ } catch (error) {
6852
+ errorCount++;
6853
+ console.error(source_default.red(`\u2717 Failed ${file.name}: ${file.path}`), error instanceof Error ? error.message : String(error));
6854
+ }
6855
+ }
6856
+ console.log(source_default.bold(`
6857
+ Summary:`));
6858
+ if (createdCount > 0) {
6859
+ console.log(source_default.green(` Created: ${createdCount}`));
6860
+ }
6861
+ if (appendedCount > 0) {
6862
+ console.log(source_default.cyan(` Appended: ${appendedCount}`));
6863
+ }
6864
+ if (updatedCount > 0) {
6865
+ console.log(source_default.green(` Updated: ${updatedCount}`));
6866
+ }
6867
+ if (errorCount > 0) {
6868
+ console.log(source_default.red(` Failed: ${errorCount}`));
6869
+ }
6870
+ console.log();
6871
+ } catch (error) {
6872
+ console.error(source_default.red("Error updating instruction files:"), error instanceof Error ? error.message : String(error));
6873
+ process.exit(1);
6874
+ }
6875
+ });
6876
+ var agentsCommand = updateInstructionsCommand;
6877
+
6509
6878
  // src/commands/init.ts
6510
6879
  var initCommand = new Command("init").description("Initialize .knowns/ folder in current directory").argument("[name]", "Project name", "My Project").action(async (name) => {
6511
6880
  try {
6512
6881
  const projectRoot = process.cwd();
6513
- const knownsPath = join3(projectRoot, ".knowns");
6514
- if (existsSync(knownsPath)) {
6882
+ const knownsPath = join4(projectRoot, ".knowns");
6883
+ if (existsSync2(knownsPath)) {
6515
6884
  console.log(source_default.yellow("\u26A0\uFE0F Project already initialized"));
6516
6885
  console.log(source_default.gray(` Location: ${knownsPath}`));
6517
6886
  return;
@@ -6522,9 +6891,28 @@ var initCommand = new Command("init").description("Initialize .knowns/ folder in
6522
6891
  console.log(source_default.gray(` Name: ${project.name}`));
6523
6892
  console.log(source_default.gray(` Location: ${knownsPath}`));
6524
6893
  console.log();
6894
+ console.log(source_default.bold("Updating AI instruction files..."));
6895
+ console.log();
6896
+ let syncedCount = 0;
6897
+ for (const file of INSTRUCTION_FILES) {
6898
+ try {
6899
+ const result = await updateInstructionFile(file.path, KNOWNS_GUIDELINES);
6900
+ if (result.success) {
6901
+ syncedCount++;
6902
+ const action = result.action === "created" ? "Created" : result.action === "appended" ? "Appended" : "Updated";
6903
+ console.log(source_default.green(`\u2713 ${action} ${file.name}: ${file.path}`));
6904
+ }
6905
+ } catch (error) {
6906
+ console.log(source_default.yellow(`\u26A0\uFE0F Skipped ${file.name}: ${file.path}`));
6907
+ }
6908
+ }
6909
+ console.log();
6910
+ console.log(source_default.green(`\u2713 Synced guidelines to ${syncedCount} AI instruction file(s)`));
6911
+ console.log();
6525
6912
  console.log(source_default.cyan("Next steps:"));
6526
6913
  console.log(source_default.gray(' 1. Create a task: knowns task create "My first task"'));
6527
6914
  console.log(source_default.gray(" 2. List tasks: knowns task list"));
6915
+ console.log(source_default.gray(" 3. Update AI instructions: knowns agents --update-instructions"));
6528
6916
  } catch (error) {
6529
6917
  console.error(source_default.red("\u2717 Failed to initialize project"));
6530
6918
  if (error instanceof Error) {
@@ -6534,12 +6922,12 @@ var initCommand = new Command("init").description("Initialize .knowns/ folder in
6534
6922
  }
6535
6923
  });
6536
6924
  // src/commands/task.ts
6537
- import { mkdir as mkdir3, readdir as readdir2, unlink } from "fs/promises";
6538
- import { join as join6 } from "path";
6925
+ import { mkdir as mkdir4, readdir as readdir2, unlink } from "fs/promises";
6926
+ import { join as join7 } from "path";
6539
6927
 
6540
6928
  // src/utils/doc-links.ts
6541
- import { existsSync as existsSync2 } from "fs";
6542
- import { join as join4 } from "path";
6929
+ import { existsSync as existsSync3 } from "fs";
6930
+ import { join as join5 } from "path";
6543
6931
  function parseMarkdownLinks(text) {
6544
6932
  const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
6545
6933
  const links = [];
@@ -6555,7 +6943,7 @@ function parseMarkdownLinks(text) {
6555
6943
  function resolveDocReferences(content, projectRoot) {
6556
6944
  const links = parseMarkdownLinks(content);
6557
6945
  const docReferences = [];
6558
- const docsDir = join4(projectRoot, ".knowns", "docs");
6946
+ const docsDir = join5(projectRoot, ".knowns", "docs");
6559
6947
  for (const link of links) {
6560
6948
  if (link.target.startsWith("http://") || link.target.startsWith("https://")) {
6561
6949
  continue;
@@ -6568,8 +6956,8 @@ function resolveDocReferences(content, projectRoot) {
6568
6956
  if (!filename.endsWith(".md")) {
6569
6957
  filename = `${filename}.md`;
6570
6958
  }
6571
- const resolvedPath = join4(docsDir, filename);
6572
- const exists = existsSync2(resolvedPath);
6959
+ const resolvedPath = join5(docsDir, filename);
6960
+ const exists = existsSync3(resolvedPath);
6573
6961
  docReferences.push({
6574
6962
  text: link.text,
6575
6963
  filename: link.target,
@@ -6599,16 +6987,16 @@ function formatDocReferences(references, options2 = {}) {
6599
6987
  }
6600
6988
 
6601
6989
  // src/utils/find-project-root.ts
6602
- import { existsSync as existsSync3 } from "fs";
6603
- import { dirname, join as join5 } from "path";
6990
+ import { existsSync as existsSync4 } from "fs";
6991
+ import { dirname as dirname2, join as join6 } from "path";
6604
6992
  function findProjectRoot(startPath = process.cwd()) {
6605
6993
  let currentPath = startPath;
6606
6994
  for (let i = 0;i < 20; i++) {
6607
- const knownsPath = join5(currentPath, ".knowns");
6608
- if (existsSync3(knownsPath)) {
6995
+ const knownsPath = join6(currentPath, ".knowns");
6996
+ if (existsSync4(knownsPath)) {
6609
6997
  return currentPath;
6610
6998
  }
6611
- const parentPath = dirname(currentPath);
6999
+ const parentPath = dirname2(currentPath);
6612
7000
  if (parentPath === currentPath) {
6613
7001
  return null;
6614
7002
  }
@@ -7223,17 +7611,17 @@ var archiveCommand = new Command("archive").description("Archive a task").argume
7223
7611
  console.error(source_default.red(`\u2717 Task ${id} not found`));
7224
7612
  process.exit(1);
7225
7613
  }
7226
- const archiveDir = join6(projectRoot, ".knowns", "archive");
7227
- await mkdir3(archiveDir, { recursive: true });
7228
- const tasksPath = join6(projectRoot, ".knowns", "tasks");
7614
+ const archiveDir = join7(projectRoot, ".knowns", "archive");
7615
+ await mkdir4(archiveDir, { recursive: true });
7616
+ const tasksPath = join7(projectRoot, ".knowns", "tasks");
7229
7617
  const files = await readdir2(tasksPath);
7230
7618
  const taskFile = files.find((f) => f.startsWith(`task-${id} -`));
7231
7619
  if (!taskFile) {
7232
7620
  console.error(source_default.red(`\u2717 Task file for ${id} not found`));
7233
7621
  process.exit(1);
7234
7622
  }
7235
- const oldPath = join6(tasksPath, taskFile);
7236
- const newPath = join6(archiveDir, taskFile);
7623
+ const oldPath = join7(tasksPath, taskFile);
7624
+ const newPath = join7(archiveDir, taskFile);
7237
7625
  const content = await Bun.file(oldPath).text();
7238
7626
  await Bun.write(newPath, content);
7239
7627
  await unlink(oldPath);
@@ -7254,16 +7642,16 @@ var unarchiveCommand = new Command("unarchive").description("Restore archived ta
7254
7642
  console.error(source_default.gray(' Run "knowns init" to initialize'));
7255
7643
  process.exit(1);
7256
7644
  }
7257
- const archiveDir = join6(projectRoot, ".knowns", "archive");
7258
- const tasksPath = join6(projectRoot, ".knowns", "tasks");
7645
+ const archiveDir = join7(projectRoot, ".knowns", "archive");
7646
+ const tasksPath = join7(projectRoot, ".knowns", "tasks");
7259
7647
  const files = await readdir2(archiveDir);
7260
7648
  const taskFile = files.find((f) => f.startsWith(`task-${id} -`));
7261
7649
  if (!taskFile) {
7262
7650
  console.error(source_default.red(`\u2717 Archived task ${id} not found`));
7263
7651
  process.exit(1);
7264
7652
  }
7265
- const archivePath = join6(archiveDir, taskFile);
7266
- const tasksFilePath = join6(tasksPath, taskFile);
7653
+ const archivePath = join7(archiveDir, taskFile);
7654
+ const tasksFilePath = join7(tasksPath, taskFile);
7267
7655
  const content = await Bun.file(archivePath).text();
7268
7656
  await Bun.write(tasksFilePath, content);
7269
7657
  await unlink(archivePath);
@@ -7854,9 +8242,9 @@ var boardCommand = new Command("board").description("Display Kanban board").opti
7854
8242
  }
7855
8243
  });
7856
8244
  // src/commands/search.ts
7857
- import { existsSync as existsSync4 } from "fs";
7858
- import { readFile, readdir as readdir3 } from "fs/promises";
7859
- import { join as join7 } from "path";
8245
+ import { existsSync as existsSync5 } from "fs";
8246
+ import { readFile as readFile2, readdir as readdir3 } from "fs/promises";
8247
+ import { join as join8 } from "path";
7860
8248
  var import_gray_matter2 = __toESM(require_gray_matter(), 1);
7861
8249
  function getFileStore3() {
7862
8250
  const projectRoot = findProjectRoot();
@@ -7908,8 +8296,8 @@ function calculateDocScore(doc, query) {
7908
8296
  return score;
7909
8297
  }
7910
8298
  async function searchDocs(query, projectRoot) {
7911
- const docsDir = join7(projectRoot, ".knowns", "docs");
7912
- if (!existsSync4(docsDir)) {
8299
+ const docsDir = join8(projectRoot, ".knowns", "docs");
8300
+ if (!existsSync5(docsDir)) {
7913
8301
  return [];
7914
8302
  }
7915
8303
  try {
@@ -7917,7 +8305,7 @@ async function searchDocs(query, projectRoot) {
7917
8305
  const mdFiles = files.filter((f) => f.endsWith(".md"));
7918
8306
  const results = [];
7919
8307
  for (const file of mdFiles) {
7920
- const content = await readFile(join7(docsDir, file), "utf-8");
8308
+ const content = await readFile2(join8(docsDir, file), "utf-8");
7921
8309
  const { data, content: docContent } = import_gray_matter2.default(content);
7922
8310
  const metadata = data;
7923
8311
  const doc = {
@@ -8500,9 +8888,9 @@ timeCommand.addCommand(addCommand);
8500
8888
  timeCommand.addCommand(reportCommand);
8501
8889
  // src/server/index.ts
8502
8890
  import { watch } from "fs";
8503
- import { existsSync as existsSync5 } from "fs";
8504
- import { mkdir as mkdir4, readFile as readFile2, readdir as readdir4, writeFile } from "fs/promises";
8505
- import { join as join8, relative } from "path";
8891
+ import { existsSync as existsSync6 } from "fs";
8892
+ import { mkdir as mkdir5, readFile as readFile3, readdir as readdir4, writeFile as writeFile2 } from "fs/promises";
8893
+ import { join as join9, relative } from "path";
8506
8894
  var import_gray_matter3 = __toESM(require_gray_matter(), 1);
8507
8895
  var buildVersion = Date.now();
8508
8896
  async function startServer(options2) {
@@ -8515,9 +8903,9 @@ async function startServer(options2) {
8515
8903
  client.send(msg);
8516
8904
  }
8517
8905
  };
8518
- const uiPath = join8(projectRoot, "src", "ui");
8519
- const entrypoint = join8(uiPath, "index.html");
8520
- const buildDir = join8(projectRoot, ".knowns", "ui-build");
8906
+ const uiPath = join9(projectRoot, "src", "ui");
8907
+ const entrypoint = join9(uiPath, "index.html");
8908
+ const buildDir = join9(projectRoot, ".knowns", "ui-build");
8521
8909
  const entryFile = Bun.file(entrypoint);
8522
8910
  if (!await entryFile.exists()) {
8523
8911
  throw new Error(`UI entry point not found: ${entrypoint}`);
@@ -8526,7 +8914,7 @@ async function startServer(options2) {
8526
8914
  console.log("Building UI...");
8527
8915
  const startTime = Date.now();
8528
8916
  const buildResult = await Bun.build({
8529
- entrypoints: [join8(uiPath, "main.tsx")],
8917
+ entrypoints: [join9(uiPath, "main.tsx")],
8530
8918
  outdir: buildDir,
8531
8919
  target: "browser",
8532
8920
  minify: false,
@@ -8540,7 +8928,7 @@ async function startServer(options2) {
8540
8928
  return false;
8541
8929
  }
8542
8930
  const cssResult = await Bun.build({
8543
- entrypoints: [join8(uiPath, "index.css")],
8931
+ entrypoints: [join9(uiPath, "index.css")],
8544
8932
  outdir: buildDir,
8545
8933
  target: "browser",
8546
8934
  minify: false
@@ -8594,7 +8982,7 @@ async function startServer(options2) {
8594
8982
  return handleAPI(req, url, store, broadcast);
8595
8983
  }
8596
8984
  if (url.pathname === "/main.js" || url.pathname.startsWith("/main.js?")) {
8597
- const file = Bun.file(join8(buildDir, "main.js"));
8985
+ const file = Bun.file(join9(buildDir, "main.js"));
8598
8986
  if (await file.exists()) {
8599
8987
  return new Response(file, {
8600
8988
  headers: {
@@ -8605,7 +8993,7 @@ async function startServer(options2) {
8605
8993
  }
8606
8994
  }
8607
8995
  if (url.pathname === "/index.css" || url.pathname.startsWith("/index.css?")) {
8608
- const file = Bun.file(join8(buildDir, "index.css"));
8996
+ const file = Bun.file(join9(buildDir, "index.css"));
8609
8997
  if (await file.exists()) {
8610
8998
  return new Response(file, {
8611
8999
  headers: {
@@ -8708,7 +9096,7 @@ async function findMarkdownFiles(dir, baseDir) {
8708
9096
  const files = [];
8709
9097
  const entries = await readdir4(dir, { withFileTypes: true });
8710
9098
  for (const entry of entries) {
8711
- const fullPath = join8(dir, entry.name);
9099
+ const fullPath = join9(dir, entry.name);
8712
9100
  if (entry.isDirectory()) {
8713
9101
  const subFiles = await findMarkdownFiles(fullPath, baseDir);
8714
9102
  files.push(...subFiles);
@@ -8761,14 +9149,14 @@ async function handleAPI(req, url, store, broadcast) {
8761
9149
  });
8762
9150
  }
8763
9151
  if (url.pathname === "/api/docs" && req.method === "GET") {
8764
- const docsDir = join8(store.projectRoot, ".knowns", "docs");
8765
- if (!existsSync5(docsDir)) {
9152
+ const docsDir = join9(store.projectRoot, ".knowns", "docs");
9153
+ if (!existsSync6(docsDir)) {
8766
9154
  return new Response(JSON.stringify({ docs: [] }), { headers });
8767
9155
  }
8768
9156
  const mdFiles = await findMarkdownFiles(docsDir, docsDir);
8769
9157
  const docs = await Promise.all(mdFiles.map(async (relativePath) => {
8770
- const fullPath = join8(docsDir, relativePath);
8771
- const content = await readFile2(fullPath, "utf-8");
9158
+ const fullPath = join9(docsDir, relativePath);
9159
+ const content = await readFile3(fullPath, "utf-8");
8772
9160
  const { data, content: docContent } = import_gray_matter3.default(content);
8773
9161
  const pathParts = relativePath.split("/");
8774
9162
  const filename = pathParts[pathParts.length - 1];
@@ -8784,9 +9172,9 @@ async function handleAPI(req, url, store, broadcast) {
8784
9172
  return new Response(JSON.stringify({ docs }), { headers });
8785
9173
  }
8786
9174
  if (url.pathname === "/api/docs" && req.method === "POST") {
8787
- const docsDir = join8(store.projectRoot, ".knowns", "docs");
8788
- if (!existsSync5(docsDir)) {
8789
- await mkdir4(docsDir, { recursive: true });
9175
+ const docsDir = join9(store.projectRoot, ".knowns", "docs");
9176
+ if (!existsSync6(docsDir)) {
9177
+ await mkdir5(docsDir, { recursive: true });
8790
9178
  }
8791
9179
  const data = await req.json();
8792
9180
  const { title, description, tags, content, folder } = data;
@@ -8801,16 +9189,16 @@ async function handleAPI(req, url, store, broadcast) {
8801
9189
  let targetDir;
8802
9190
  if (folder?.trim()) {
8803
9191
  const cleanFolder = folder.trim().replace(/^\/+|\/+$/g, "");
8804
- targetDir = join8(docsDir, cleanFolder);
8805
- filepath = join8(targetDir, filename);
9192
+ targetDir = join9(docsDir, cleanFolder);
9193
+ filepath = join9(targetDir, filename);
8806
9194
  } else {
8807
9195
  targetDir = docsDir;
8808
- filepath = join8(docsDir, filename);
9196
+ filepath = join9(docsDir, filename);
8809
9197
  }
8810
- if (!existsSync5(targetDir)) {
8811
- await mkdir4(targetDir, { recursive: true });
9198
+ if (!existsSync6(targetDir)) {
9199
+ await mkdir5(targetDir, { recursive: true });
8812
9200
  }
8813
- if (existsSync5(filepath)) {
9201
+ if (existsSync6(filepath)) {
8814
9202
  return new Response(JSON.stringify({ error: "Document with this title already exists in this folder" }), {
8815
9203
  status: 409,
8816
9204
  headers
@@ -8825,7 +9213,7 @@ async function handleAPI(req, url, store, broadcast) {
8825
9213
  tags: tags || []
8826
9214
  };
8827
9215
  const markdown = import_gray_matter3.default.stringify(content || "", frontmatter);
8828
- await writeFile(filepath, markdown, "utf-8");
9216
+ await writeFile2(filepath, markdown, "utf-8");
8829
9217
  return new Response(JSON.stringify({
8830
9218
  success: true,
8831
9219
  filename,
@@ -8835,8 +9223,8 @@ async function handleAPI(req, url, store, broadcast) {
8835
9223
  }), { status: 201, headers });
8836
9224
  }
8837
9225
  if (url.pathname === "/api/config" && req.method === "GET") {
8838
- const configPath = join8(store.projectRoot, ".knowns", "config.json");
8839
- if (!existsSync5(configPath)) {
9226
+ const configPath = join9(store.projectRoot, ".knowns", "config.json");
9227
+ if (!existsSync6(configPath)) {
8840
9228
  return new Response(JSON.stringify({
8841
9229
  config: {
8842
9230
  defaultPriority: "medium",
@@ -8846,7 +9234,7 @@ async function handleAPI(req, url, store, broadcast) {
8846
9234
  }
8847
9235
  }), { headers });
8848
9236
  }
8849
- const content = await readFile2(configPath, "utf-8");
9237
+ const content = await readFile3(configPath, "utf-8");
8850
9238
  const config = JSON.parse(content);
8851
9239
  if (!config.visibleColumns) {
8852
9240
  config.visibleColumns = ["todo", "in-progress", "done"];
@@ -8855,8 +9243,8 @@ async function handleAPI(req, url, store, broadcast) {
8855
9243
  }
8856
9244
  if (url.pathname === "/api/config" && req.method === "POST") {
8857
9245
  const config = await req.json();
8858
- const configPath = join8(store.projectRoot, ".knowns", "config.json");
8859
- await writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
9246
+ const configPath = join9(store.projectRoot, ".knowns", "config.json");
9247
+ await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
8860
9248
  return new Response(JSON.stringify({ success: true }), { headers });
8861
9249
  }
8862
9250
  if (url.pathname === "/api/search" && req.method === "GET") {
@@ -8878,13 +9266,13 @@ async function handleAPI(req, url, store, broadcast) {
8878
9266
  ].join(" ").toLowerCase();
8879
9267
  return searchText.includes(q);
8880
9268
  });
8881
- const docsDir = join8(store.projectRoot, ".knowns", "docs");
9269
+ const docsDir = join9(store.projectRoot, ".knowns", "docs");
8882
9270
  const docResults = [];
8883
- if (existsSync5(docsDir)) {
9271
+ if (existsSync6(docsDir)) {
8884
9272
  const files = await readdir4(docsDir);
8885
9273
  const mdFiles = files.filter((f) => f.endsWith(".md"));
8886
9274
  for (const file of mdFiles) {
8887
- const content = await readFile2(join8(docsDir, file), "utf-8");
9275
+ const content = await readFile3(join9(docsDir, file), "utf-8");
8888
9276
  const { data, content: docContent } = import_gray_matter3.default(content);
8889
9277
  const searchText = `${data.title || ""} ${data.description || ""} ${data.tags?.join(" ") || ""} ${docContent}`.toLowerCase();
8890
9278
  if (searchText.includes(q)) {
@@ -8936,17 +9324,17 @@ var browserCommand = new Command("browser").description("Open web UI for task ma
8936
9324
  }
8937
9325
  });
8938
9326
  // src/commands/doc.ts
8939
- import { existsSync as existsSync6 } from "fs";
8940
- import { mkdir as mkdir5, readFile as readFile3, readdir as readdir5, writeFile as writeFile2 } from "fs/promises";
8941
- import { join as join9 } from "path";
9327
+ import { existsSync as existsSync7 } from "fs";
9328
+ import { mkdir as mkdir6, readFile as readFile4, readdir as readdir5, writeFile as writeFile3 } from "fs/promises";
9329
+ import { join as join10 } from "path";
8942
9330
  var import_gray_matter4 = __toESM(require_gray_matter(), 1);
8943
- var DOCS_DIR = join9(process.cwd(), ".knowns", "docs");
9331
+ var DOCS_DIR = join10(process.cwd(), ".knowns", "docs");
8944
9332
  async function getAllMdFiles(dir, basePath = "") {
8945
9333
  const files = [];
8946
9334
  const entries = await readdir5(dir, { withFileTypes: true });
8947
9335
  for (const entry of entries) {
8948
- const fullPath = join9(dir, entry.name);
8949
- const relativePath = basePath ? join9(basePath, entry.name) : entry.name;
9336
+ const fullPath = join10(dir, entry.name);
9337
+ const relativePath = basePath ? join10(basePath, entry.name) : entry.name;
8950
9338
  if (entry.isDirectory()) {
8951
9339
  const subFiles = await getAllMdFiles(fullPath, relativePath);
8952
9340
  files.push(...subFiles);
@@ -8957,8 +9345,8 @@ async function getAllMdFiles(dir, basePath = "") {
8957
9345
  return files;
8958
9346
  }
8959
9347
  async function ensureDocsDir() {
8960
- if (!existsSync6(DOCS_DIR)) {
8961
- await mkdir5(DOCS_DIR, { recursive: true });
9348
+ if (!existsSync7(DOCS_DIR)) {
9349
+ await mkdir6(DOCS_DIR, { recursive: true });
8962
9350
  }
8963
9351
  }
8964
9352
  function titleToFilename(title) {
@@ -8968,8 +9356,8 @@ var createCommand3 = new Command("create").description("Create a new documentati
8968
9356
  try {
8969
9357
  await ensureDocsDir();
8970
9358
  const filename = `${titleToFilename(title)}.md`;
8971
- const filepath = join9(DOCS_DIR, filename);
8972
- if (existsSync6(filepath)) {
9359
+ const filepath = join10(DOCS_DIR, filename);
9360
+ if (existsSync7(filepath)) {
8973
9361
  console.error(source_default.red(`\u2717 Document already exists: ${filename}`));
8974
9362
  process.exit(1);
8975
9363
  }
@@ -8989,7 +9377,7 @@ var createCommand3 = new Command("create").description("Create a new documentati
8989
9377
 
8990
9378
  Write your documentation here.
8991
9379
  `, metadata);
8992
- await writeFile2(filepath, content, "utf-8");
9380
+ await writeFile3(filepath, content, "utf-8");
8993
9381
  if (options2.plain) {
8994
9382
  console.log(`Created: ${filename}`);
8995
9383
  } else {
@@ -9016,7 +9404,7 @@ var listCommand2 = new Command("list").description("List all documentation files
9016
9404
  }
9017
9405
  const docs = [];
9018
9406
  for (const file of mdFiles) {
9019
- const content = await readFile3(join9(DOCS_DIR, file), "utf-8");
9407
+ const content = await readFile4(join10(DOCS_DIR, file), "utf-8");
9020
9408
  const { data } = import_gray_matter4.default(content);
9021
9409
  docs.push({
9022
9410
  filename: file,
@@ -9075,12 +9463,12 @@ var viewCommand2 = new Command("view").description("View a documentation file").
9075
9463
  try {
9076
9464
  await ensureDocsDir();
9077
9465
  let filename = name.endsWith(".md") ? name : `${name}.md`;
9078
- let filepath = join9(DOCS_DIR, filename);
9079
- if (!existsSync6(filepath)) {
9466
+ let filepath = join10(DOCS_DIR, filename);
9467
+ if (!existsSync7(filepath)) {
9080
9468
  filename = `${titleToFilename(name)}.md`;
9081
- filepath = join9(DOCS_DIR, filename);
9469
+ filepath = join10(DOCS_DIR, filename);
9082
9470
  }
9083
- if (!existsSync6(filepath)) {
9471
+ if (!existsSync7(filepath)) {
9084
9472
  const allFiles = await getAllMdFiles(DOCS_DIR);
9085
9473
  const searchName = name.toLowerCase().replace(/\.md$/, "");
9086
9474
  const matchingFile = allFiles.find((file) => {
@@ -9090,14 +9478,14 @@ var viewCommand2 = new Command("view").description("View a documentation file").
9090
9478
  });
9091
9479
  if (matchingFile) {
9092
9480
  filename = matchingFile;
9093
- filepath = join9(DOCS_DIR, matchingFile);
9481
+ filepath = join10(DOCS_DIR, matchingFile);
9094
9482
  }
9095
9483
  }
9096
- if (!existsSync6(filepath)) {
9484
+ if (!existsSync7(filepath)) {
9097
9485
  console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
9098
9486
  process.exit(1);
9099
9487
  }
9100
- const fileContent = await readFile3(filepath, "utf-8");
9488
+ const fileContent = await readFile4(filepath, "utf-8");
9101
9489
  const { data, content } = import_gray_matter4.default(fileContent);
9102
9490
  const metadata = data;
9103
9491
  if (options2.plain) {
@@ -9176,16 +9564,16 @@ var editCommand2 = new Command("edit").description("Edit a documentation file me
9176
9564
  try {
9177
9565
  await ensureDocsDir();
9178
9566
  let filename = name.endsWith(".md") ? name : `${name}.md`;
9179
- let filepath = join9(DOCS_DIR, filename);
9180
- if (!existsSync6(filepath)) {
9567
+ let filepath = join10(DOCS_DIR, filename);
9568
+ if (!existsSync7(filepath)) {
9181
9569
  filename = `${titleToFilename(name)}.md`;
9182
- filepath = join9(DOCS_DIR, filename);
9570
+ filepath = join10(DOCS_DIR, filename);
9183
9571
  }
9184
- if (!existsSync6(filepath)) {
9572
+ if (!existsSync7(filepath)) {
9185
9573
  console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
9186
9574
  process.exit(1);
9187
9575
  }
9188
- const fileContent = await readFile3(filepath, "utf-8");
9576
+ const fileContent = await readFile4(filepath, "utf-8");
9189
9577
  const { data, content } = import_gray_matter4.default(fileContent);
9190
9578
  const metadata = data;
9191
9579
  if (options2.title)
@@ -9196,7 +9584,7 @@ var editCommand2 = new Command("edit").description("Edit a documentation file me
9196
9584
  metadata.tags = options2.tags.split(",").map((t) => t.trim());
9197
9585
  metadata.updatedAt = new Date().toISOString();
9198
9586
  const newContent = import_gray_matter4.default.stringify(content, metadata);
9199
- await writeFile2(filepath, newContent, "utf-8");
9587
+ await writeFile3(filepath, newContent, "utf-8");
9200
9588
  console.log(source_default.green(`\u2713 Updated documentation: ${source_default.bold(filename)}`));
9201
9589
  } catch (error) {
9202
9590
  console.error(source_default.red("Error editing documentation:"), error instanceof Error ? error.message : String(error));
@@ -9205,9 +9593,9 @@ var editCommand2 = new Command("edit").description("Edit a documentation file me
9205
9593
  });
9206
9594
  var docCommand = new Command("doc").description("Manage documentation").addCommand(createCommand3).addCommand(listCommand2).addCommand(viewCommand2).addCommand(editCommand2);
9207
9595
  // src/commands/config.ts
9208
- import { existsSync as existsSync7 } from "fs";
9209
- import { mkdir as mkdir6, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
9210
- import { join as join10 } from "path";
9596
+ import { existsSync as existsSync8 } from "fs";
9597
+ import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
9598
+ import { join as join11 } from "path";
9211
9599
 
9212
9600
  // node_modules/zod/v4/classic/external.js
9213
9601
  var exports_external = {};
@@ -22647,12 +23035,12 @@ function getProjectRoot2() {
22647
23035
  return projectRoot;
22648
23036
  }
22649
23037
  async function loadConfig(projectRoot) {
22650
- const configPath = join10(projectRoot, CONFIG_FILE);
22651
- if (!existsSync7(configPath)) {
23038
+ const configPath = join11(projectRoot, CONFIG_FILE);
23039
+ if (!existsSync8(configPath)) {
22652
23040
  return { ...DEFAULT_CONFIG };
22653
23041
  }
22654
23042
  try {
22655
- const content = await readFile4(configPath, "utf-8");
23043
+ const content = await readFile5(configPath, "utf-8");
22656
23044
  const data = JSON.parse(content);
22657
23045
  const validated = ConfigSchema.parse(data);
22658
23046
  return { ...DEFAULT_CONFIG, ...validated };
@@ -22665,13 +23053,13 @@ async function loadConfig(projectRoot) {
22665
23053
  }
22666
23054
  }
22667
23055
  async function saveConfig(projectRoot, config2) {
22668
- const configPath = join10(projectRoot, CONFIG_FILE);
22669
- const knownsDir = join10(projectRoot, ".knowns");
22670
- if (!existsSync7(knownsDir)) {
22671
- await mkdir6(knownsDir, { recursive: true });
23056
+ const configPath = join11(projectRoot, CONFIG_FILE);
23057
+ const knownsDir = join11(projectRoot, ".knowns");
23058
+ if (!existsSync8(knownsDir)) {
23059
+ await mkdir7(knownsDir, { recursive: true });
22672
23060
  }
22673
23061
  try {
22674
- await writeFile3(configPath, JSON.stringify(config2, null, 2), "utf-8");
23062
+ await writeFile4(configPath, JSON.stringify(config2, null, 2), "utf-8");
22675
23063
  } catch (error46) {
22676
23064
  console.error(source_default.red("\u2717 Failed to save config"));
22677
23065
  if (error46 instanceof Error) {
@@ -22813,128 +23201,9 @@ var resetCommand = new Command("reset").description("Reset configuration to defa
22813
23201
  }
22814
23202
  });
22815
23203
  var configCommand = new Command("config").description("Manage configuration settings").addCommand(listCommand3).addCommand(getCommand).addCommand(setCommand).addCommand(resetCommand);
22816
- // src/commands/agents.ts
22817
- import { existsSync as existsSync8 } from "fs";
22818
- import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
22819
- import { dirname as dirname2, join as join11 } from "path";
22820
- var PROJECT_ROOT = process.cwd();
22821
- var CLAUDE_MD = join11(PROJECT_ROOT, "CLAUDE.md");
22822
- var INSTRUCTION_FILES = [
22823
- { path: "CLAUDE.md", name: "Claude Code" },
22824
- { path: "AGENTS.md", name: "Agent SDK" },
22825
- { path: "GEMINI.md", name: "Gemini" },
22826
- { path: ".github/copilot-instructions.md", name: "GitHub Copilot" }
22827
- ];
22828
- function extractGuidelines(content) {
22829
- const startMarker = "<!-- KNOWNS GUIDELINES START -->";
22830
- const endMarker = "<!-- KNOWNS GUIDELINES END -->";
22831
- const startIndex = content.indexOf(startMarker);
22832
- const endIndex = content.indexOf(endMarker);
22833
- if (startIndex === -1 || endIndex === -1) {
22834
- return null;
22835
- }
22836
- return content.substring(startIndex, endIndex + endMarker.length);
22837
- }
22838
- async function updateInstructionFile(filePath, guidelines) {
22839
- const fullPath = join11(PROJECT_ROOT, filePath);
22840
- const startMarker = "<!-- KNOWNS GUIDELINES START -->";
22841
- const endMarker = "<!-- KNOWNS GUIDELINES END -->";
22842
- const dir = dirname2(fullPath);
22843
- if (!existsSync8(dir)) {
22844
- await mkdir7(dir, { recursive: true });
22845
- }
22846
- if (!existsSync8(fullPath)) {
22847
- await writeFile4(fullPath, guidelines, "utf-8");
22848
- return { success: true, action: "created" };
22849
- }
22850
- const content = await readFile5(fullPath, "utf-8");
22851
- const startIndex = content.indexOf(startMarker);
22852
- const endIndex = content.indexOf(endMarker);
22853
- if (startIndex === -1 || endIndex === -1) {
22854
- const newContent2 = `${content.trimEnd()}
22855
-
22856
- ${guidelines}
22857
- `;
22858
- await writeFile4(fullPath, newContent2, "utf-8");
22859
- return { success: true, action: "appended" };
22860
- }
22861
- const before = content.substring(0, startIndex);
22862
- const after = content.substring(endIndex + endMarker.length);
22863
- const newContent = before + guidelines + after;
22864
- await writeFile4(fullPath, newContent, "utf-8");
22865
- return { success: true, action: "updated" };
22866
- }
22867
- var updateInstructionsCommand = new Command("agents").description("Manage agent instruction files").option("--update-instructions", "Update agent instruction files").action(async (options2) => {
22868
- if (!options2.updateInstructions) {
22869
- console.log(source_default.yellow("No action specified. Use --update-instructions to update files."));
22870
- console.log(source_default.gray(`
22871
- Example: knowns agents --update-instructions`));
22872
- return;
22873
- }
22874
- try {
22875
- if (!existsSync8(CLAUDE_MD)) {
22876
- console.error(source_default.red("Error: CLAUDE.md not found in project root"));
22877
- console.error(source_default.gray("The source file must exist with <!-- KNOWNS GUIDELINES START --> markers"));
22878
- process.exit(1);
22879
- }
22880
- const claudeContent = await readFile5(CLAUDE_MD, "utf-8");
22881
- const guidelines = extractGuidelines(claudeContent);
22882
- if (!guidelines) {
22883
- console.error(source_default.red("Error: No guidelines found in CLAUDE.md"));
22884
- console.error(source_default.gray("Ensure CLAUDE.md contains <!-- KNOWNS GUIDELINES START --> and <!-- KNOWNS GUIDELINES END --> markers"));
22885
- process.exit(1);
22886
- }
22887
- console.log(source_default.bold(`
22888
- Updating agent instruction files...
22889
- `));
22890
- let createdCount = 0;
22891
- let appendedCount = 0;
22892
- let updatedCount = 0;
22893
- let errorCount = 0;
22894
- for (const file2 of INSTRUCTION_FILES) {
22895
- try {
22896
- const result = await updateInstructionFile(file2.path, guidelines);
22897
- if (result.success) {
22898
- if (result.action === "created") {
22899
- createdCount++;
22900
- console.log(source_default.green(`\u2713 Created ${file2.name}: ${file2.path}`));
22901
- } else if (result.action === "appended") {
22902
- appendedCount++;
22903
- console.log(source_default.cyan(`\u2713 Appended ${file2.name}: ${file2.path}`));
22904
- } else {
22905
- updatedCount++;
22906
- console.log(source_default.green(`\u2713 Updated ${file2.name}: ${file2.path}`));
22907
- }
22908
- }
22909
- } catch (error46) {
22910
- errorCount++;
22911
- console.error(source_default.red(`\u2717 Failed ${file2.name}: ${file2.path}`), error46 instanceof Error ? error46.message : String(error46));
22912
- }
22913
- }
22914
- console.log(source_default.bold(`
22915
- Summary:`));
22916
- if (createdCount > 0) {
22917
- console.log(source_default.green(` Created: ${createdCount}`));
22918
- }
22919
- if (appendedCount > 0) {
22920
- console.log(source_default.cyan(` Appended: ${appendedCount}`));
22921
- }
22922
- if (updatedCount > 0) {
22923
- console.log(source_default.green(` Updated: ${updatedCount}`));
22924
- }
22925
- if (errorCount > 0) {
22926
- console.log(source_default.red(` Failed: ${errorCount}`));
22927
- }
22928
- console.log();
22929
- } catch (error46) {
22930
- console.error(source_default.red("Error updating instruction files:"), error46 instanceof Error ? error46.message : String(error46));
22931
- process.exit(1);
22932
- }
22933
- });
22934
- var agentsCommand = updateInstructionsCommand;
22935
23204
  // src/index.ts
22936
23205
  var program2 = new Command;
22937
- program2.name("knowns").description("CLI tool for dev teams to manage tasks, track time, and sync").version("0.1.0");
23206
+ program2.name("knowns").description("CLI tool for dev teams to manage tasks, track time, and sync").version("0.1.2");
22938
23207
  program2.addCommand(initCommand);
22939
23208
  program2.addCommand(taskCommand);
22940
23209
  program2.addCommand(boardCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knowns",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool for dev teams to manage tasks and documentation",
5
5
  "module": "index.ts",
6
6
  "type": "module",