clikit-plugin 0.3.4 → 0.3.5

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
@@ -3386,7 +3386,7 @@ var require_parse = __commonJS((exports, module) => {
3386
3386
 
3387
3387
  // node_modules/gray-matter/index.js
3388
3388
  var require_gray_matter = __commonJS((exports, module) => {
3389
- var fs = __require("fs");
3389
+ var fs2 = __require("fs");
3390
3390
  var sections = require_section_matter();
3391
3391
  var defaults = require_defaults();
3392
3392
  var stringify = require_stringify();
@@ -3473,7 +3473,7 @@ var require_gray_matter = __commonJS((exports, module) => {
3473
3473
  return stringify(file2, data, options2);
3474
3474
  };
3475
3475
  matter.read = function(filepath, options2) {
3476
- const str2 = fs.readFileSync(filepath, "utf8");
3476
+ const str2 = fs2.readFileSync(filepath, "utf8");
3477
3477
  const file2 = matter(str2, options2);
3478
3478
  file2.path = filepath;
3479
3479
  return file2;
@@ -3500,6 +3500,372 @@ var require_gray_matter = __commonJS((exports, module) => {
3500
3500
  module.exports = matter;
3501
3501
  });
3502
3502
 
3503
+ // src/cli.ts
3504
+ import * as fs from "fs";
3505
+ import * as path from "path";
3506
+ import * as os from "os";
3507
+ import { fileURLToPath } from "url";
3508
+ var PLUGIN_NAME = "clikit-plugin";
3509
+ var DCP_PLUGIN_ENTRY = "@tarquinen/opencode-dcp@beta";
3510
+ var VERSION = "0.0.0";
3511
+ function getPackageRoot() {
3512
+ const currentFile = fileURLToPath(import.meta.url);
3513
+ const currentDir = path.dirname(currentFile);
3514
+ if (path.basename(currentDir) === "dist") {
3515
+ return path.dirname(currentDir);
3516
+ }
3517
+ return path.dirname(currentDir);
3518
+ }
3519
+ function getPackageVersion() {
3520
+ const packageJsonPath = path.join(getPackageRoot(), "package.json");
3521
+ try {
3522
+ const raw = fs.readFileSync(packageJsonPath, "utf-8");
3523
+ const parsed = JSON.parse(raw);
3524
+ return parsed.version || VERSION;
3525
+ } catch {
3526
+ return VERSION;
3527
+ }
3528
+ }
3529
+ function getPluginEntry() {
3530
+ return `${PLUGIN_NAME}@latest`;
3531
+ }
3532
+ function resolveProjectDir(env = process.env, cwd = process.cwd()) {
3533
+ const candidates = [env.INIT_CWD, env.PWD, cwd].filter((value) => typeof value === "string" && value.trim().length > 0);
3534
+ for (const candidate of candidates) {
3535
+ const resolved = path.resolve(candidate);
3536
+ try {
3537
+ if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
3538
+ return resolved;
3539
+ }
3540
+ } catch {}
3541
+ }
3542
+ return cwd;
3543
+ }
3544
+ function upsertPluginEntry(existingPlugins, pluginEntry) {
3545
+ let pluginName;
3546
+ if (pluginEntry.startsWith("@")) {
3547
+ const versionAt = pluginEntry.indexOf("@", 1);
3548
+ pluginName = versionAt === -1 ? pluginEntry : pluginEntry.slice(0, versionAt);
3549
+ } else {
3550
+ pluginName = pluginEntry.split("@")[0] || pluginEntry;
3551
+ }
3552
+ const filteredPlugins = existingPlugins.filter((p) => p !== pluginName && !p.startsWith(`${pluginName}@`));
3553
+ filteredPlugins.push(pluginEntry);
3554
+ return filteredPlugins;
3555
+ }
3556
+ function copyFileIfMissing(sourcePath, targetPath, stats) {
3557
+ if (!fs.existsSync(sourcePath)) {
3558
+ stats.missingSources.push(sourcePath);
3559
+ return;
3560
+ }
3561
+ if (fs.existsSync(targetPath)) {
3562
+ stats.skipped += 1;
3563
+ return;
3564
+ }
3565
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
3566
+ fs.copyFileSync(sourcePath, targetPath);
3567
+ stats.copied += 1;
3568
+ }
3569
+ function copyDirectoryFilesIfMissing(sourceDir, targetDir, stats) {
3570
+ if (!fs.existsSync(sourceDir)) {
3571
+ stats.missingSources.push(sourceDir);
3572
+ return;
3573
+ }
3574
+ fs.mkdirSync(targetDir, { recursive: true });
3575
+ const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
3576
+ for (const entry of entries) {
3577
+ const sourcePath = path.join(sourceDir, entry.name);
3578
+ const targetPath = path.join(targetDir, entry.name);
3579
+ if (entry.isDirectory()) {
3580
+ copyDirectoryFilesIfMissing(sourcePath, targetPath, stats);
3581
+ continue;
3582
+ }
3583
+ if (entry.isFile()) {
3584
+ copyFileIfMissing(sourcePath, targetPath, stats);
3585
+ }
3586
+ }
3587
+ }
3588
+ function scaffoldProjectOpencode(projectDir, packageRoot = getPackageRoot()) {
3589
+ const projectOpencodeDir = path.join(projectDir, ".opencode");
3590
+ const stats = {
3591
+ copied: 0,
3592
+ skipped: 0,
3593
+ missingSources: []
3594
+ };
3595
+ fs.mkdirSync(projectOpencodeDir, { recursive: true });
3596
+ copyFileIfMissing(path.join(packageRoot, "AGENTS.md"), path.join(projectOpencodeDir, "AGENTS.md"), stats);
3597
+ copyDirectoryFilesIfMissing(path.join(packageRoot, "command"), path.join(projectOpencodeDir, "command"), stats);
3598
+ copyDirectoryFilesIfMissing(path.join(packageRoot, "skill"), path.join(projectOpencodeDir, "skill"), stats);
3599
+ copyDirectoryFilesIfMissing(path.join(packageRoot, "memory", "_templates"), path.join(projectOpencodeDir, "memory", "_templates"), stats);
3600
+ copyDirectoryFilesIfMissing(path.join(packageRoot, "src", "agents"), path.join(projectOpencodeDir, "src", "agents"), stats);
3601
+ copyFileIfMissing(path.join(packageRoot, "README.md"), path.join(projectOpencodeDir, "README-clikit.md"), stats);
3602
+ const indexPath = path.join(projectOpencodeDir, "index.ts");
3603
+ if (!fs.existsSync(indexPath)) {
3604
+ fs.writeFileSync(indexPath, `import CliKitPlugin from "${PLUGIN_NAME}";
3605
+
3606
+ export default CliKitPlugin;
3607
+ `);
3608
+ stats.copied += 1;
3609
+ } else {
3610
+ stats.skipped += 1;
3611
+ }
3612
+ return stats;
3613
+ }
3614
+ function getShellRcFiles() {
3615
+ const home = getRealHome();
3616
+ const rcFiles = [];
3617
+ const shell = process.env.SHELL || "";
3618
+ if (shell.includes("zsh")) {
3619
+ rcFiles.push(path.join(home, ".zshrc"));
3620
+ } else if (shell.includes("fish")) {
3621
+ rcFiles.push(path.join(home, ".config", "fish", "config.fish"));
3622
+ } else {
3623
+ rcFiles.push(path.join(home, ".bashrc"));
3624
+ const bashProfile = path.join(home, ".bash_profile");
3625
+ if (fs.existsSync(bashProfile)) {
3626
+ rcFiles.push(bashProfile);
3627
+ }
3628
+ }
3629
+ return rcFiles;
3630
+ }
3631
+ function ensureEnvInShellRc(key, value) {
3632
+ const exportLine = `export ${key}=${value}`;
3633
+ const marker = `# Added by clikit-plugin`;
3634
+ const block = `
3635
+ ${marker}
3636
+ ${exportLine}
3637
+ `;
3638
+ const rcFiles = getShellRcFiles();
3639
+ for (const rcFile of rcFiles) {
3640
+ try {
3641
+ const existing = fs.existsSync(rcFile) ? fs.readFileSync(rcFile, "utf-8") : "";
3642
+ if (existing.includes(`export ${key}=`) || existing.includes(`${key}=`)) {
3643
+ console.log(`\u2713 ${key} already set in ${rcFile}`);
3644
+ continue;
3645
+ }
3646
+ fs.appendFileSync(rcFile, block, "utf-8");
3647
+ console.log(`\u2713 Added ${exportLine} to ${rcFile}`);
3648
+ } catch (err) {
3649
+ console.warn(`\u26A0 Could not write to ${rcFile}: ${err}`);
3650
+ }
3651
+ }
3652
+ }
3653
+ function removeLegacyGlobalPluginAssets(configDir) {
3654
+ const legacyPluginPath = path.join(configDir, "plugins", "clikit.js");
3655
+ const legacyAgentsDir = path.join(configDir, "plugins", "agents");
3656
+ const legacyCommandDir = path.join(configDir, "command");
3657
+ const legacyStatusPath = path.join(legacyCommandDir, "status.md");
3658
+ const legacyStatusBeadsPath = path.join(legacyCommandDir, "status-beads.md");
3659
+ if (fs.existsSync(legacyPluginPath)) {
3660
+ fs.rmSync(legacyPluginPath, { force: true });
3661
+ console.log(`\u2713 Removed legacy local plugin file: ${legacyPluginPath}`);
3662
+ }
3663
+ if (fs.existsSync(legacyAgentsDir)) {
3664
+ fs.rmSync(legacyAgentsDir, { recursive: true, force: true });
3665
+ console.log(`\u2713 Removed legacy local agents directory: ${legacyAgentsDir}`);
3666
+ }
3667
+ if (fs.existsSync(legacyStatusPath)) {
3668
+ fs.rmSync(legacyStatusPath, { force: true });
3669
+ console.log(`\u2713 Removed legacy command file: ${legacyStatusPath}`);
3670
+ }
3671
+ if (fs.existsSync(legacyStatusBeadsPath)) {
3672
+ fs.rmSync(legacyStatusBeadsPath, { force: true });
3673
+ console.log(`\u2713 Removed legacy command file: ${legacyStatusBeadsPath}`);
3674
+ }
3675
+ }
3676
+ function getRealHome() {
3677
+ if (process.env.SNAP_REAL_HOME) {
3678
+ return process.env.SNAP_REAL_HOME;
3679
+ }
3680
+ const home = os.homedir();
3681
+ const snapMatch = home.match(/^(\/home\/[^/]+)\/snap\//);
3682
+ if (snapMatch) {
3683
+ return snapMatch[1];
3684
+ }
3685
+ return home;
3686
+ }
3687
+ function getConfigDir() {
3688
+ if (process.env.OPENCODE_CONFIG_DIR) {
3689
+ return process.env.OPENCODE_CONFIG_DIR;
3690
+ }
3691
+ const home = getRealHome();
3692
+ if (process.platform === "win32") {
3693
+ return path.join(process.env.APPDATA || path.join(home, "AppData", "Roaming"), "opencode");
3694
+ }
3695
+ return path.join(process.env.XDG_CONFIG_HOME || path.join(home, ".config"), "opencode");
3696
+ }
3697
+ function getConfigPath() {
3698
+ const configDir = getConfigDir();
3699
+ const jsonPath = path.join(configDir, "opencode.json");
3700
+ const jsoncPath = path.join(configDir, "opencode.jsonc");
3701
+ if (fs.existsSync(jsoncPath))
3702
+ return jsoncPath;
3703
+ if (fs.existsSync(jsonPath))
3704
+ return jsonPath;
3705
+ return jsonPath;
3706
+ }
3707
+ function getCliKitConfigPath(configDir = getConfigDir()) {
3708
+ const candidates = ["clikit.jsonc", "clikit.json", "clikit.config.json"];
3709
+ for (const name of candidates) {
3710
+ const fullPath = path.join(configDir, name);
3711
+ if (fs.existsSync(fullPath)) {
3712
+ return fullPath;
3713
+ }
3714
+ }
3715
+ return path.join(configDir, "clikit.json");
3716
+ }
3717
+ function ensureConfigDir() {
3718
+ const configDir = getConfigDir();
3719
+ if (!fs.existsSync(configDir)) {
3720
+ fs.mkdirSync(configDir, { recursive: true });
3721
+ }
3722
+ }
3723
+ function parseConfig(configPath) {
3724
+ try {
3725
+ if (!fs.existsSync(configPath)) {
3726
+ return { config: {}, raw: "", parseError: null };
3727
+ }
3728
+ const content = fs.readFileSync(configPath, "utf-8");
3729
+ try {
3730
+ const parsed = JSON.parse(content);
3731
+ return { config: parsed, raw: content, parseError: null };
3732
+ } catch {
3733
+ const cleaned = content.replace(/\/\*[\s\S]*?\*\//g, "");
3734
+ const cleanedTrailing = cleaned.replace(/,\s*([}\]])/g, "$1");
3735
+ const parsed = JSON.parse(cleanedTrailing);
3736
+ return { config: parsed, raw: content, parseError: null };
3737
+ }
3738
+ } catch (err) {
3739
+ const raw = fs.existsSync(configPath) ? fs.readFileSync(configPath, "utf-8") : "";
3740
+ return { config: {}, raw, parseError: String(err) };
3741
+ }
3742
+ }
3743
+ function writeConfig(configPath, config) {
3744
+ ensureConfigDir();
3745
+ const tmpPath = `${configPath}.tmp`;
3746
+ const content = JSON.stringify(config, null, 2) + `
3747
+ `;
3748
+ fs.writeFileSync(tmpPath, content);
3749
+ fs.renameSync(tmpPath, configPath);
3750
+ }
3751
+ async function install(options2) {
3752
+ const pluginEntry = getPluginEntry();
3753
+ try {
3754
+ ensureConfigDir();
3755
+ const configPath = getConfigPath();
3756
+ const result = parseConfig(configPath);
3757
+ if (result.parseError && result.raw.trim()) {
3758
+ console.error(`\u2717 Config file has syntax errors and cannot be safely modified.`);
3759
+ console.error(` Error: ${result.parseError}`);
3760
+ console.error(` Please fix the config file manually.`);
3761
+ return 1;
3762
+ }
3763
+ const config = result.config;
3764
+ const existingPlugins = Array.isArray(config.plugin) ? config.plugin.filter((p) => typeof p === "string") : [];
3765
+ const filteredPlugins = upsertPluginEntry(existingPlugins, pluginEntry);
3766
+ const finalPlugins = upsertPluginEntry(filteredPlugins, DCP_PLUGIN_ENTRY);
3767
+ const pluginMergedConfig = { ...config, plugin: finalPlugins };
3768
+ writeConfig(configPath, pluginMergedConfig);
3769
+ if (options2.includeProjectScaffold) {
3770
+ const projectDir = resolveProjectDir();
3771
+ scaffoldProjectOpencode(projectDir);
3772
+ }
3773
+ removeLegacyGlobalPluginAssets(getConfigDir());
3774
+ ensureEnvInShellRc("OPENCODE_ENABLE_EXA", "1");
3775
+ const memoryDir = path.join(getConfigDir(), "memory");
3776
+ const memorySubdirs = ["specs", "plans", "research", "reviews", "handoffs", "beads", "prds"];
3777
+ for (const subdir of memorySubdirs) {
3778
+ const dir = path.join(memoryDir, subdir);
3779
+ if (!fs.existsSync(dir)) {
3780
+ fs.mkdirSync(dir, { recursive: true });
3781
+ }
3782
+ }
3783
+ const clikitConfigPath = getCliKitConfigPath();
3784
+ if (!fs.existsSync(clikitConfigPath)) {
3785
+ const defaultConfig = {
3786
+ $schema: `https://unpkg.com/${PLUGIN_NAME}@latest/schema.json`,
3787
+ disabled_agents: [],
3788
+ disabled_commands: [],
3789
+ disabled_skills: [],
3790
+ agents: {},
3791
+ commands: {},
3792
+ skills: {
3793
+ enable: [],
3794
+ disable: []
3795
+ },
3796
+ hooks: {}
3797
+ };
3798
+ writeConfig(clikitConfigPath, defaultConfig);
3799
+ }
3800
+ console.log(`\u2713 CliKit installed (${pluginEntry})`);
3801
+ console.log(`\u2713 DCP installed (${DCP_PLUGIN_ENTRY})`);
3802
+ console.log(`\u2713 Config: ${configPath}`);
3803
+ console.log("\u2713 Restart OpenCode");
3804
+ return 0;
3805
+ } catch (err) {
3806
+ console.error(`\u2717 Install failed: ${err}`);
3807
+ return 1;
3808
+ }
3809
+ }
3810
+ function help() {
3811
+ console.log(`
3812
+ CliKit - OpenCode Plugin
3813
+
3814
+ Usage:
3815
+ bun x clikit-plugin <command>
3816
+
3817
+ Commands:
3818
+ install Install CliKit globally for OpenCode
3819
+ help Show this help message
3820
+ version Show version
3821
+
3822
+ Install options:
3823
+ --project Also scaffold project .opencode files (default: disabled)
3824
+
3825
+ Examples:
3826
+ bun x clikit-plugin install
3827
+ bun x clikit-plugin install --project
3828
+ `);
3829
+ }
3830
+ function version() {
3831
+ console.log(`clikit-plugin v${getPackageVersion()}`);
3832
+ }
3833
+ async function main() {
3834
+ const args = process.argv.slice(2);
3835
+ const command = args[0] || "help";
3836
+ const flags = args.slice(1);
3837
+ let exitCode = 0;
3838
+ switch (command) {
3839
+ case "install":
3840
+ case "i":
3841
+ exitCode = await install({
3842
+ includeProjectScaffold: flags.includes("--project")
3843
+ });
3844
+ break;
3845
+ case "help":
3846
+ case "-h":
3847
+ case "--help":
3848
+ help();
3849
+ break;
3850
+ case "version":
3851
+ case "-v":
3852
+ case "--version":
3853
+ version();
3854
+ break;
3855
+ default:
3856
+ console.error(`Unknown command: ${command}`);
3857
+ help();
3858
+ exitCode = 1;
3859
+ }
3860
+ process.exit(exitCode);
3861
+ }
3862
+ if (import.meta.main) {
3863
+ main().catch((err) => {
3864
+ console.error(err);
3865
+ process.exit(1);
3866
+ });
3867
+ }
3868
+
3503
3869
  // node_modules/zod/v4/classic/external.js
3504
3870
  var exports_external = {};
3505
3871
  __export(exports_external, {
@@ -3733,7 +4099,7 @@ __export(exports_external, {
3733
4099
  // node_modules/zod/v4/core/index.js
3734
4100
  var exports_core2 = {};
3735
4101
  __export(exports_core2, {
3736
- version: () => version,
4102
+ version: () => version2,
3737
4103
  util: () => exports_util,
3738
4104
  treeifyError: () => treeifyError,
3739
4105
  toJSONSchema: () => toJSONSchema,
@@ -4229,10 +4595,10 @@ function mergeDefs(...defs) {
4229
4595
  function cloneDef(schema) {
4230
4596
  return mergeDefs(schema._zod.def);
4231
4597
  }
4232
- function getElementAtPath(obj, path) {
4233
- if (!path)
4598
+ function getElementAtPath(obj, path2) {
4599
+ if (!path2)
4234
4600
  return obj;
4235
- return path.reduce((acc, key) => acc?.[key], obj);
4601
+ return path2.reduce((acc, key) => acc?.[key], obj);
4236
4602
  }
4237
4603
  function promiseAllObject(promisesObj) {
4238
4604
  const keys = Object.keys(promisesObj);
@@ -4591,11 +4957,11 @@ function aborted(x, startIndex = 0) {
4591
4957
  }
4592
4958
  return false;
4593
4959
  }
4594
- function prefixIssues(path, issues) {
4960
+ function prefixIssues(path2, issues) {
4595
4961
  return issues.map((iss) => {
4596
4962
  var _a;
4597
4963
  (_a = iss).path ?? (_a.path = []);
4598
- iss.path.unshift(path);
4964
+ iss.path.unshift(path2);
4599
4965
  return iss;
4600
4966
  });
4601
4967
  }
@@ -4763,7 +5129,7 @@ function treeifyError(error, _mapper) {
4763
5129
  return issue2.message;
4764
5130
  };
4765
5131
  const result = { errors: [] };
4766
- const processError = (error2, path = []) => {
5132
+ const processError = (error2, path2 = []) => {
4767
5133
  var _a, _b;
4768
5134
  for (const issue2 of error2.issues) {
4769
5135
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -4773,7 +5139,7 @@ function treeifyError(error, _mapper) {
4773
5139
  } else if (issue2.code === "invalid_element") {
4774
5140
  processError({ issues: issue2.issues }, issue2.path);
4775
5141
  } else {
4776
- const fullpath = [...path, ...issue2.path];
5142
+ const fullpath = [...path2, ...issue2.path];
4777
5143
  if (fullpath.length === 0) {
4778
5144
  result.errors.push(mapper(issue2));
4779
5145
  continue;
@@ -4805,8 +5171,8 @@ function treeifyError(error, _mapper) {
4805
5171
  }
4806
5172
  function toDotPath(_path) {
4807
5173
  const segs = [];
4808
- const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
4809
- for (const seg of path) {
5174
+ const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
5175
+ for (const seg of path2) {
4810
5176
  if (typeof seg === "number")
4811
5177
  segs.push(`[${seg}]`);
4812
5178
  else if (typeof seg === "symbol")
@@ -4990,10 +5356,10 @@ var nanoid = /^[a-zA-Z0-9_-]{21}$/;
4990
5356
  var duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
4991
5357
  var extendedDuration = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
4992
5358
  var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
4993
- var uuid = (version) => {
4994
- if (!version)
5359
+ var uuid = (version2) => {
5360
+ if (!version2)
4995
5361
  return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
4996
- return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
5362
+ return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
4997
5363
  };
4998
5364
  var uuid4 = /* @__PURE__ */ uuid(4);
4999
5365
  var uuid6 = /* @__PURE__ */ uuid(6);
@@ -5652,7 +6018,7 @@ class Doc {
5652
6018
  }
5653
6019
 
5654
6020
  // node_modules/zod/v4/core/versions.js
5655
- var version = {
6021
+ var version2 = {
5656
6022
  major: 4,
5657
6023
  minor: 1,
5658
6024
  patch: 8
@@ -5664,7 +6030,7 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
5664
6030
  inst ?? (inst = {});
5665
6031
  inst._zod.def = def;
5666
6032
  inst._zod.bag = inst._zod.bag || {};
5667
- inst._zod.version = version;
6033
+ inst._zod.version = version2;
5668
6034
  const checks = [...inst._zod.def.checks ?? []];
5669
6035
  if (inst._zod.traits.has("$ZodCheck")) {
5670
6036
  checks.unshift(inst);
@@ -15823,15 +16189,18 @@ tool.schema = exports_external;
15823
16189
  // src/index.ts
15824
16190
  import { execFile as execFile3 } from "child_process";
15825
16191
  import { promisify as promisify3 } from "util";
16192
+ import * as fs11 from "fs";
16193
+ import * as path11 from "path";
16194
+ import * as os3 from "os";
15826
16195
 
15827
16196
  // src/agents/index.ts
15828
16197
  var import_gray_matter = __toESM(require_gray_matter(), 1);
15829
- import * as fs2 from "fs";
15830
- import * as path2 from "path";
16198
+ import * as fs3 from "fs";
16199
+ import * as path3 from "path";
15831
16200
 
15832
16201
  // src/hooks/error-logger.ts
15833
- import * as fs from "fs";
15834
- import * as path from "path";
16202
+ import * as fs2 from "fs";
16203
+ import * as path2 from "path";
15835
16204
  var BLOCKED_TOOL_ERROR_PREFIX = "[CliKit] Blocked tool execution:";
15836
16205
  var _initErrorBuffer = [];
15837
16206
  function bufferInitError(source, level, message, context) {
@@ -15874,10 +16243,10 @@ function formatHookErrorLog(hookName, error45, context) {
15874
16243
  }
15875
16244
  function writeErrorLog(hookName, error45, projectDir, context) {
15876
16245
  try {
15877
- const logDir = path.join(projectDir, ".opencode");
15878
- const logPath = path.join(logDir, "error-log.txt");
15879
- if (!fs.existsSync(logDir)) {
15880
- fs.mkdirSync(logDir, { recursive: true });
16246
+ const logDir = path2.join(projectDir, ".opencode");
16247
+ const logPath = path2.join(logDir, "error-log.txt");
16248
+ if (!fs2.existsSync(logDir)) {
16249
+ fs2.mkdirSync(logDir, { recursive: true });
15881
16250
  }
15882
16251
  const timestamp = new Date().toISOString();
15883
16252
  const message = getErrorMessage(error45);
@@ -15894,15 +16263,15 @@ ${stack}`] : [],
15894
16263
  ""
15895
16264
  ].join(`
15896
16265
  `);
15897
- fs.appendFileSync(logPath, entry, "utf-8");
16266
+ fs2.appendFileSync(logPath, entry, "utf-8");
15898
16267
  } catch {}
15899
16268
  }
15900
16269
  function writeBufferedErrorLog(entry, projectDir) {
15901
16270
  try {
15902
- const logDir = path.join(projectDir, ".opencode");
15903
- const logPath = path.join(logDir, "error-log.txt");
15904
- if (!fs.existsSync(logDir)) {
15905
- fs.mkdirSync(logDir, { recursive: true });
16271
+ const logDir = path2.join(projectDir, ".opencode");
16272
+ const logPath = path2.join(logDir, "error-log.txt");
16273
+ if (!fs2.existsSync(logDir)) {
16274
+ fs2.mkdirSync(logDir, { recursive: true });
15906
16275
  }
15907
16276
  const timestamp = new Date().toISOString();
15908
16277
  const contextStr = entry.context && Object.keys(entry.context).length > 0 ? `context: ${JSON.stringify(entry.context, null, 2)}` : "";
@@ -15915,29 +16284,29 @@ function writeBufferedErrorLog(entry, projectDir) {
15915
16284
  ""
15916
16285
  ].join(`
15917
16286
  `);
15918
- fs.appendFileSync(logPath, line, "utf-8");
16287
+ fs2.appendFileSync(logPath, line, "utf-8");
15919
16288
  } catch {}
15920
16289
  }
15921
16290
 
15922
16291
  // src/agents/index.ts
15923
16292
  var AGENTS_DIR_CANDIDATES = [
15924
16293
  import.meta.dir,
15925
- path2.join(import.meta.dir, "../src/agents"),
15926
- path2.join(import.meta.dir, "../../src/agents"),
15927
- path2.join(import.meta.dir, "../agents")
16294
+ path3.join(import.meta.dir, "../src/agents"),
16295
+ path3.join(import.meta.dir, "../../src/agents"),
16296
+ path3.join(import.meta.dir, "../agents")
15928
16297
  ];
15929
16298
  function resolveAgentsDir() {
15930
16299
  for (const dir of AGENTS_DIR_CANDIDATES) {
15931
- if (!fs2.existsSync(dir))
16300
+ if (!fs3.existsSync(dir))
15932
16301
  continue;
15933
16302
  try {
15934
- const hasAgentFiles = fs2.readdirSync(dir).some((f) => f.endsWith(".md") && f !== "AGENTS.md");
16303
+ const hasAgentFiles = fs3.readdirSync(dir).some((f) => f.endsWith(".md") && f !== "AGENTS.md");
15935
16304
  if (hasAgentFiles)
15936
16305
  return dir;
15937
16306
  } catch {}
15938
16307
  }
15939
16308
  for (const dir of AGENTS_DIR_CANDIDATES) {
15940
- if (fs2.existsSync(dir)) {
16309
+ if (fs3.existsSync(dir)) {
15941
16310
  return dir;
15942
16311
  }
15943
16312
  }
@@ -15946,7 +16315,7 @@ function resolveAgentsDir() {
15946
16315
  var VALID_MODES = new Set(["subagent", "primary", "all"]);
15947
16316
  function validateFrontmatter(frontmatter, filePath) {
15948
16317
  const warnings = [];
15949
- const name = path2.basename(filePath, ".md");
16318
+ const name = path3.basename(filePath, ".md");
15950
16319
  if (!frontmatter.description) {
15951
16320
  warnings.push(`[${name}] Missing 'description' \u2014 agent will have empty description`);
15952
16321
  }
@@ -15969,7 +16338,7 @@ function validateFrontmatter(frontmatter, filePath) {
15969
16338
  }
15970
16339
  function parseAgentMarkdown(filePath) {
15971
16340
  try {
15972
- const content = fs2.readFileSync(filePath, "utf-8");
16341
+ const content = fs3.readFileSync(filePath, "utf-8");
15973
16342
  const { data: frontmatter, content: body } = import_gray_matter.default(content);
15974
16343
  const warnings = validateFrontmatter(frontmatter, filePath);
15975
16344
  for (const warning of warnings) {
@@ -16005,13 +16374,13 @@ function parseAgentMarkdown(filePath) {
16005
16374
  function loadAgents() {
16006
16375
  const agents = {};
16007
16376
  const agentsDir = resolveAgentsDir();
16008
- if (!fs2.existsSync(agentsDir)) {
16377
+ if (!fs3.existsSync(agentsDir)) {
16009
16378
  return agents;
16010
16379
  }
16011
- const files = fs2.readdirSync(agentsDir).filter((f) => f.endsWith(".md") && f !== "AGENTS.md").sort();
16380
+ const files = fs3.readdirSync(agentsDir).filter((f) => f.endsWith(".md") && f !== "AGENTS.md").sort();
16012
16381
  for (const file2 of files) {
16013
- const agentName = path2.basename(file2, ".md");
16014
- const agentPath = path2.join(agentsDir, file2);
16382
+ const agentName = path3.basename(file2, ".md");
16383
+ const agentPath = path3.join(agentsDir, file2);
16015
16384
  const agent = parseAgentMarkdown(agentPath);
16016
16385
  if (agent) {
16017
16386
  agents[agentName] = agent;
@@ -16022,10 +16391,10 @@ function loadAgents() {
16022
16391
  var _cachedAgents = null;
16023
16392
  var _cachedAgentsFingerprint = "";
16024
16393
  function getAgentsFingerprint(agentsDir) {
16025
- const files = fs2.readdirSync(agentsDir).filter((f) => f.endsWith(".md") && f !== "AGENTS.md").sort();
16394
+ const files = fs3.readdirSync(agentsDir).filter((f) => f.endsWith(".md") && f !== "AGENTS.md").sort();
16026
16395
  const parts = files.map((file2) => {
16027
- const fullPath = path2.join(agentsDir, file2);
16028
- const stat = fs2.statSync(fullPath);
16396
+ const fullPath = path3.join(agentsDir, file2);
16397
+ const stat = fs3.statSync(fullPath);
16029
16398
  const size = stat.size;
16030
16399
  return `${file2}:${stat.mtimeMs}:${size}`;
16031
16400
  });
@@ -16047,16 +16416,16 @@ function getBuiltinAgents() {
16047
16416
 
16048
16417
  // src/commands/index.ts
16049
16418
  var import_gray_matter2 = __toESM(require_gray_matter(), 1);
16050
- import * as fs3 from "fs";
16051
- import * as path3 from "path";
16419
+ import * as fs4 from "fs";
16420
+ import * as path4 from "path";
16052
16421
  var COMMANDS_DIR_CANDIDATES = [
16053
- path3.join(import.meta.dir, "../command"),
16054
- path3.join(import.meta.dir, "../../command"),
16055
- path3.join(import.meta.dir, "../../../command")
16422
+ path4.join(import.meta.dir, "../command"),
16423
+ path4.join(import.meta.dir, "../../command"),
16424
+ path4.join(import.meta.dir, "../../../command")
16056
16425
  ];
16057
16426
  function resolveCommandsDir() {
16058
16427
  for (const dir of COMMANDS_DIR_CANDIDATES) {
16059
- if (fs3.existsSync(dir)) {
16428
+ if (fs4.existsSync(dir)) {
16060
16429
  return dir;
16061
16430
  }
16062
16431
  }
@@ -16064,7 +16433,7 @@ function resolveCommandsDir() {
16064
16433
  }
16065
16434
  function parseCommandMarkdown(filePath) {
16066
16435
  try {
16067
- const content = fs3.readFileSync(filePath, "utf-8");
16436
+ const content = fs4.readFileSync(filePath, "utf-8");
16068
16437
  const { data: frontmatter, content: body } = import_gray_matter2.default(content);
16069
16438
  const config2 = {
16070
16439
  description: frontmatter.description || "",
@@ -16091,13 +16460,13 @@ function parseCommandMarkdown(filePath) {
16091
16460
  function loadCommands() {
16092
16461
  const commands = {};
16093
16462
  const commandsDir = resolveCommandsDir();
16094
- if (!fs3.existsSync(commandsDir)) {
16463
+ if (!fs4.existsSync(commandsDir)) {
16095
16464
  return commands;
16096
16465
  }
16097
- const files = fs3.readdirSync(commandsDir).filter((f) => f.endsWith(".md")).sort();
16466
+ const files = fs4.readdirSync(commandsDir).filter((f) => f.endsWith(".md")).sort();
16098
16467
  for (const file2 of files) {
16099
- const commandName = path3.basename(file2, ".md");
16100
- const commandPath = path3.join(commandsDir, file2);
16468
+ const commandName = path4.basename(file2, ".md");
16469
+ const commandPath = path4.join(commandsDir, file2);
16101
16470
  const command = parseCommandMarkdown(commandPath);
16102
16471
  if (command) {
16103
16472
  commands[commandName] = command;
@@ -16108,10 +16477,10 @@ function loadCommands() {
16108
16477
  var _cachedCommands = null;
16109
16478
  var _cachedCommandsFingerprint = "";
16110
16479
  function getCommandsFingerprint(commandsDir) {
16111
- const files = fs3.readdirSync(commandsDir).filter((f) => f.endsWith(".md")).sort();
16480
+ const files = fs4.readdirSync(commandsDir).filter((f) => f.endsWith(".md")).sort();
16112
16481
  const parts = files.map((file2) => {
16113
- const fullPath = path3.join(commandsDir, file2);
16114
- const stat = fs3.statSync(fullPath);
16482
+ const fullPath = path4.join(commandsDir, file2);
16483
+ const stat = fs4.statSync(fullPath);
16115
16484
  return `${file2}:${stat.mtimeMs}`;
16116
16485
  });
16117
16486
  return parts.join("|");
@@ -16132,16 +16501,16 @@ function getBuiltinCommands() {
16132
16501
 
16133
16502
  // src/skills/index.ts
16134
16503
  var import_gray_matter3 = __toESM(require_gray_matter(), 1);
16135
- import * as fs4 from "fs";
16136
- import * as path4 from "path";
16504
+ import * as fs5 from "fs";
16505
+ import * as path5 from "path";
16137
16506
  var SKILLS_DIR_CANDIDATES = [
16138
- path4.join(import.meta.dir, "../skill"),
16139
- path4.join(import.meta.dir, "../../skill"),
16140
- path4.join(import.meta.dir, "../../../skill")
16507
+ path5.join(import.meta.dir, "../skill"),
16508
+ path5.join(import.meta.dir, "../../skill"),
16509
+ path5.join(import.meta.dir, "../../../skill")
16141
16510
  ];
16142
16511
  function resolveSkillsDir() {
16143
16512
  for (const dir of SKILLS_DIR_CANDIDATES) {
16144
- if (fs4.existsSync(dir)) {
16513
+ if (fs5.existsSync(dir)) {
16145
16514
  return dir;
16146
16515
  }
16147
16516
  }
@@ -16150,23 +16519,23 @@ function resolveSkillsDir() {
16150
16519
  function getBuiltinSkills() {
16151
16520
  const skills = {};
16152
16521
  const skillsDir = resolveSkillsDir();
16153
- if (!fs4.existsSync(skillsDir)) {
16522
+ if (!fs5.existsSync(skillsDir)) {
16154
16523
  bufferInitError("skills", "warn", `Skills directory not found: ${skillsDir}`);
16155
16524
  return skills;
16156
16525
  }
16157
- const skillDirs = fs4.readdirSync(skillsDir, { withFileTypes: true });
16526
+ const skillDirs = fs5.readdirSync(skillsDir, { withFileTypes: true });
16158
16527
  for (const dirent of skillDirs) {
16159
16528
  if (!dirent.isDirectory())
16160
16529
  continue;
16161
16530
  const skillName = dirent.name;
16162
- const skillPath = path4.join(skillsDir, skillName);
16163
- const skillMdPath = path4.join(skillPath, "SKILL.md");
16164
- if (!fs4.existsSync(skillMdPath)) {
16531
+ const skillPath = path5.join(skillsDir, skillName);
16532
+ const skillMdPath = path5.join(skillPath, "SKILL.md");
16533
+ if (!fs5.existsSync(skillMdPath)) {
16165
16534
  bufferInitError("skills", "warn", `Missing SKILL.md for skill: ${skillName}`, { skillPath });
16166
16535
  continue;
16167
16536
  }
16168
16537
  try {
16169
- const fileContent = fs4.readFileSync(skillMdPath, "utf-8");
16538
+ const fileContent = fs5.readFileSync(skillMdPath, "utf-8");
16170
16539
  const { data, content } = import_gray_matter3.default(fileContent);
16171
16540
  skills[skillName] = {
16172
16541
  name: data.name || skillName,
@@ -16185,9 +16554,9 @@ function getBuiltinSkills() {
16185
16554
  }
16186
16555
 
16187
16556
  // src/config.ts
16188
- import * as fs5 from "fs";
16189
- import * as path5 from "path";
16190
- import * as os from "os";
16557
+ import * as fs6 from "fs";
16558
+ import * as path6 from "path";
16559
+ import * as os2 from "os";
16191
16560
  var DEFAULT_CONFIG = {
16192
16561
  disabled_agents: [],
16193
16562
  disabled_commands: [],
@@ -16277,15 +16646,15 @@ var DEFAULT_CONFIG = {
16277
16646
  };
16278
16647
  function getUserConfigDir() {
16279
16648
  if (process.platform === "win32") {
16280
- return process.env.APPDATA || path5.join(os.homedir(), "AppData", "Roaming");
16649
+ return process.env.APPDATA || path6.join(os2.homedir(), "AppData", "Roaming");
16281
16650
  }
16282
- return process.env.XDG_CONFIG_HOME || path5.join(os.homedir(), ".config");
16651
+ return process.env.XDG_CONFIG_HOME || path6.join(os2.homedir(), ".config");
16283
16652
  }
16284
16653
  function getOpenCodeConfigDir() {
16285
16654
  if (process.env.OPENCODE_CONFIG_DIR) {
16286
16655
  return process.env.OPENCODE_CONFIG_DIR;
16287
16656
  }
16288
- return path5.join(getUserConfigDir(), "opencode");
16657
+ return path6.join(getUserConfigDir(), "opencode");
16289
16658
  }
16290
16659
  function stripJsonComments(content) {
16291
16660
  let result = "";
@@ -16343,10 +16712,10 @@ function stripJsonComments(content) {
16343
16712
  }
16344
16713
  function loadJsonFile(filePath) {
16345
16714
  try {
16346
- if (!fs5.existsSync(filePath)) {
16715
+ if (!fs6.existsSync(filePath)) {
16347
16716
  return null;
16348
16717
  }
16349
- const content = fs5.readFileSync(filePath, "utf-8");
16718
+ const content = fs6.readFileSync(filePath, "utf-8");
16350
16719
  try {
16351
16720
  return JSON.parse(content);
16352
16721
  } catch {
@@ -16380,12 +16749,12 @@ function loadCliKitConfig(projectDirectory) {
16380
16749
  const userBaseDir = getOpenCodeConfigDir();
16381
16750
  const projectBaseDirs = [
16382
16751
  safeDir,
16383
- path5.join(safeDir, ".opencode")
16752
+ path6.join(safeDir, ".opencode")
16384
16753
  ];
16385
16754
  const configCandidates = ["clikit.jsonc", "clikit.json", "clikit.config.json"];
16386
16755
  let config2 = { ...DEFAULT_CONFIG };
16387
16756
  for (const candidate of configCandidates) {
16388
- const userConfigPath = path5.join(userBaseDir, candidate);
16757
+ const userConfigPath = path6.join(userBaseDir, candidate);
16389
16758
  const userConfig = loadJsonFile(userConfigPath);
16390
16759
  if (userConfig) {
16391
16760
  config2 = deepMerge(config2, userConfig);
@@ -16394,7 +16763,7 @@ function loadCliKitConfig(projectDirectory) {
16394
16763
  }
16395
16764
  for (const baseDir of projectBaseDirs) {
16396
16765
  for (const candidate of configCandidates) {
16397
- const projectConfigPath = path5.join(baseDir, candidate);
16766
+ const projectConfigPath = path6.join(baseDir, candidate);
16398
16767
  const projectConfig = loadJsonFile(projectConfigPath);
16399
16768
  if (projectConfig) {
16400
16769
  config2 = deepMerge(config2, projectConfig);
@@ -16904,8 +17273,8 @@ function formatTruncationLog(result) {
16904
17273
  return `[CliKit:truncator] Truncated output: ${result.originalLines} \u2192 ${result.truncatedLines} lines, saved ${(saved / 1024).toFixed(1)}KB`;
16905
17274
  }
16906
17275
  // src/hooks/memory-digest.ts
16907
- import * as fs6 from "fs";
16908
- import * as path6 from "path";
17276
+ import * as fs7 from "fs";
17277
+ import * as path7 from "path";
16909
17278
  import { Database } from "bun:sqlite";
16910
17279
  function parseJsonArray(value) {
16911
17280
  if (typeof value !== "string" || !value.trim())
@@ -16925,7 +17294,7 @@ function formatDate(iso) {
16925
17294
  }
16926
17295
  }
16927
17296
  function writeTopicFile(memoryDir, type, heading, rows) {
16928
- const topicPath = path6.join(memoryDir, `${type}.md`);
17297
+ const topicPath = path7.join(memoryDir, `${type}.md`);
16929
17298
  const lines = [];
16930
17299
  lines.push(`# ${heading}`);
16931
17300
  lines.push("");
@@ -16966,16 +17335,16 @@ function writeTopicFile(memoryDir, type, heading, rows) {
16966
17335
  lines.push("---");
16967
17336
  lines.push("");
16968
17337
  }
16969
- fs6.writeFileSync(topicPath, lines.join(`
17338
+ fs7.writeFileSync(topicPath, lines.join(`
16970
17339
  `), "utf-8");
16971
17340
  }
16972
17341
  function generateMemoryDigest(projectDir, config2) {
16973
17342
  const result = { written: false, path: "", counts: {} };
16974
17343
  if (typeof projectDir !== "string" || !projectDir)
16975
17344
  return result;
16976
- const memoryDir = path6.join(projectDir, ".opencode", "memory");
16977
- const dbPath = path6.join(memoryDir, "memory.db");
16978
- if (!fs6.existsSync(dbPath)) {
17345
+ const memoryDir = path7.join(projectDir, ".opencode", "memory");
17346
+ const dbPath = path7.join(memoryDir, "memory.db");
17347
+ if (!fs7.existsSync(dbPath)) {
16979
17348
  return result;
16980
17349
  }
16981
17350
  const compactMode = config2?.compact_mode !== false;
@@ -17040,14 +17409,14 @@ function generateMemoryDigest(projectDir, config2) {
17040
17409
  sections.push("*No observations found in memory database.*");
17041
17410
  sections.push("");
17042
17411
  }
17043
- const digestPath = path6.join(memoryDir, "_digest.md");
17412
+ const digestPath = path7.join(memoryDir, "_digest.md");
17044
17413
  const content = sections.join(`
17045
17414
  `);
17046
17415
  try {
17047
- if (!fs6.existsSync(memoryDir)) {
17048
- fs6.mkdirSync(memoryDir, { recursive: true });
17416
+ if (!fs7.existsSync(memoryDir)) {
17417
+ fs7.mkdirSync(memoryDir, { recursive: true });
17049
17418
  }
17050
- fs6.writeFileSync(digestPath, content, "utf-8");
17419
+ fs7.writeFileSync(digestPath, content, "utf-8");
17051
17420
  result.written = true;
17052
17421
  result.path = digestPath;
17053
17422
  } catch {}
@@ -17061,8 +17430,8 @@ function formatDigestLog(result) {
17061
17430
  return `[CliKit:memory-digest] Generated digest: ${parts || "empty"}`;
17062
17431
  }
17063
17432
  // src/hooks/todo-beads-sync.ts
17064
- import * as fs7 from "fs";
17065
- import * as path7 from "path";
17433
+ import * as fs8 from "fs";
17434
+ import * as path8 from "path";
17066
17435
  import { Database as Database2 } from "bun:sqlite";
17067
17436
  import { execFile } from "child_process";
17068
17437
  import { promisify } from "util";
@@ -17217,8 +17586,8 @@ function syncTodosToBeads(projectDirectory, sessionID, todos, config2) {
17217
17586
  skippedReason: "Todo sync disabled; Beads is authoritative"
17218
17587
  };
17219
17588
  }
17220
- const beadsDbPath = path7.join(projectDirectory, ".beads", "beads.db");
17221
- if (!fs7.existsSync(beadsDbPath)) {
17589
+ const beadsDbPath = path8.join(projectDirectory, ".beads", "beads.db");
17590
+ if (!fs8.existsSync(beadsDbPath)) {
17222
17591
  return {
17223
17592
  synced: false,
17224
17593
  sessionID,
@@ -17248,7 +17617,7 @@ function syncTodosToBeads(projectDirectory, sessionID, todos, config2) {
17248
17617
  throw lastError instanceof Error ? lastError : new Error("Todo-Beads sync failed after retries");
17249
17618
  }
17250
17619
  function flushBeadsJsonl(projectDirectory, result) {
17251
- const jsonlPath = path7.join(projectDirectory, ".beads", "issues.jsonl");
17620
+ const jsonlPath = path8.join(projectDirectory, ".beads", "issues.jsonl");
17252
17621
  execFileAsync("bd", ["export", "--force", "-o", jsonlPath], {
17253
17622
  cwd: projectDirectory,
17254
17623
  timeout: 5000
@@ -17265,8 +17634,8 @@ function formatTodoBeadsSyncLog(result) {
17265
17634
  return `[CliKit:todo-beads-sync] session=${result.sessionID} todos=${result.totalTodos} created=${result.created} updated=${result.updated} closed=${result.closed}`;
17266
17635
  }
17267
17636
  // src/hooks/beads-context.ts
17268
- import * as fs8 from "fs";
17269
- import * as path8 from "path";
17637
+ import * as fs9 from "fs";
17638
+ import * as path9 from "path";
17270
17639
  import { Database as Database3 } from "bun:sqlite";
17271
17640
  var BEADS_CONTEXT_BUSY_TIMEOUT_MS = 2000;
17272
17641
  var PRIORITY_LABELS = {
@@ -17282,8 +17651,8 @@ var STATUS_ICONS = {
17282
17651
  closed: "\u2713"
17283
17652
  };
17284
17653
  function openBeadsDbReadonly(projectDirectory) {
17285
- const beadsDbPath = path8.join(projectDirectory, ".beads", "beads.db");
17286
- if (!fs8.existsSync(beadsDbPath)) {
17654
+ const beadsDbPath = path9.join(projectDirectory, ".beads", "beads.db");
17655
+ if (!fs9.existsSync(beadsDbPath)) {
17287
17656
  return null;
17288
17657
  }
17289
17658
  try {
@@ -17440,8 +17809,8 @@ function shouldAttemptTilthForTool(toolName, toolInput) {
17440
17809
  const normalized = toolName.toLowerCase();
17441
17810
  if (!normalized.includes("read"))
17442
17811
  return false;
17443
- const path9 = extractFilePath(toolInput);
17444
- return typeof path9 === "string" && path9.length > 0;
17812
+ const path10 = extractFilePath(toolInput);
17813
+ return typeof path10 === "string" && path10.length > 0;
17445
17814
  }
17446
17815
  function extractFilePath(toolInput) {
17447
17816
  for (const key of ["filePath", "file_path", "path", "file"]) {
@@ -17527,12 +17896,12 @@ import { execFile as execFile2 } from "child_process";
17527
17896
  import { promisify as promisify2 } from "util";
17528
17897
 
17529
17898
  // src/tools/memory-db.ts
17530
- import * as fs9 from "fs";
17531
- import * as path9 from "path";
17899
+ import * as fs10 from "fs";
17900
+ import * as path10 from "path";
17532
17901
  import { Database as Database4 } from "bun:sqlite";
17533
17902
  function getMemoryPaths(projectDir = process.cwd()) {
17534
- const memoryDir = path9.join(projectDir, ".opencode", "memory");
17535
- const memoryDbPath = path9.join(memoryDir, "memory.db");
17903
+ const memoryDir = path10.join(projectDir, ".opencode", "memory");
17904
+ const memoryDbPath = path10.join(memoryDir, "memory.db");
17536
17905
  return { memoryDir, memoryDbPath };
17537
17906
  }
17538
17907
  function ensureObservationSchema(db) {
@@ -17594,8 +17963,8 @@ function ensureObservationSchema(db) {
17594
17963
  function openMemoryDb(options2 = {}) {
17595
17964
  const { projectDir, readonly: readonly2 = false } = options2;
17596
17965
  const { memoryDir, memoryDbPath } = getMemoryPaths(projectDir);
17597
- if (!readonly2 && !fs9.existsSync(memoryDir)) {
17598
- fs9.mkdirSync(memoryDir, { recursive: true });
17966
+ if (!readonly2 && !fs10.existsSync(memoryDir)) {
17967
+ fs10.mkdirSync(memoryDir, { recursive: true });
17599
17968
  }
17600
17969
  const db = new Database4(memoryDbPath, readonly2 ? { readonly: true } : undefined);
17601
17970
  if (!readonly2) {
@@ -17953,6 +18322,49 @@ function buildSummary(sections, maxTokens) {
17953
18322
 
17954
18323
  // src/index.ts
17955
18324
  var execFileAsync3 = promisify3(execFile3);
18325
+ var DCP_PLUGIN_ENTRY2 = "@tarquinen/opencode-dcp@beta";
18326
+ var DCP_PLUGIN_BASE = "@tarquinen/opencode-dcp";
18327
+ function ensureDcpInConfig() {
18328
+ try {
18329
+ const configDir = (() => {
18330
+ if (process.env.OPENCODE_CONFIG_DIR)
18331
+ return process.env.OPENCODE_CONFIG_DIR;
18332
+ const home = (() => {
18333
+ if (process.env.SNAP_REAL_HOME)
18334
+ return process.env.SNAP_REAL_HOME;
18335
+ const h = os3.homedir();
18336
+ const m = h.match(/^(\/home\/[^/]+)\/snap\//);
18337
+ return m ? m[1] : h;
18338
+ })();
18339
+ if (process.platform === "win32") {
18340
+ return path11.join(process.env.APPDATA || path11.join(home, "AppData", "Roaming"), "opencode");
18341
+ }
18342
+ return path11.join(process.env.XDG_CONFIG_HOME || path11.join(home, ".config"), "opencode");
18343
+ })();
18344
+ const jsoncPath = path11.join(configDir, "opencode.jsonc");
18345
+ const jsonPath = path11.join(configDir, "opencode.json");
18346
+ const configPath = fs11.existsSync(jsoncPath) ? jsoncPath : jsonPath;
18347
+ if (!fs11.existsSync(configPath))
18348
+ return;
18349
+ const raw = fs11.readFileSync(configPath, "utf-8");
18350
+ let config2;
18351
+ try {
18352
+ config2 = JSON.parse(raw);
18353
+ } catch {
18354
+ const cleaned = raw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/,\s*([}\]])/g, "$1");
18355
+ config2 = JSON.parse(cleaned);
18356
+ }
18357
+ const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((p) => typeof p === "string") : [];
18358
+ const hasDcp = plugins.some((p) => p === DCP_PLUGIN_BASE || p.startsWith(`${DCP_PLUGIN_BASE}@`));
18359
+ if (hasDcp)
18360
+ return;
18361
+ const updated = upsertPluginEntry(plugins, DCP_PLUGIN_ENTRY2);
18362
+ const tmpPath = `${configPath}.tmp`;
18363
+ fs11.writeFileSync(tmpPath, JSON.stringify({ ...config2, plugin: updated }, null, 2) + `
18364
+ `);
18365
+ fs11.renameSync(tmpPath, configPath);
18366
+ } catch {}
18367
+ }
17956
18368
  var CliKitPlugin = async (ctx) => {
17957
18369
  const todosBySession = new Map;
17958
18370
  const defaultMcpEntries = {
@@ -18209,6 +18621,7 @@ ${(content || "").trim()}`.trim();
18209
18621
  ].join(`
18210
18622
  `);
18211
18623
  }
18624
+ ensureDcpInConfig();
18212
18625
  const pluginConfig = loadCliKitConfig(ctx.directory) ?? {};
18213
18626
  const debugLogsEnabled = pluginConfig.hooks?.session_logging === true && process.env.CLIKIT_DEBUG === "1";
18214
18627
  const toolLogsEnabled = pluginConfig.hooks?.tool_logging === true && process.env.CLIKIT_DEBUG === "1";