@docyrus/docyrus 0.0.22 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +12 -0
  2. package/main.js +234 -11
  3. package/main.js.map +4 -4
  4. package/package.json +6 -4
  5. package/resources/pi-agent/assets/docyrus-logo.svg +16 -0
  6. package/resources/pi-agent/extensions/architect.ts +771 -0
  7. package/resources/pi-agent/extensions/notify.ts +57 -55
  8. package/resources/pi-agent/extensions/pi-custom-compaction/CHANGELOG.md +27 -0
  9. package/resources/pi-agent/extensions/pi-custom-compaction/LICENSE +21 -0
  10. package/resources/pi-agent/extensions/pi-custom-compaction/README.md +244 -0
  11. package/resources/pi-agent/extensions/pi-custom-compaction/VENDORED_FROM.md +6 -0
  12. package/resources/pi-agent/extensions/pi-custom-compaction/banner.png +0 -0
  13. package/resources/pi-agent/extensions/pi-custom-compaction/commands/register-commands.ts +63 -0
  14. package/resources/pi-agent/extensions/pi-custom-compaction/events/register-events.ts +229 -0
  15. package/resources/pi-agent/extensions/pi-custom-compaction/index.ts +10 -0
  16. package/resources/pi-agent/extensions/pi-custom-compaction/package.json +57 -0
  17. package/resources/pi-agent/extensions/pi-custom-compaction/paths.ts +13 -0
  18. package/resources/pi-agent/extensions/pi-custom-compaction/policy/config.ts +32 -0
  19. package/resources/pi-agent/extensions/pi-custom-compaction/policy/merge.ts +67 -0
  20. package/resources/pi-agent/extensions/pi-custom-compaction/policy/parse.ts +354 -0
  21. package/resources/pi-agent/extensions/pi-custom-compaction/policy/types.ts +131 -0
  22. package/resources/pi-agent/extensions/pi-custom-compaction/runtime/model-resolution.ts +77 -0
  23. package/resources/pi-agent/extensions/pi-custom-compaction/runtime/pure.ts +56 -0
  24. package/resources/pi-agent/extensions/pi-custom-compaction/runtime/session-state.ts +244 -0
  25. package/resources/pi-agent/extensions/pi-custom-compaction/summary/generate.ts +184 -0
  26. package/resources/pi-agent/extensions/pi-custom-compaction/summary/template.ts +124 -0
  27. package/server-loader.js +4017 -0
  28. package/server-loader.js.map +7 -0
package/README.md CHANGED
@@ -186,6 +186,17 @@ Launch the OpenTUI terminal UI (requires Bun):
186
186
  docyrus tui
187
187
  ```
188
188
 
189
+ Start the agent HTTP server:
190
+
191
+ ```bash
192
+ docyrus server
193
+ docyrus server --port 4000
194
+ docyrus server --profile agent
195
+ docyrus server --model anthropic/claude-sonnet-4-20250514 --thinking high
196
+ ```
197
+
198
+ For full endpoint documentation see [docs/API.md](docs/API.md).
199
+
189
200
  Launch the scoped pi assistant and coding agent:
190
201
 
191
202
  ```bash
@@ -208,4 +219,5 @@ Inside the interactive agent TUI:
208
219
  ```bash
209
220
  /login # browser or API-key provider chooser
210
221
  /logout # remove saved provider configuration
222
+ /architect <brief> # discover tenant data sources and generate local planning artifacts under docs/architect/
211
223
  ```
package/main.js CHANGED
@@ -18851,7 +18851,7 @@ var require_core3 = __commonJS({
18851
18851
  return match && match.index === 0;
18852
18852
  }
18853
18853
  var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
18854
- function join7(regexps, separator = "|") {
18854
+ function join8(regexps, separator = "|") {
18855
18855
  let numCaptures = 0;
18856
18856
  return regexps.map((regex) => {
18857
18857
  numCaptures += 1;
@@ -19155,7 +19155,7 @@ var require_core3 = __commonJS({
19155
19155
  this.exec = () => null;
19156
19156
  }
19157
19157
  const terminators = this.regexes.map((el) => el[1]);
19158
- this.matcherRe = langRe(join7(terminators), true);
19158
+ this.matcherRe = langRe(join8(terminators), true);
19159
19159
  this.lastIndex = 0;
19160
19160
  }
19161
19161
  /** @param {string} s */
@@ -124678,7 +124678,7 @@ function buildInputSchema(args, env2, options2) {
124678
124678
  // package.json
124679
124679
  var package_default = {
124680
124680
  name: "@docyrus/docyrus",
124681
- version: "0.0.22",
124681
+ version: "0.0.24",
124682
124682
  private: false,
124683
124683
  description: "Docyrus API CLI",
124684
124684
  main: "./main.js",
@@ -124686,17 +124686,19 @@ var package_default = {
124686
124686
  docyrus: "main.js"
124687
124687
  },
124688
124688
  dependencies: {
124689
- "@mozilla/readability": "^0.6.0",
124690
124689
  "@clack/prompts": "^0.11.0",
124691
- "@modelcontextprotocol/ext-apps": "^1.2.2",
124692
- "@modelcontextprotocol/sdk": "^1.25.1",
124690
+ "@hono/node-server": "^1.14.1",
124693
124691
  "@mariozechner/pi-ai": "0.61.0",
124694
124692
  "@mariozechner/pi-coding-agent": "0.61.1",
124693
+ "@modelcontextprotocol/ext-apps": "^1.2.2",
124694
+ "@modelcontextprotocol/sdk": "^1.25.1",
124695
+ "@mozilla/readability": "^0.6.0",
124695
124696
  "@opentui/core": "^0.1.85",
124696
124697
  "@opentui/react": "^0.1.85",
124697
124698
  "@xterm/headless": "^5.5.0",
124698
124699
  cheerio: "^1.1.2",
124699
124700
  diff: "^8.0.2",
124701
+ hono: "^4.7.10",
124700
124702
  incur: "^0.1.6",
124701
124703
  jsdom: "^27.0.1",
124702
124704
  marked: "^15.0.12",
@@ -124872,6 +124874,41 @@ function createCoderCli(dependencies) {
124872
124874
  });
124873
124875
  }
124874
124876
 
124877
+ // src/commands/serverCommand.ts
124878
+ var PI_AGENT_THINKING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh"];
124879
+ function hasRawVerboseFlag2() {
124880
+ return process.argv.includes("--verbose");
124881
+ }
124882
+ function createServerCli(dependencies) {
124883
+ return Cli_exports.create("server", {
124884
+ description: "Start HTTP server bridging pi agent to AI SDK useChat",
124885
+ env: EnvSchema,
124886
+ outputPolicy: "agent-only",
124887
+ options: external_exports.object({
124888
+ profile: external_exports.enum(["agent", "coder"]).default("coder").describe("Agent profile to use"),
124889
+ port: external_exports.coerce.number().int().default(3111).describe("Server port"),
124890
+ provider: external_exports.string().optional().describe("Model provider"),
124891
+ model: external_exports.string().optional().describe("Model pattern or full provider/model id"),
124892
+ thinking: external_exports.enum(PI_AGENT_THINKING_LEVELS2).optional().describe("Thinking level"),
124893
+ sessionDir: external_exports.string().optional().describe("Override session storage directory"),
124894
+ apiKey: external_exports.string().optional().describe("Temporary provider API key override for this run"),
124895
+ verbose: external_exports.boolean().optional().describe("Enable verbose pi startup output")
124896
+ }),
124897
+ run: async (context) => {
124898
+ await dependencies.launchPiAgentServer({
124899
+ profile: context.options.profile,
124900
+ port: context.options.port,
124901
+ provider: context.options.provider,
124902
+ model: context.options.model,
124903
+ thinking: context.options.thinking,
124904
+ sessionDir: context.options.sessionDir,
124905
+ apiKey: context.options.apiKey,
124906
+ verbose: context.options.verbose || hasRawVerboseFlag2() ? true : void 0
124907
+ });
124908
+ }
124909
+ });
124910
+ }
124911
+
124875
124912
  // src/commands/aiCommand.ts
124876
124913
  var import_node_crypto2 = require("node:crypto");
124877
124914
 
@@ -129268,6 +129305,40 @@ function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
129268
129305
  }
129269
129306
  return resolved;
129270
129307
  }
129308
+ function resolveDocyrusCliEntryPath(options2 = {}) {
129309
+ const cwd = options2.cwd ?? process.cwd();
129310
+ const dirname6 = options2.dirname ?? __dirname;
129311
+ const argv = options2.argv ?? process.argv;
129312
+ const fileExists = options2.existsSyncFn ?? import_node_fs5.existsSync;
129313
+ const seen = /* @__PURE__ */ new Set();
129314
+ const candidates = options2.candidatePaths ?? [];
129315
+ const addCandidate = (candidate) => {
129316
+ if (!candidate) {
129317
+ return;
129318
+ }
129319
+ const resolvedCandidate = (0, import_node_path10.resolve)(candidate);
129320
+ if (!seen.has(resolvedCandidate)) {
129321
+ seen.add(resolvedCandidate);
129322
+ candidates.push(resolvedCandidate);
129323
+ }
129324
+ };
129325
+ const argvScript = argv[1]?.trim();
129326
+ const normalizedArgvScript = argvScript ? argvScript.startsWith("/") ? argvScript : (0, import_node_path10.resolve)(cwd, argvScript) : void 0;
129327
+ if (normalizedArgvScript && normalizedArgvScript.endsWith(".js")) {
129328
+ addCandidate(normalizedArgvScript);
129329
+ }
129330
+ addCandidate((0, import_node_path10.resolve)(cwd, "dist/apps/api-cli/main.js"));
129331
+ addCandidate((0, import_node_path10.resolve)(dirname6, "../main.js"));
129332
+ addCandidate((0, import_node_path10.resolve)(dirname6, "main.js"));
129333
+ if (normalizedArgvScript) {
129334
+ addCandidate(normalizedArgvScript);
129335
+ }
129336
+ const resolved = candidates.find((candidate) => fileExists(candidate));
129337
+ if (!resolved) {
129338
+ throw new UserInputError(`Unable to locate the Docyrus CLI entry file. Checked: ${candidates.join(", ")}`);
129339
+ }
129340
+ return resolved;
129341
+ }
129271
129342
  function resolveInstalledPiPackageRootPath(options2 = {}) {
129272
129343
  const cwd = options2.cwd ?? process.cwd();
129273
129344
  const dirname6 = options2.dirname ?? __dirname;
@@ -129498,6 +129569,7 @@ function createPiAgentLauncher(options2) {
129498
129569
  const processExecPath = options2.processExecPath ?? process.execPath;
129499
129570
  const resolveResourceRoot = options2.resolvePackagedPiResourceRootFn ?? resolvePackagedPiResourceRoot;
129500
129571
  const resolveLoaderPath = options2.resolveDocyrusPiLoaderEntryPathFn ?? resolveDocyrusPiLoaderEntryPath;
129572
+ const resolveCliEntryPath = options2.resolveDocyrusCliEntryPathFn ?? resolveDocyrusCliEntryPath;
129501
129573
  const resolvePiPackageRoot = options2.resolveInstalledPiPackageRootPathFn ?? resolveInstalledPiPackageRootPath;
129502
129574
  return async (request) => {
129503
129575
  validatePiAgentLaunchRequest({
@@ -129536,6 +129608,7 @@ function createPiAgentLauncher(options2) {
129536
129608
  spawnCommand
129537
129609
  });
129538
129610
  const loaderEntryPath = resolveLoaderPath({ cwd });
129611
+ const cliEntryPath = resolveCliEntryPath({ cwd });
129539
129612
  const piPackageRoot = resolvePiPackageRoot({ cwd });
129540
129613
  const result = spawnCommand(processExecPath, [loaderEntryPath], {
129541
129614
  stdio: ["inherit", "inherit", "inherit"],
@@ -129546,7 +129619,10 @@ function createPiAgentLauncher(options2) {
129546
129619
  PI_CODING_AGENT_DIR: agentRootPath,
129547
129620
  PI_PACKAGE_DIR: piPackageRoot,
129548
129621
  DOCYRUS_PI_REQUEST: JSON.stringify(request),
129549
- DOCYRUS_PI_VERSION: options2.version || "dev"
129622
+ DOCYRUS_PI_VERSION: options2.version || "dev",
129623
+ DOCYRUS_CLI_EXECUTABLE: processExecPath,
129624
+ DOCYRUS_CLI_ENTRY: cliEntryPath,
129625
+ DOCYRUS_CLI_SCOPE: options2.settingsPaths.scope
129550
129626
  }
129551
129627
  });
129552
129628
  if (result.error) {
@@ -129560,9 +129636,141 @@ function createPiAgentLauncher(options2) {
129560
129636
  };
129561
129637
  }
129562
129638
 
129639
+ // src/services/piAgentServerLauncher.ts
129640
+ var import_node_child_process5 = require("node:child_process");
129641
+ var import_node_fs6 = require("node:fs");
129642
+ var import_node_path11 = require("node:path");
129643
+ var import_node_child_process6 = require("node:child_process");
129644
+ function resolveServerLoaderEntryPath(cwd, dirname6) {
129645
+ const seen = /* @__PURE__ */ new Set();
129646
+ const candidates = [];
129647
+ const addCandidate = (candidate) => {
129648
+ if (!seen.has(candidate)) {
129649
+ seen.add(candidate);
129650
+ candidates.push(candidate);
129651
+ }
129652
+ };
129653
+ const collectAncestorCandidates = (startDir) => {
129654
+ let currentDir = (0, import_node_path11.resolve)(startDir);
129655
+ while (true) {
129656
+ addCandidate((0, import_node_path11.join)(currentDir, "dist", "apps", "api-cli", "server-loader.js"));
129657
+ addCandidate((0, import_node_path11.join)(currentDir, "server-loader.js"));
129658
+ if ((0, import_node_path11.basename)(currentDir) === "dist") {
129659
+ addCandidate((0, import_node_path11.join)(currentDir, "apps", "api-cli", "server-loader.js"));
129660
+ }
129661
+ const parentDir = (0, import_node_path11.resolve)(currentDir, "..");
129662
+ if (parentDir === currentDir) {
129663
+ break;
129664
+ }
129665
+ currentDir = parentDir;
129666
+ }
129667
+ };
129668
+ addCandidate((0, import_node_path11.resolve)(cwd, "dist/apps/api-cli/server-loader.js"));
129669
+ addCandidate((0, import_node_path11.resolve)(dirname6, "../server-loader.js"));
129670
+ addCandidate((0, import_node_path11.resolve)(dirname6, "server-loader.js"));
129671
+ collectAncestorCandidates(cwd);
129672
+ collectAncestorCandidates(dirname6);
129673
+ const resolved = candidates.find((candidate) => (0, import_node_fs6.existsSync)(candidate));
129674
+ if (!resolved) {
129675
+ throw new UserInputError(`Unable to locate Docyrus pi server loader entry file. Checked: ${candidates.join(", ")}`);
129676
+ }
129677
+ return resolved;
129678
+ }
129679
+ function createPiAgentServerLauncher(options2) {
129680
+ const cwd = options2.cwd ?? process.cwd();
129681
+ return async (request) => {
129682
+ const activeEnvironment = await options2.environmentConfigService.getActiveEnvironment();
129683
+ const activeProfile = await options2.authStore.getActiveProfile(activeEnvironment.apiBaseUrl);
129684
+ const settingsRootPath = options2.settingsPaths.rootPath;
129685
+ const agentRootPath = resolveDocyrusPiAgentRootPath(settingsRootPath);
129686
+ const resourceRoot = resolvePackagedPiResourceRoot({ cwd });
129687
+ await syncPackagedSkills({
129688
+ resourceRoot,
129689
+ agentRootPath
129690
+ });
129691
+ await writeRuntimeSkill({
129692
+ agentRootPath,
129693
+ content: createPiAgentRuntimeSkill({
129694
+ scope: options2.settingsPaths.scope,
129695
+ cwd,
129696
+ activeEnvironment,
129697
+ activeProfile,
129698
+ settingsRootPath
129699
+ })
129700
+ });
129701
+ await installExternalDocyrusSkillsOnce({
129702
+ agentRootPath,
129703
+ cwd,
129704
+ scope: options2.settingsPaths.scope,
129705
+ spawnCommand: import_node_child_process6.spawnSync
129706
+ });
129707
+ installPackagedDocyrusPlatformSkill({
129708
+ resourceRoot,
129709
+ cwd,
129710
+ scope: options2.settingsPaths.scope,
129711
+ spawnCommand: import_node_child_process6.spawnSync
129712
+ });
129713
+ const loaderEntryPath = resolveServerLoaderEntryPath(cwd, __dirname);
129714
+ const piPackageRoot = resolveInstalledPiPackageRootPath({ cwd });
129715
+ const child = (0, import_node_child_process5.spawn)(process.execPath, [loaderEntryPath], {
129716
+ stdio: "inherit",
129717
+ cwd,
129718
+ env: {
129719
+ ...process.env,
129720
+ PI_CODING_AGENT_DIR: agentRootPath,
129721
+ PI_PACKAGE_DIR: piPackageRoot,
129722
+ DOCYRUS_PI_REQUEST: JSON.stringify(request),
129723
+ DOCYRUS_PI_VERSION: options2.version || "dev"
129724
+ }
129725
+ });
129726
+ await new Promise((resolve, reject) => {
129727
+ child.on("error", (error48) => {
129728
+ reject(new UserInputError(`Unable to start Docyrus pi server loader: ${error48.message}`, {
129729
+ cause: error48
129730
+ }));
129731
+ });
129732
+ child.on("exit", (code, signal) => {
129733
+ if (code === 0 || code === null) {
129734
+ resolve();
129735
+ } else if (signal) {
129736
+ reject(new UserInputError(`Docyrus pi server loader exited due to signal ${signal}.`));
129737
+ } else {
129738
+ reject(new UserInputError(`Docyrus pi server loader exited with code ${code}.`));
129739
+ }
129740
+ });
129741
+ });
129742
+ };
129743
+ }
129744
+
129745
+ // src/services/stderrFilter.ts
129746
+ var INCUR_SKILLS_OUT_OF_DATE_WARNING_PATTERN = /^⚠ Skills are out of date\. Run '.* skills add' to update\.\n\n$/;
129747
+ function isIncurSkillsOutOfDateWarning(chunk) {
129748
+ const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
129749
+ return INCUR_SKILLS_OUT_OF_DATE_WARNING_PATTERN.test(text);
129750
+ }
129751
+ async function runWithIncurSkillsOutOfDateWarningSuppressed(params) {
129752
+ const stderr = params.stderr ?? process.stderr;
129753
+ const originalWrite = stderr.write;
129754
+ const forwardWrite = stderr.write.bind(stderr);
129755
+ stderr.write = ((...args) => {
129756
+ const [chunk, encodingOrCallback, callback] = args;
129757
+ if (isIncurSkillsOutOfDateWarning(chunk)) {
129758
+ const resolvedCallback = typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
129759
+ resolvedCallback?.();
129760
+ return true;
129761
+ }
129762
+ return forwardWrite(...args);
129763
+ });
129764
+ try {
129765
+ return await params.run();
129766
+ } finally {
129767
+ stderr.write = originalWrite;
129768
+ }
129769
+ }
129770
+
129563
129771
  // src/services/tenantOpenApi.ts
129564
129772
  var import_promises8 = require("node:fs/promises");
129565
- var import_node_path11 = require("node:path");
129773
+ var import_node_path12 = require("node:path");
129566
129774
  function resolveSourceUrl(tenantId, template) {
129567
129775
  return template.replace("{tenantId}", encodeURIComponent(tenantId));
129568
129776
  }
@@ -129586,7 +129794,7 @@ var TenantOpenApiService = class {
129586
129794
  }
129587
129795
  async #writeOpenApiFile(tenantId, parsedContent) {
129588
129796
  const filePath = this.getTenantOpenApiFilePath(tenantId);
129589
- await (0, import_promises8.mkdir)((0, import_node_path11.dirname)(filePath), {
129797
+ await (0, import_promises8.mkdir)((0, import_node_path12.dirname)(filePath), {
129590
129798
  recursive: true,
129591
129799
  mode: 448
129592
129800
  });
@@ -129632,7 +129840,7 @@ var TenantOpenApiService = class {
129632
129840
  throw new AuthSessionError("Tenant ID is required to resolve OpenAPI spec path.");
129633
129841
  }
129634
129842
  const rootPath = this.params?.rootPath || TENANT_OPENAPI_ROOT_PATH;
129635
- return (0, import_node_path11.join)(rootPath, normalizedTenantId, "openapi.json");
129843
+ return (0, import_node_path12.join)(rootPath, normalizedTenantId, "openapi.json");
129636
129844
  }
129637
129845
  async downloadTenantOpenApi(tenantId, options2 = {}) {
129638
129846
  const normalizedTenantId = tenantId.trim();
@@ -129695,6 +129903,7 @@ var ROOT_HELP_COMMANDS = [
129695
129903
  { command: 'ai "<prompt>"', description: "Send a prompt to the default Docyrus CLI agent" },
129696
129904
  { command: "agent [prompt]", description: "Launch the scoped Docyrus pi assistant" },
129697
129905
  { command: "coder [prompt]", description: "Launch the scoped Docyrus pi coding agent" },
129906
+ { command: "server", description: "Start HTTP server bridging pi agent to AI SDK useChat" },
129698
129907
  { command: "chrome start", description: "Launch Chrome with remote debugging on :9222" },
129699
129908
  { command: "chrome nav <url>", description: "Navigate the active Chrome tab" },
129700
129909
  { command: "chrome content <url>", description: "Extract readable page content as markdown" },
@@ -129731,6 +129940,13 @@ function createDocyrusCli(params) {
129731
129940
  cwd: params?.cwd,
129732
129941
  version: package_default.version
129733
129942
  });
129943
+ const piAgentServerLauncher = createPiAgentServerLauncher({
129944
+ settingsPaths,
129945
+ environmentConfigService,
129946
+ authStore,
129947
+ cwd: params?.cwd,
129948
+ version: package_default.version
129949
+ });
129734
129950
  const createAuthSessionService = (apiBaseUrl) => {
129735
129951
  return new AuthSessionService({
129736
129952
  apiBaseUrl: normalizeApiBaseUrl(apiBaseUrl),
@@ -129788,6 +130004,9 @@ function createDocyrusCli(params) {
129788
130004
  cli2.command(createCoderCli({
129789
130005
  launchPiAgent: piAgentLauncher
129790
130006
  }));
130007
+ cli2.command(createServerCli({
130008
+ launchPiAgentServer: piAgentServerLauncher
130009
+ }));
129791
130010
  cli2.command(createChromeCli({
129792
130011
  cwd: params?.cwd
129793
130012
  }));
@@ -129828,7 +130047,11 @@ var runtimeArgs = extractGlobalFlagFromArgv(process.argv.slice(2));
129828
130047
  var cli = createDocyrusCli({
129829
130048
  forceGlobalSettings: runtimeArgs.forceGlobal
129830
130049
  });
129831
- cli.serve(runtimeArgs.argv);
130050
+ void runWithIncurSkillsOutOfDateWarningSuppressed({
130051
+ run: async () => {
130052
+ await cli.serve(runtimeArgs.argv);
130053
+ }
130054
+ });
129832
130055
  var main_default = cli;
129833
130056
  // Annotate the CommonJS export names for ESM import in node:
129834
130057
  0 && (module.exports = {