knowns 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,18 +8903,39 @@ 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");
8521
- const entryFile = Bun.file(entrypoint);
8522
- if (!await entryFile.exists()) {
8523
- throw new Error(`UI entry point not found: ${entrypoint}`);
8906
+ const currentDir = import.meta.dir;
8907
+ let packageRoot = currentDir;
8908
+ if (currentDir.endsWith("/dist")) {
8909
+ packageRoot = join9(currentDir, "..");
8910
+ } else if (currentDir.includes("/src/server")) {
8911
+ packageRoot = join9(currentDir, "..", "..");
8912
+ }
8913
+ const uiSourcePath = join9(packageRoot, "src", "ui");
8914
+ const uiDistPath = join9(packageRoot, "dist", "ui");
8915
+ let uiPath;
8916
+ let shouldBuild = false;
8917
+ if (existsSync6(join9(uiDistPath, "main.js"))) {
8918
+ uiPath = uiDistPath;
8919
+ shouldBuild = false;
8920
+ } else if (existsSync6(join9(uiSourcePath, "index.html"))) {
8921
+ uiPath = uiSourcePath;
8922
+ shouldBuild = true;
8923
+ } else {
8924
+ throw new Error(`UI files not found. Tried:
8925
+ - ${uiDistPath} (${existsSync6(uiDistPath) ? "exists but no main.js" : "not found"})
8926
+ - ${uiSourcePath} (${existsSync6(uiSourcePath) ? "exists but no index.html" : "not found"})
8927
+ Package root: ${packageRoot}
8928
+ Current dir: ${currentDir}`);
8524
8929
  }
8930
+ const buildDir = join9(projectRoot, ".knowns", "ui-build");
8525
8931
  const buildUI = async () => {
8932
+ if (!shouldBuild) {
8933
+ return true;
8934
+ }
8526
8935
  console.log("Building UI...");
8527
8936
  const startTime = Date.now();
8528
8937
  const buildResult = await Bun.build({
8529
- entrypoints: [join8(uiPath, "main.tsx")],
8938
+ entrypoints: [join9(uiPath, "main.tsx")],
8530
8939
  outdir: buildDir,
8531
8940
  target: "browser",
8532
8941
  minify: false,
@@ -8540,7 +8949,7 @@ async function startServer(options2) {
8540
8949
  return false;
8541
8950
  }
8542
8951
  const cssResult = await Bun.build({
8543
- entrypoints: [join8(uiPath, "index.css")],
8952
+ entrypoints: [join9(uiPath, "index.css")],
8544
8953
  outdir: buildDir,
8545
8954
  target: "browser",
8546
8955
  minify: false
@@ -8552,31 +8961,36 @@ async function startServer(options2) {
8552
8961
  console.log(`UI built in ${Date.now() - startTime}ms`);
8553
8962
  return true;
8554
8963
  };
8555
- if (!await buildUI()) {
8556
- throw new Error("Failed to build UI");
8557
- }
8558
- let rebuildTimeout = null;
8559
- const watcher = watch(uiPath, { recursive: true }, async (_event, filename) => {
8560
- if (!filename)
8561
- return;
8562
- if (!filename.endsWith(".tsx") && !filename.endsWith(".ts") && !filename.endsWith(".css")) {
8563
- return;
8964
+ if (shouldBuild) {
8965
+ if (!await buildUI()) {
8966
+ throw new Error("Failed to build UI");
8564
8967
  }
8565
- if (rebuildTimeout) {
8566
- clearTimeout(rebuildTimeout);
8567
- }
8568
- rebuildTimeout = setTimeout(async () => {
8569
- console.log(`File changed: ${filename}`);
8570
- const success = await buildUI();
8571
- if (success) {
8572
- broadcast({ type: "reload" });
8968
+ }
8969
+ let watcher = null;
8970
+ if (shouldBuild) {
8971
+ let rebuildTimeout = null;
8972
+ watcher = watch(uiPath, { recursive: true }, async (_event, filename) => {
8973
+ if (!filename)
8974
+ return;
8975
+ if (!filename.endsWith(".tsx") && !filename.endsWith(".ts") && !filename.endsWith(".css")) {
8976
+ return;
8573
8977
  }
8574
- }, 100);
8575
- });
8576
- process.on("SIGINT", () => {
8577
- watcher.close();
8578
- process.exit(0);
8579
- });
8978
+ if (rebuildTimeout) {
8979
+ clearTimeout(rebuildTimeout);
8980
+ }
8981
+ rebuildTimeout = setTimeout(async () => {
8982
+ console.log(`File changed: ${filename}`);
8983
+ const success = await buildUI();
8984
+ if (success) {
8985
+ broadcast({ type: "reload" });
8986
+ }
8987
+ }, 100);
8988
+ });
8989
+ process.on("SIGINT", () => {
8990
+ watcher?.close();
8991
+ process.exit(0);
8992
+ });
8993
+ }
8580
8994
  const server = Bun.serve({
8581
8995
  port,
8582
8996
  async fetch(req, server2) {
@@ -8594,7 +9008,10 @@ async function startServer(options2) {
8594
9008
  return handleAPI(req, url, store, broadcast);
8595
9009
  }
8596
9010
  if (url.pathname === "/main.js" || url.pathname.startsWith("/main.js?")) {
8597
- const file = Bun.file(join8(buildDir, "main.js"));
9011
+ let file = Bun.file(join9(buildDir, "main.js"));
9012
+ if (!await file.exists()) {
9013
+ file = Bun.file(join9(uiPath, "main.js"));
9014
+ }
8598
9015
  if (await file.exists()) {
8599
9016
  return new Response(file, {
8600
9017
  headers: {
@@ -8605,7 +9022,10 @@ async function startServer(options2) {
8605
9022
  }
8606
9023
  }
8607
9024
  if (url.pathname === "/index.css" || url.pathname.startsWith("/index.css?")) {
8608
- const file = Bun.file(join8(buildDir, "index.css"));
9025
+ let file = Bun.file(join9(buildDir, "index.css"));
9026
+ if (!await file.exists()) {
9027
+ file = Bun.file(join9(uiPath, "main.css"));
9028
+ }
8609
9029
  if (await file.exists()) {
8610
9030
  return new Response(file, {
8611
9031
  headers: {
@@ -8693,7 +9113,11 @@ async function startServer(options2) {
8693
9113
  });
8694
9114
  console.log(`Server running at http://localhost:${port}`);
8695
9115
  console.log(`Open in browser: http://localhost:${port}`);
8696
- console.log(`Live reload enabled - watching ${uiPath}`);
9116
+ if (shouldBuild) {
9117
+ console.log(`Live reload enabled - watching ${uiPath}`);
9118
+ } else {
9119
+ console.log(`Serving pre-built UI from ${uiPath}`);
9120
+ }
8697
9121
  if (open) {
8698
9122
  const openCommand = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
8699
9123
  try {
@@ -8708,7 +9132,7 @@ async function findMarkdownFiles(dir, baseDir) {
8708
9132
  const files = [];
8709
9133
  const entries = await readdir4(dir, { withFileTypes: true });
8710
9134
  for (const entry of entries) {
8711
- const fullPath = join8(dir, entry.name);
9135
+ const fullPath = join9(dir, entry.name);
8712
9136
  if (entry.isDirectory()) {
8713
9137
  const subFiles = await findMarkdownFiles(fullPath, baseDir);
8714
9138
  files.push(...subFiles);
@@ -8761,14 +9185,14 @@ async function handleAPI(req, url, store, broadcast) {
8761
9185
  });
8762
9186
  }
8763
9187
  if (url.pathname === "/api/docs" && req.method === "GET") {
8764
- const docsDir = join8(store.projectRoot, ".knowns", "docs");
8765
- if (!existsSync5(docsDir)) {
9188
+ const docsDir = join9(store.projectRoot, ".knowns", "docs");
9189
+ if (!existsSync6(docsDir)) {
8766
9190
  return new Response(JSON.stringify({ docs: [] }), { headers });
8767
9191
  }
8768
9192
  const mdFiles = await findMarkdownFiles(docsDir, docsDir);
8769
9193
  const docs = await Promise.all(mdFiles.map(async (relativePath) => {
8770
- const fullPath = join8(docsDir, relativePath);
8771
- const content = await readFile2(fullPath, "utf-8");
9194
+ const fullPath = join9(docsDir, relativePath);
9195
+ const content = await readFile3(fullPath, "utf-8");
8772
9196
  const { data, content: docContent } = import_gray_matter3.default(content);
8773
9197
  const pathParts = relativePath.split("/");
8774
9198
  const filename = pathParts[pathParts.length - 1];
@@ -8784,9 +9208,9 @@ async function handleAPI(req, url, store, broadcast) {
8784
9208
  return new Response(JSON.stringify({ docs }), { headers });
8785
9209
  }
8786
9210
  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 });
9211
+ const docsDir = join9(store.projectRoot, ".knowns", "docs");
9212
+ if (!existsSync6(docsDir)) {
9213
+ await mkdir5(docsDir, { recursive: true });
8790
9214
  }
8791
9215
  const data = await req.json();
8792
9216
  const { title, description, tags, content, folder } = data;
@@ -8801,16 +9225,16 @@ async function handleAPI(req, url, store, broadcast) {
8801
9225
  let targetDir;
8802
9226
  if (folder?.trim()) {
8803
9227
  const cleanFolder = folder.trim().replace(/^\/+|\/+$/g, "");
8804
- targetDir = join8(docsDir, cleanFolder);
8805
- filepath = join8(targetDir, filename);
9228
+ targetDir = join9(docsDir, cleanFolder);
9229
+ filepath = join9(targetDir, filename);
8806
9230
  } else {
8807
9231
  targetDir = docsDir;
8808
- filepath = join8(docsDir, filename);
9232
+ filepath = join9(docsDir, filename);
8809
9233
  }
8810
- if (!existsSync5(targetDir)) {
8811
- await mkdir4(targetDir, { recursive: true });
9234
+ if (!existsSync6(targetDir)) {
9235
+ await mkdir5(targetDir, { recursive: true });
8812
9236
  }
8813
- if (existsSync5(filepath)) {
9237
+ if (existsSync6(filepath)) {
8814
9238
  return new Response(JSON.stringify({ error: "Document with this title already exists in this folder" }), {
8815
9239
  status: 409,
8816
9240
  headers
@@ -8825,7 +9249,7 @@ async function handleAPI(req, url, store, broadcast) {
8825
9249
  tags: tags || []
8826
9250
  };
8827
9251
  const markdown = import_gray_matter3.default.stringify(content || "", frontmatter);
8828
- await writeFile(filepath, markdown, "utf-8");
9252
+ await writeFile2(filepath, markdown, "utf-8");
8829
9253
  return new Response(JSON.stringify({
8830
9254
  success: true,
8831
9255
  filename,
@@ -8835,8 +9259,8 @@ async function handleAPI(req, url, store, broadcast) {
8835
9259
  }), { status: 201, headers });
8836
9260
  }
8837
9261
  if (url.pathname === "/api/config" && req.method === "GET") {
8838
- const configPath = join8(store.projectRoot, ".knowns", "config.json");
8839
- if (!existsSync5(configPath)) {
9262
+ const configPath = join9(store.projectRoot, ".knowns", "config.json");
9263
+ if (!existsSync6(configPath)) {
8840
9264
  return new Response(JSON.stringify({
8841
9265
  config: {
8842
9266
  defaultPriority: "medium",
@@ -8846,7 +9270,7 @@ async function handleAPI(req, url, store, broadcast) {
8846
9270
  }
8847
9271
  }), { headers });
8848
9272
  }
8849
- const content = await readFile2(configPath, "utf-8");
9273
+ const content = await readFile3(configPath, "utf-8");
8850
9274
  const config = JSON.parse(content);
8851
9275
  if (!config.visibleColumns) {
8852
9276
  config.visibleColumns = ["todo", "in-progress", "done"];
@@ -8855,8 +9279,8 @@ async function handleAPI(req, url, store, broadcast) {
8855
9279
  }
8856
9280
  if (url.pathname === "/api/config" && req.method === "POST") {
8857
9281
  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");
9282
+ const configPath = join9(store.projectRoot, ".knowns", "config.json");
9283
+ await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
8860
9284
  return new Response(JSON.stringify({ success: true }), { headers });
8861
9285
  }
8862
9286
  if (url.pathname === "/api/search" && req.method === "GET") {
@@ -8878,13 +9302,13 @@ async function handleAPI(req, url, store, broadcast) {
8878
9302
  ].join(" ").toLowerCase();
8879
9303
  return searchText.includes(q);
8880
9304
  });
8881
- const docsDir = join8(store.projectRoot, ".knowns", "docs");
9305
+ const docsDir = join9(store.projectRoot, ".knowns", "docs");
8882
9306
  const docResults = [];
8883
- if (existsSync5(docsDir)) {
9307
+ if (existsSync6(docsDir)) {
8884
9308
  const files = await readdir4(docsDir);
8885
9309
  const mdFiles = files.filter((f) => f.endsWith(".md"));
8886
9310
  for (const file of mdFiles) {
8887
- const content = await readFile2(join8(docsDir, file), "utf-8");
9311
+ const content = await readFile3(join9(docsDir, file), "utf-8");
8888
9312
  const { data, content: docContent } = import_gray_matter3.default(content);
8889
9313
  const searchText = `${data.title || ""} ${data.description || ""} ${data.tags?.join(" ") || ""} ${docContent}`.toLowerCase();
8890
9314
  if (searchText.includes(q)) {
@@ -8936,17 +9360,17 @@ var browserCommand = new Command("browser").description("Open web UI for task ma
8936
9360
  }
8937
9361
  });
8938
9362
  // 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";
9363
+ import { existsSync as existsSync7 } from "fs";
9364
+ import { mkdir as mkdir6, readFile as readFile4, readdir as readdir5, writeFile as writeFile3 } from "fs/promises";
9365
+ import { join as join10 } from "path";
8942
9366
  var import_gray_matter4 = __toESM(require_gray_matter(), 1);
8943
- var DOCS_DIR = join9(process.cwd(), ".knowns", "docs");
9367
+ var DOCS_DIR = join10(process.cwd(), ".knowns", "docs");
8944
9368
  async function getAllMdFiles(dir, basePath = "") {
8945
9369
  const files = [];
8946
9370
  const entries = await readdir5(dir, { withFileTypes: true });
8947
9371
  for (const entry of entries) {
8948
- const fullPath = join9(dir, entry.name);
8949
- const relativePath = basePath ? join9(basePath, entry.name) : entry.name;
9372
+ const fullPath = join10(dir, entry.name);
9373
+ const relativePath = basePath ? join10(basePath, entry.name) : entry.name;
8950
9374
  if (entry.isDirectory()) {
8951
9375
  const subFiles = await getAllMdFiles(fullPath, relativePath);
8952
9376
  files.push(...subFiles);
@@ -8957,8 +9381,8 @@ async function getAllMdFiles(dir, basePath = "") {
8957
9381
  return files;
8958
9382
  }
8959
9383
  async function ensureDocsDir() {
8960
- if (!existsSync6(DOCS_DIR)) {
8961
- await mkdir5(DOCS_DIR, { recursive: true });
9384
+ if (!existsSync7(DOCS_DIR)) {
9385
+ await mkdir6(DOCS_DIR, { recursive: true });
8962
9386
  }
8963
9387
  }
8964
9388
  function titleToFilename(title) {
@@ -8968,8 +9392,8 @@ var createCommand3 = new Command("create").description("Create a new documentati
8968
9392
  try {
8969
9393
  await ensureDocsDir();
8970
9394
  const filename = `${titleToFilename(title)}.md`;
8971
- const filepath = join9(DOCS_DIR, filename);
8972
- if (existsSync6(filepath)) {
9395
+ const filepath = join10(DOCS_DIR, filename);
9396
+ if (existsSync7(filepath)) {
8973
9397
  console.error(source_default.red(`\u2717 Document already exists: ${filename}`));
8974
9398
  process.exit(1);
8975
9399
  }
@@ -8989,7 +9413,7 @@ var createCommand3 = new Command("create").description("Create a new documentati
8989
9413
 
8990
9414
  Write your documentation here.
8991
9415
  `, metadata);
8992
- await writeFile2(filepath, content, "utf-8");
9416
+ await writeFile3(filepath, content, "utf-8");
8993
9417
  if (options2.plain) {
8994
9418
  console.log(`Created: ${filename}`);
8995
9419
  } else {
@@ -9016,7 +9440,7 @@ var listCommand2 = new Command("list").description("List all documentation files
9016
9440
  }
9017
9441
  const docs = [];
9018
9442
  for (const file of mdFiles) {
9019
- const content = await readFile3(join9(DOCS_DIR, file), "utf-8");
9443
+ const content = await readFile4(join10(DOCS_DIR, file), "utf-8");
9020
9444
  const { data } = import_gray_matter4.default(content);
9021
9445
  docs.push({
9022
9446
  filename: file,
@@ -9075,12 +9499,12 @@ var viewCommand2 = new Command("view").description("View a documentation file").
9075
9499
  try {
9076
9500
  await ensureDocsDir();
9077
9501
  let filename = name.endsWith(".md") ? name : `${name}.md`;
9078
- let filepath = join9(DOCS_DIR, filename);
9079
- if (!existsSync6(filepath)) {
9502
+ let filepath = join10(DOCS_DIR, filename);
9503
+ if (!existsSync7(filepath)) {
9080
9504
  filename = `${titleToFilename(name)}.md`;
9081
- filepath = join9(DOCS_DIR, filename);
9505
+ filepath = join10(DOCS_DIR, filename);
9082
9506
  }
9083
- if (!existsSync6(filepath)) {
9507
+ if (!existsSync7(filepath)) {
9084
9508
  const allFiles = await getAllMdFiles(DOCS_DIR);
9085
9509
  const searchName = name.toLowerCase().replace(/\.md$/, "");
9086
9510
  const matchingFile = allFiles.find((file) => {
@@ -9090,14 +9514,14 @@ var viewCommand2 = new Command("view").description("View a documentation file").
9090
9514
  });
9091
9515
  if (matchingFile) {
9092
9516
  filename = matchingFile;
9093
- filepath = join9(DOCS_DIR, matchingFile);
9517
+ filepath = join10(DOCS_DIR, matchingFile);
9094
9518
  }
9095
9519
  }
9096
- if (!existsSync6(filepath)) {
9520
+ if (!existsSync7(filepath)) {
9097
9521
  console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
9098
9522
  process.exit(1);
9099
9523
  }
9100
- const fileContent = await readFile3(filepath, "utf-8");
9524
+ const fileContent = await readFile4(filepath, "utf-8");
9101
9525
  const { data, content } = import_gray_matter4.default(fileContent);
9102
9526
  const metadata = data;
9103
9527
  if (options2.plain) {
@@ -9176,16 +9600,16 @@ var editCommand2 = new Command("edit").description("Edit a documentation file me
9176
9600
  try {
9177
9601
  await ensureDocsDir();
9178
9602
  let filename = name.endsWith(".md") ? name : `${name}.md`;
9179
- let filepath = join9(DOCS_DIR, filename);
9180
- if (!existsSync6(filepath)) {
9603
+ let filepath = join10(DOCS_DIR, filename);
9604
+ if (!existsSync7(filepath)) {
9181
9605
  filename = `${titleToFilename(name)}.md`;
9182
- filepath = join9(DOCS_DIR, filename);
9606
+ filepath = join10(DOCS_DIR, filename);
9183
9607
  }
9184
- if (!existsSync6(filepath)) {
9608
+ if (!existsSync7(filepath)) {
9185
9609
  console.error(source_default.red(`\u2717 Documentation not found: ${name}`));
9186
9610
  process.exit(1);
9187
9611
  }
9188
- const fileContent = await readFile3(filepath, "utf-8");
9612
+ const fileContent = await readFile4(filepath, "utf-8");
9189
9613
  const { data, content } = import_gray_matter4.default(fileContent);
9190
9614
  const metadata = data;
9191
9615
  if (options2.title)
@@ -9196,7 +9620,7 @@ var editCommand2 = new Command("edit").description("Edit a documentation file me
9196
9620
  metadata.tags = options2.tags.split(",").map((t) => t.trim());
9197
9621
  metadata.updatedAt = new Date().toISOString();
9198
9622
  const newContent = import_gray_matter4.default.stringify(content, metadata);
9199
- await writeFile2(filepath, newContent, "utf-8");
9623
+ await writeFile3(filepath, newContent, "utf-8");
9200
9624
  console.log(source_default.green(`\u2713 Updated documentation: ${source_default.bold(filename)}`));
9201
9625
  } catch (error) {
9202
9626
  console.error(source_default.red("Error editing documentation:"), error instanceof Error ? error.message : String(error));
@@ -9205,9 +9629,9 @@ var editCommand2 = new Command("edit").description("Edit a documentation file me
9205
9629
  });
9206
9630
  var docCommand = new Command("doc").description("Manage documentation").addCommand(createCommand3).addCommand(listCommand2).addCommand(viewCommand2).addCommand(editCommand2);
9207
9631
  // 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";
9632
+ import { existsSync as existsSync8 } from "fs";
9633
+ import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
9634
+ import { join as join11 } from "path";
9211
9635
 
9212
9636
  // node_modules/zod/v4/classic/external.js
9213
9637
  var exports_external = {};
@@ -22647,12 +23071,12 @@ function getProjectRoot2() {
22647
23071
  return projectRoot;
22648
23072
  }
22649
23073
  async function loadConfig(projectRoot) {
22650
- const configPath = join10(projectRoot, CONFIG_FILE);
22651
- if (!existsSync7(configPath)) {
23074
+ const configPath = join11(projectRoot, CONFIG_FILE);
23075
+ if (!existsSync8(configPath)) {
22652
23076
  return { ...DEFAULT_CONFIG };
22653
23077
  }
22654
23078
  try {
22655
- const content = await readFile4(configPath, "utf-8");
23079
+ const content = await readFile5(configPath, "utf-8");
22656
23080
  const data = JSON.parse(content);
22657
23081
  const validated = ConfigSchema.parse(data);
22658
23082
  return { ...DEFAULT_CONFIG, ...validated };
@@ -22665,13 +23089,13 @@ async function loadConfig(projectRoot) {
22665
23089
  }
22666
23090
  }
22667
23091
  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 });
23092
+ const configPath = join11(projectRoot, CONFIG_FILE);
23093
+ const knownsDir = join11(projectRoot, ".knowns");
23094
+ if (!existsSync8(knownsDir)) {
23095
+ await mkdir7(knownsDir, { recursive: true });
22672
23096
  }
22673
23097
  try {
22674
- await writeFile3(configPath, JSON.stringify(config2, null, 2), "utf-8");
23098
+ await writeFile4(configPath, JSON.stringify(config2, null, 2), "utf-8");
22675
23099
  } catch (error46) {
22676
23100
  console.error(source_default.red("\u2717 Failed to save config"));
22677
23101
  if (error46 instanceof Error) {
@@ -22813,128 +23237,9 @@ var resetCommand = new Command("reset").description("Reset configuration to defa
22813
23237
  }
22814
23238
  });
22815
23239
  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
23240
  // src/index.ts
22936
23241
  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");
23242
+ program2.name("knowns").description("CLI tool for dev teams to manage tasks, track time, and sync").version("0.1.2");
22938
23243
  program2.addCommand(initCommand);
22939
23244
  program2.addCommand(taskCommand);
22940
23245
  program2.addCommand(boardCommand);