@docyrus/docyrus 0.0.63 → 0.0.65

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 (36) hide show
  1. package/README.md +19 -0
  2. package/agent-loader.js +165 -21
  3. package/agent-loader.js.map +2 -2
  4. package/main.js +363 -113
  5. package/main.js.map +4 -4
  6. package/package.json +5 -4
  7. package/resources/pi-agent/extensions/browser-tools.ts +1 -1
  8. package/resources/pi-agent/extensions/context.ts +12 -73
  9. package/resources/pi-agent/extensions/control.ts +1 -1
  10. package/resources/pi-agent/extensions/loop.ts +4 -1
  11. package/resources/pi-agent/extensions/pi-bash-live-view/index.ts +1 -1
  12. package/resources/pi-agent/extensions/pi-bash-live-view/package.json +3 -3
  13. package/resources/pi-agent/extensions/pi-fff/README.md +152 -0
  14. package/resources/pi-agent/extensions/pi-fff/VENDORED_FROM.md +7 -0
  15. package/resources/pi-agent/extensions/pi-fff/package.json +53 -0
  16. package/resources/pi-agent/extensions/pi-fff/src/index.ts +820 -0
  17. package/resources/pi-agent/extensions/pi-mcp-adapter/index.ts +1 -1
  18. package/resources/pi-agent/extensions/pi-mcp-adapter/package.json +1 -1
  19. package/resources/pi-agent/extensions/prompt-editor.ts +26 -7
  20. package/resources/pi-agent/extensions/soul.ts +183 -0
  21. package/resources/pi-agent/extensions/todos.ts +1 -1
  22. package/resources/pi-agent/skills/grill-me/SKILL.md +11 -8
  23. package/resources/pi-agent/skills/release-manager/SKILL.md +469 -30
  24. package/resources/pi-agent/souls/boomer-parent.md +23 -0
  25. package/resources/pi-agent/souls/bro.md +22 -0
  26. package/resources/pi-agent/souls/catalog.ts +79 -0
  27. package/resources/pi-agent/souls/caveman.md +21 -0
  28. package/resources/pi-agent/souls/linkedin-influencer.md +60 -0
  29. package/resources/pi-agent/souls/master-yoda.md +22 -0
  30. package/resources/pi-agent/souls/noir-detective.md +24 -0
  31. package/resources/pi-agent/souls/nonsense-engineer.md +23 -0
  32. package/resources/pi-agent/souls/pirate.md +24 -0
  33. package/resources/pi-agent/souls/shakespeare.md +24 -0
  34. package/server-loader.js +803 -93
  35. package/server-loader.js.map +4 -4
  36. package/resources/pi-agent/skills/changelog-generator/SKILL.md +0 -461
package/main.js CHANGED
@@ -18864,7 +18864,7 @@ var require_core3 = __commonJS({
18864
18864
  return match && match.index === 0;
18865
18865
  }
18866
18866
  var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
18867
- function join18(regexps, separator = "|") {
18867
+ function join20(regexps, separator = "|") {
18868
18868
  let numCaptures = 0;
18869
18869
  return regexps.map((regex) => {
18870
18870
  numCaptures += 1;
@@ -19168,7 +19168,7 @@ var require_core3 = __commonJS({
19168
19168
  this.exec = () => null;
19169
19169
  }
19170
19170
  const terminators = this.regexes.map((el) => el[1]);
19171
- this.matcherRe = langRe(join18(terminators), true);
19171
+ this.matcherRe = langRe(join20(terminators), true);
19172
19172
  this.lastIndex = 0;
19173
19173
  }
19174
19174
  /** @param {string} s */
@@ -85749,9 +85749,9 @@ var init_lib10 = __esm({
85749
85749
  * @returns {undefined}
85750
85750
  * Nothing.
85751
85751
  */
85752
- set dirname(dirname13) {
85752
+ set dirname(dirname14) {
85753
85753
  assertPath(this.basename, "dirname");
85754
- this.path = import_node_path7.default.join(dirname13 || "", this.basename);
85754
+ this.path = import_node_path7.default.join(dirname14 || "", this.basename);
85755
85755
  }
85756
85756
  /**
85757
85757
  * Get the extname (including dot) (example: `'.js'`).
@@ -102181,8 +102181,8 @@ var require_snapshot_utils = __commonJS({
102181
102181
  var require_snapshot_recorder = __commonJS({
102182
102182
  "../../node_modules/.pnpm/undici@7.24.7/node_modules/undici/lib/mock/snapshot-recorder.js"(exports2, module2) {
102183
102183
  "use strict";
102184
- var { writeFile: writeFile9, readFile: readFile17, mkdir: mkdir10 } = require("node:fs/promises");
102185
- var { dirname: dirname13, resolve: resolve2 } = require("node:path");
102184
+ var { writeFile: writeFile10, readFile: readFile18, mkdir: mkdir12 } = require("node:fs/promises");
102185
+ var { dirname: dirname14, resolve: resolve2 } = require("node:path");
102186
102186
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = require("node:timers");
102187
102187
  var { InvalidArgumentError, UndiciError } = require_errors3();
102188
102188
  var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -102383,7 +102383,7 @@ var require_snapshot_recorder = __commonJS({
102383
102383
  throw new InvalidArgumentError("Snapshot path is required");
102384
102384
  }
102385
102385
  try {
102386
- const data = await readFile17(resolve2(path8), "utf8");
102386
+ const data = await readFile18(resolve2(path8), "utf8");
102387
102387
  const parsed = JSON.parse(data);
102388
102388
  if (Array.isArray(parsed)) {
102389
102389
  this.#snapshots.clear();
@@ -102413,12 +102413,12 @@ var require_snapshot_recorder = __commonJS({
102413
102413
  throw new InvalidArgumentError("Snapshot path is required");
102414
102414
  }
102415
102415
  const resolvedPath = resolve2(path8);
102416
- await mkdir10(dirname13(resolvedPath), { recursive: true });
102416
+ await mkdir12(dirname14(resolvedPath), { recursive: true });
102417
102417
  const data = Array.from(this.#snapshots.entries()).map(([hash3, snapshot]) => ({
102418
102418
  hash: hash3,
102419
102419
  snapshot
102420
102420
  }));
102421
- await writeFile9(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
102421
+ await writeFile10(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
102422
102422
  }
102423
102423
  /**
102424
102424
  * Clears all recorded snapshots
@@ -138338,8 +138338,8 @@ function sanitizeName(name2) {
138338
138338
  }
138339
138339
  function rmForce(target) {
138340
138340
  try {
138341
- const stat = fs2.lstatSync(target);
138342
- if (stat.isSymbolicLink())
138341
+ const stat2 = fs2.lstatSync(target);
138342
+ if (stat2.isSymbolicLink())
138343
138343
  fs2.unlinkSync(target);
138344
138344
  else
138345
138345
  fs2.rmSync(target, { recursive: true, force: true });
@@ -139349,7 +139349,7 @@ function buildInputSchema(args2, env2, options2) {
139349
139349
  // package.json
139350
139350
  var package_default = {
139351
139351
  name: "@docyrus/docyrus",
139352
- version: "0.0.63",
139352
+ version: "0.0.65",
139353
139353
  private: false,
139354
139354
  description: "Docyrus API CLI",
139355
139355
  main: "./main.js",
@@ -139361,16 +139361,16 @@ var package_default = {
139361
139361
  },
139362
139362
  dependencies: {
139363
139363
  "@clack/prompts": "^0.11.0",
139364
+ "@ff-labs/fff-node": "0.6.4",
139364
139365
  "@hono/node-server": "^1.19.13",
139365
- "@mariozechner/pi-ai": "0.65.0",
139366
- "@mariozechner/pi-coding-agent": "0.65.0",
139366
+ "@mariozechner/pi-ai": "0.69.0",
139367
+ "@mariozechner/pi-coding-agent": "0.69.0",
139367
139368
  "@modelcontextprotocol/ext-apps": "^1.2.2",
139368
139369
  "@modelcontextprotocol/sdk": "^1.25.1",
139369
139370
  "@mozilla/readability": "^0.6.0",
139370
139371
  "@opentui/core": "0.1.96",
139371
139372
  "@opentui/react": "0.1.96",
139372
139373
  "@repomix/tree-sitter-wasms": "^0.1.16",
139373
- "@sinclair/typebox": "^0.34.48",
139374
139374
  "@xterm/headless": "^5.5.0",
139375
139375
  diff: "^9.0.0",
139376
139376
  hono: "^4.12.14",
@@ -139389,6 +139389,7 @@ var package_default = {
139389
139389
  "strip-ansi": "^7.1.0",
139390
139390
  turndown: "^7.2.2",
139391
139391
  "turndown-plugin-gfm": "^1.0.2",
139392
+ typebox: "^1.1.24",
139392
139393
  undici: "^7.24.0",
139393
139394
  unified: "^11.0.5",
139394
139395
  "unist-util-visit": "^5.1.0",
@@ -139423,7 +139424,8 @@ var EnvironmentConfigStateSchema = external_exports.object({
139423
139424
  version: external_exports.literal(1),
139424
139425
  activeEnvironmentId: external_exports.string().min(1),
139425
139426
  environments: external_exports.array(EnvironmentConfigItemSchema).min(1),
139426
- defaultClientId: external_exports.string().min(1).optional()
139427
+ defaultClientId: external_exports.string().min(1).optional(),
139428
+ activeSoulId: external_exports.string().min(1).optional()
139427
139429
  });
139428
139430
  var LegacyAuthSessionSchema = external_exports.object({
139429
139431
  apiBaseUrl: external_exports.string().min(1),
@@ -140219,6 +140221,14 @@ var AUTH_DIR_PATH = (0, import_node_path3.join)((0, import_node_os5.homedir)(),
140219
140221
  var AUTH_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "auth.json");
140220
140222
  var CONFIG_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "config.json");
140221
140223
  var TENANT_OPENAPI_ROOT_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "tenans");
140224
+ var DOCYRUS_PI_AGENT_GLOBAL_ROOT_PATH = (0, import_node_path3.join)(
140225
+ AUTH_DIR_PATH,
140226
+ DOCYRUS_PI_DIR_NAME,
140227
+ DOCYRUS_PI_AGENT_DIR_NAME
140228
+ );
140229
+ function getDocyrusPiAgentGlobalRootPath() {
140230
+ return DOCYRUS_PI_AGENT_GLOBAL_ROOT_PATH;
140231
+ }
140222
140232
  var TENANT_OPENAPI_PUBLIC_URL_TEMPLATE = "https://api.docyrus.app/storage/v1/object/public/tenant-public/{tenantId}/openapi.json";
140223
140233
  var DEFAULT_ENVIRONMENT_ID = "live";
140224
140234
  var DEFAULT_ENVIRONMENTS = [
@@ -140782,12 +140792,12 @@ function summarizeFailure(result) {
140782
140792
  }
140783
140793
  function resolveBrowserToolsResourceRoot(options2 = {}) {
140784
140794
  const cwd = options2.cwd ?? process.cwd();
140785
- const dirname13 = options2.dirname ?? __dirname;
140795
+ const dirname14 = options2.dirname ?? __dirname;
140786
140796
  const fileExists = options2.existsSyncFn ?? import_node_fs3.existsSync;
140787
140797
  const candidates = options2.candidatePaths ?? [
140788
140798
  (0, import_node_path4.resolve)(cwd, "apps/api-cli/resources/browser-tools"),
140789
- (0, import_node_path4.resolve)(dirname13, "../resources/browser-tools"),
140790
- (0, import_node_path4.resolve)(dirname13, "resources/browser-tools"),
140799
+ (0, import_node_path4.resolve)(dirname14, "../resources/browser-tools"),
140800
+ (0, import_node_path4.resolve)(dirname14, "resources/browser-tools"),
140791
140801
  (0, import_node_path4.resolve)(cwd, "dist/apps/api-cli/resources/browser-tools")
140792
140802
  ];
140793
140803
  const resolved = candidates.find((candidate) => fileExists(candidate));
@@ -147901,7 +147911,7 @@ async function resolveKnowledgeProviderFromAgentRuntime(params) {
147901
147911
  }
147902
147912
  };
147903
147913
  }
147904
- const agentRootPath = resolveDocyrusPiAgentRootPath(params.settingsRootPath);
147914
+ const agentRootPath = params.piAgentRootPath ?? getDocyrusPiAgentGlobalRootPath();
147905
147915
  const authState = readJsonFile((0, import_node_path14.join)(agentRootPath, "auth.json")) || {};
147906
147916
  const envStore = new AgentEnvStore((0, import_node_path14.join)(agentRootPath, "env.json"));
147907
147917
  const envState = await envStore.readState();
@@ -152537,16 +152547,16 @@ function resolveCliScriptPath() {
152537
152547
  }
152538
152548
  function resolveOpenTuiEntryPath(options2 = {}) {
152539
152549
  const cwd = options2.cwd ?? process.cwd();
152540
- const dirname13 = options2.dirname ?? __dirname;
152550
+ const dirname14 = options2.dirname ?? __dirname;
152541
152551
  const fileExists = options2.existsSyncFn ?? import_node_fs16.existsSync;
152542
152552
  const candidates = [
152543
152553
  // Source/dev mode in monorepo. Prefer this first so Bun resolves deps via
152544
152554
  // apps/api-cli/node_modules in workspace runs (e.g. `pnpm docyrus tui`).
152545
152555
  (0, import_node_path25.resolve)(cwd, "apps/api-cli/src/tui/opentuiMain.tsx"),
152546
- (0, import_node_path25.resolve)(dirname13, "../tui/opentuiMain.tsx"),
152556
+ (0, import_node_path25.resolve)(dirname14, "../tui/opentuiMain.tsx"),
152547
152557
  // Dist mode (bundled command runtime)
152548
- (0, import_node_path25.resolve)(dirname13, "tui.mjs"),
152549
- (0, import_node_path25.resolve)(dirname13, "../tui.mjs"),
152558
+ (0, import_node_path25.resolve)(dirname14, "tui.mjs"),
152559
+ (0, import_node_path25.resolve)(dirname14, "../tui.mjs"),
152550
152560
  (0, import_node_path25.resolve)(cwd, "dist/apps/api-cli/tui.mjs")
152551
152561
  ];
152552
152562
  const resolved = candidates.find((candidate) => fileExists(candidate));
@@ -153641,6 +153651,76 @@ var AuthStore = class {
153641
153651
  // src/services/environmentConfig.ts
153642
153652
  var import_promises21 = require("node:fs/promises");
153643
153653
  var import_node_path27 = require("node:path");
153654
+
153655
+ // resources/pi-agent/souls/catalog.ts
153656
+ var DEFAULT_SOUL_ID = "default";
153657
+ var SOULS = [
153658
+ {
153659
+ id: "default",
153660
+ name: "Default",
153661
+ description: "Standard Docyrus operator voice. No style overlay.",
153662
+ promptFile: null
153663
+ },
153664
+ {
153665
+ id: "caveman",
153666
+ name: "Caveman",
153667
+ description: "Short grunts. Agent talk simple. Fire good.",
153668
+ promptFile: "caveman.md"
153669
+ },
153670
+ {
153671
+ id: "boomer-parent",
153672
+ name: "Boomer Parent",
153673
+ description: "Overly proud dad-jokes energy with 'back in my day' asides.",
153674
+ promptFile: "boomer-parent.md"
153675
+ },
153676
+ {
153677
+ id: "master-yoda",
153678
+ name: "Master Yoda",
153679
+ description: "Inverted syntax the agent speaks. Mystical brevity, hmm.",
153680
+ promptFile: "master-yoda.md"
153681
+ },
153682
+ {
153683
+ id: "bro",
153684
+ name: "Bro",
153685
+ description: "Pure gym-bro hype energy. 'Lit, fam, let's go.'",
153686
+ promptFile: "bro.md"
153687
+ },
153688
+ {
153689
+ id: "nonsense-engineer",
153690
+ name: "Nonsense Engineer",
153691
+ description: "Maximum jargon, minimum meaning. 'Leveraging synergistic abstractions.'",
153692
+ promptFile: "nonsense-engineer.md"
153693
+ },
153694
+ {
153695
+ id: "shakespeare",
153696
+ name: "Shakespeare",
153697
+ description: "Thee/thou, dramatic flair, iambic vibes.",
153698
+ promptFile: "shakespeare.md"
153699
+ },
153700
+ {
153701
+ id: "noir-detective",
153702
+ name: "Noir Detective",
153703
+ description: "Hard-boiled 1940s narrator. Every bug is a dame.",
153704
+ promptFile: "noir-detective.md"
153705
+ },
153706
+ {
153707
+ id: "pirate",
153708
+ name: "Pirate",
153709
+ description: "Aye matey, every task a seafaring metaphor, arrr.",
153710
+ promptFile: "pirate.md"
153711
+ },
153712
+ {
153713
+ id: "linkedin-influencer",
153714
+ name: "LinkedIn Influencer",
153715
+ description: "Every reply is a mini-post. Single-sentence paragraphs. Humble-brags. 'Agree? \u{1F447}'",
153716
+ promptFile: "linkedin-influencer.md"
153717
+ }
153718
+ ];
153719
+ function findSoul(id) {
153720
+ return SOULS.find((soul) => soul.id === id);
153721
+ }
153722
+
153723
+ // src/services/environmentConfig.ts
153644
153724
  var ENVIRONMENT_ID_ALIASES = {
153645
153725
  "local-development": "dev",
153646
153726
  prod: "live"
@@ -153664,9 +153744,20 @@ function createDefaultState3() {
153664
153744
  name: environment.name,
153665
153745
  apiBaseUrl: environment.apiBaseUrl
153666
153746
  })),
153667
- defaultClientId: void 0
153747
+ defaultClientId: void 0,
153748
+ activeSoulId: DEFAULT_SOUL_ID
153668
153749
  };
153669
153750
  }
153751
+ function normalizeSoulId(value2) {
153752
+ if (!value2) {
153753
+ return DEFAULT_SOUL_ID;
153754
+ }
153755
+ const trimmed = value2.trim();
153756
+ if (!trimmed) {
153757
+ return DEFAULT_SOUL_ID;
153758
+ }
153759
+ return findSoul(trimmed) ? trimmed : DEFAULT_SOUL_ID;
153760
+ }
153670
153761
  function normalizeState3(state) {
153671
153762
  const defaultsById = new Map(
153672
153763
  DEFAULT_ENVIRONMENTS.map((environment) => [
@@ -153717,7 +153808,8 @@ function normalizeState3(state) {
153717
153808
  version: 1,
153718
153809
  activeEnvironmentId: hasActiveEnvironment ? canonicalActiveEnvironmentId : fallbackActiveEnvironment,
153719
153810
  environments,
153720
- defaultClientId: state.defaultClientId?.trim() || void 0
153811
+ defaultClientId: state.defaultClientId?.trim() || void 0,
153812
+ activeSoulId: normalizeSoulId(state.activeSoulId)
153721
153813
  };
153722
153814
  }
153723
153815
  var EnvironmentConfigService = class {
@@ -153822,6 +153914,25 @@ var EnvironmentConfigService = class {
153822
153914
  defaultClientId: trimmedClientId
153823
153915
  });
153824
153916
  }
153917
+ async getActiveSoulId() {
153918
+ const state = await this.#readStateWithDefaults();
153919
+ return normalizeSoulId(state.activeSoulId);
153920
+ }
153921
+ async setActiveSoulId(soulId) {
153922
+ const trimmed = soulId.trim();
153923
+ if (!trimmed) {
153924
+ throw new UserInputError("Soul ID cannot be empty.");
153925
+ }
153926
+ if (!findSoul(trimmed)) {
153927
+ throw new UserInputError(`Unknown soul '${soulId}'. Use /souls inside the pi agent or GET /api/souls to view options.`);
153928
+ }
153929
+ const state = await this.#readStateWithDefaults();
153930
+ await this.writeState({
153931
+ ...state,
153932
+ activeSoulId: trimmed
153933
+ });
153934
+ return trimmed;
153935
+ }
153825
153936
  async #readStateWithDefaults() {
153826
153937
  const state = await this.readState();
153827
153938
  if (state.environments.length > 0) {
@@ -153839,8 +153950,111 @@ var EnvironmentConfigService = class {
153839
153950
  // src/services/piAgentLauncher.ts
153840
153951
  var import_node_child_process8 = require("node:child_process");
153841
153952
  var import_node_fs17 = require("node:fs");
153953
+ var import_promises24 = require("node:fs/promises");
153954
+ var import_node_path30 = require("node:path");
153955
+
153956
+ // src/agent/piAgentMigration.ts
153842
153957
  var import_promises22 = require("node:fs/promises");
153843
153958
  var import_node_path28 = require("node:path");
153959
+ var LEGACY_PI_AGENT_FILES = [
153960
+ "auth.json",
153961
+ "env.json",
153962
+ "models.json",
153963
+ "settings.json"
153964
+ ];
153965
+ async function pathExists(filePath) {
153966
+ try {
153967
+ await (0, import_promises22.access)(filePath);
153968
+ return true;
153969
+ } catch {
153970
+ return false;
153971
+ }
153972
+ }
153973
+ async function safeResolveRealPath(filePath) {
153974
+ try {
153975
+ const stats = await (0, import_promises22.stat)(filePath);
153976
+ return stats.isDirectory() ? filePath : void 0;
153977
+ } catch {
153978
+ return void 0;
153979
+ }
153980
+ }
153981
+ async function migrateLegacyPiAgentDir(params) {
153982
+ if (params.legacyRootPath === params.globalRootPath) {
153983
+ return { migrated: false, copiedFiles: [] };
153984
+ }
153985
+ const globalAuthPath = (0, import_node_path28.join)(params.globalRootPath, "auth.json");
153986
+ if (await pathExists(globalAuthPath)) {
153987
+ return { migrated: false, copiedFiles: [] };
153988
+ }
153989
+ const legacyAuthPath = (0, import_node_path28.join)(params.legacyRootPath, "auth.json");
153990
+ if (!await pathExists(legacyAuthPath)) {
153991
+ return { migrated: false, copiedFiles: [] };
153992
+ }
153993
+ const legacyRoot = await safeResolveRealPath(params.legacyRootPath);
153994
+ if (!legacyRoot) {
153995
+ return { migrated: false, copiedFiles: [] };
153996
+ }
153997
+ await (0, import_promises22.mkdir)(params.globalRootPath, {
153998
+ recursive: true,
153999
+ mode: 448
154000
+ });
154001
+ const copiedFiles = [];
154002
+ for (const fileName of LEGACY_PI_AGENT_FILES) {
154003
+ const source = (0, import_node_path28.join)(params.legacyRootPath, fileName);
154004
+ if (!await pathExists(source)) {
154005
+ continue;
154006
+ }
154007
+ const destination = (0, import_node_path28.join)(params.globalRootPath, fileName);
154008
+ await (0, import_promises22.copyFile)(source, destination);
154009
+ await (0, import_promises22.chmod)(destination, 384).catch(() => {
154010
+ });
154011
+ copiedFiles.push(fileName);
154012
+ }
154013
+ return { migrated: true, copiedFiles };
154014
+ }
154015
+
154016
+ // src/services/soulRegistry.ts
154017
+ var import_promises23 = require("node:fs/promises");
154018
+ var import_node_path29 = require("node:path");
154019
+ function resolveBasePromptPath(params) {
154020
+ const filename = params.profile === "agent" ? "agent-system.md" : "coder-system.md";
154021
+ return (0, import_node_path29.join)(params.resourceRoot, "prompts", filename);
154022
+ }
154023
+ async function composeSystemPrompt(params) {
154024
+ const soul = findSoul(params.soulId) ?? findSoul(DEFAULT_SOUL_ID);
154025
+ if (!soul) {
154026
+ throw new Error(`Soul catalog is missing the '${DEFAULT_SOUL_ID}' entry.`);
154027
+ }
154028
+ const basePromptPath = resolveBasePromptPath({
154029
+ resourceRoot: params.resourceRoot,
154030
+ profile: params.profile
154031
+ });
154032
+ if (!soul.promptFile) {
154033
+ return basePromptPath;
154034
+ }
154035
+ const overlayPath = (0, import_node_path29.join)(params.resourceRoot, "souls", soul.promptFile);
154036
+ const [basePrompt, overlayPrompt] = await Promise.all([
154037
+ (0, import_promises23.readFile)(basePromptPath, "utf8"),
154038
+ (0, import_promises23.readFile)(overlayPath, "utf8")
154039
+ ]);
154040
+ const composedPath = (0, import_node_path29.join)(params.agentRootPath, `system-prompt-${params.profile}.md`);
154041
+ const composed = `${basePrompt.trimEnd()}
154042
+
154043
+ ---
154044
+
154045
+ ${overlayPrompt.trimEnd()}
154046
+ `;
154047
+ await (0, import_promises23.mkdir)((0, import_node_path29.dirname)(composedPath), {
154048
+ recursive: true,
154049
+ mode: 448
154050
+ });
154051
+ await (0, import_promises23.writeFile)(composedPath, composed, {
154052
+ encoding: "utf8",
154053
+ mode: 384
154054
+ });
154055
+ await (0, import_promises23.chmod)(composedPath, 384);
154056
+ return composedPath;
154057
+ }
153844
154058
 
153845
154059
  // src/services/spinner.ts
153846
154060
  var import_picocolors2 = __toESM(require_picocolors());
@@ -153902,13 +154116,13 @@ function summarizeFailure3(result, commandLabel = "Command") {
153902
154116
  }
153903
154117
  function resolvePackagedPiResourceRoot(options2 = {}) {
153904
154118
  const cwd = options2.cwd ?? process.cwd();
153905
- const dirname13 = options2.dirname ?? __dirname;
154119
+ const dirname14 = options2.dirname ?? __dirname;
153906
154120
  const fileExists = options2.existsSyncFn ?? import_node_fs17.existsSync;
153907
154121
  const candidates = [
153908
- (0, import_node_path28.resolve)(cwd, "apps/api-cli/resources/pi-agent"),
153909
- (0, import_node_path28.resolve)(dirname13, "../resources/pi-agent"),
153910
- (0, import_node_path28.resolve)(dirname13, "resources/pi-agent"),
153911
- (0, import_node_path28.resolve)(cwd, "dist/apps/api-cli/resources/pi-agent")
154122
+ (0, import_node_path30.resolve)(cwd, "apps/api-cli/resources/pi-agent"),
154123
+ (0, import_node_path30.resolve)(dirname14, "../resources/pi-agent"),
154124
+ (0, import_node_path30.resolve)(dirname14, "resources/pi-agent"),
154125
+ (0, import_node_path30.resolve)(cwd, "dist/apps/api-cli/resources/pi-agent")
153912
154126
  ];
153913
154127
  const resolved = candidates.find((candidate) => fileExists(candidate));
153914
154128
  if (!resolved) {
@@ -153918,7 +154132,7 @@ function resolvePackagedPiResourceRoot(options2 = {}) {
153918
154132
  }
153919
154133
  function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
153920
154134
  const cwd = options2.cwd ?? process.cwd();
153921
- const dirname13 = options2.dirname ?? __dirname;
154135
+ const dirname14 = options2.dirname ?? __dirname;
153922
154136
  const fileExists = options2.existsSyncFn ?? import_node_fs17.existsSync;
153923
154137
  const seen = /* @__PURE__ */ new Set();
153924
154138
  const candidates = options2.candidatePaths ?? [];
@@ -153929,25 +154143,25 @@ function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
153929
154143
  }
153930
154144
  };
153931
154145
  const collectAncestorCandidates = (startDir) => {
153932
- let currentDir = (0, import_node_path28.resolve)(startDir);
154146
+ let currentDir = (0, import_node_path30.resolve)(startDir);
153933
154147
  while (true) {
153934
- addCandidate((0, import_node_path28.join)(currentDir, "dist", "apps", "api-cli", "agent-loader.js"));
153935
- addCandidate((0, import_node_path28.join)(currentDir, "agent-loader.js"));
153936
- if ((0, import_node_path28.basename)(currentDir) === "dist") {
153937
- addCandidate((0, import_node_path28.join)(currentDir, "apps", "api-cli", "agent-loader.js"));
154148
+ addCandidate((0, import_node_path30.join)(currentDir, "dist", "apps", "api-cli", "agent-loader.js"));
154149
+ addCandidate((0, import_node_path30.join)(currentDir, "agent-loader.js"));
154150
+ if ((0, import_node_path30.basename)(currentDir) === "dist") {
154151
+ addCandidate((0, import_node_path30.join)(currentDir, "apps", "api-cli", "agent-loader.js"));
153938
154152
  }
153939
- const parentDir = (0, import_node_path28.resolve)(currentDir, "..");
154153
+ const parentDir = (0, import_node_path30.resolve)(currentDir, "..");
153940
154154
  if (parentDir === currentDir) {
153941
154155
  break;
153942
154156
  }
153943
154157
  currentDir = parentDir;
153944
154158
  }
153945
154159
  };
153946
- addCandidate((0, import_node_path28.resolve)(cwd, "dist/apps/api-cli/agent-loader.js"));
153947
- addCandidate((0, import_node_path28.resolve)(dirname13, "../agent-loader.js"));
153948
- addCandidate((0, import_node_path28.resolve)(dirname13, "agent-loader.js"));
154160
+ addCandidate((0, import_node_path30.resolve)(cwd, "dist/apps/api-cli/agent-loader.js"));
154161
+ addCandidate((0, import_node_path30.resolve)(dirname14, "../agent-loader.js"));
154162
+ addCandidate((0, import_node_path30.resolve)(dirname14, "agent-loader.js"));
153949
154163
  collectAncestorCandidates(cwd);
153950
- collectAncestorCandidates(dirname13);
154164
+ collectAncestorCandidates(dirname14);
153951
154165
  const resolved = candidates.find((candidate) => fileExists(candidate));
153952
154166
  if (!resolved) {
153953
154167
  throw new UserInputError(`Unable to locate Docyrus pi loader entry file. Checked: ${candidates.join(", ")}`);
@@ -153956,7 +154170,7 @@ function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
153956
154170
  }
153957
154171
  function resolveDocyrusCliEntryPath(options2 = {}) {
153958
154172
  const cwd = options2.cwd ?? process.cwd();
153959
- const dirname13 = options2.dirname ?? __dirname;
154173
+ const dirname14 = options2.dirname ?? __dirname;
153960
154174
  const argv = options2.argv ?? process.argv;
153961
154175
  const fileExists = options2.existsSyncFn ?? import_node_fs17.existsSync;
153962
154176
  const seen = /* @__PURE__ */ new Set();
@@ -153965,20 +154179,20 @@ function resolveDocyrusCliEntryPath(options2 = {}) {
153965
154179
  if (!candidate) {
153966
154180
  return;
153967
154181
  }
153968
- const resolvedCandidate = (0, import_node_path28.resolve)(candidate);
154182
+ const resolvedCandidate = (0, import_node_path30.resolve)(candidate);
153969
154183
  if (!seen.has(resolvedCandidate)) {
153970
154184
  seen.add(resolvedCandidate);
153971
154185
  candidates.push(resolvedCandidate);
153972
154186
  }
153973
154187
  };
153974
154188
  const argvScript = argv[1]?.trim();
153975
- const normalizedArgvScript = argvScript ? argvScript.startsWith("/") ? argvScript : (0, import_node_path28.resolve)(cwd, argvScript) : void 0;
154189
+ const normalizedArgvScript = argvScript ? argvScript.startsWith("/") ? argvScript : (0, import_node_path30.resolve)(cwd, argvScript) : void 0;
153976
154190
  if (normalizedArgvScript && normalizedArgvScript.endsWith(".js")) {
153977
154191
  addCandidate(normalizedArgvScript);
153978
154192
  }
153979
- addCandidate((0, import_node_path28.resolve)(cwd, "dist/apps/api-cli/main.js"));
153980
- addCandidate((0, import_node_path28.resolve)(dirname13, "../main.js"));
153981
- addCandidate((0, import_node_path28.resolve)(dirname13, "main.js"));
154193
+ addCandidate((0, import_node_path30.resolve)(cwd, "dist/apps/api-cli/main.js"));
154194
+ addCandidate((0, import_node_path30.resolve)(dirname14, "../main.js"));
154195
+ addCandidate((0, import_node_path30.resolve)(dirname14, "main.js"));
153982
154196
  if (normalizedArgvScript) {
153983
154197
  addCandidate(normalizedArgvScript);
153984
154198
  }
@@ -153990,7 +154204,7 @@ function resolveDocyrusCliEntryPath(options2 = {}) {
153990
154204
  }
153991
154205
  function resolveInstalledPiPackageRootPath(options2 = {}) {
153992
154206
  const cwd = options2.cwd ?? process.cwd();
153993
- const dirname13 = options2.dirname ?? __dirname;
154207
+ const dirname14 = options2.dirname ?? __dirname;
153994
154208
  const fileExists = options2.existsSyncFn ?? import_node_fs17.existsSync;
153995
154209
  const seen = /* @__PURE__ */ new Set();
153996
154210
  const candidates = options2.candidatePaths ?? [];
@@ -154001,32 +154215,32 @@ function resolveInstalledPiPackageRootPath(options2 = {}) {
154001
154215
  }
154002
154216
  };
154003
154217
  const collectAncestorCandidates = (startDir) => {
154004
- let currentDir = (0, import_node_path28.resolve)(startDir);
154218
+ let currentDir = (0, import_node_path30.resolve)(startDir);
154005
154219
  while (true) {
154006
- addCandidate((0, import_node_path28.join)(currentDir, "node_modules", "@mariozechner", "pi-coding-agent", "package.json"));
154007
- if ((0, import_node_path28.basename)(currentDir) === "node_modules") {
154008
- addCandidate((0, import_node_path28.join)(currentDir, "@mariozechner", "pi-coding-agent", "package.json"));
154220
+ addCandidate((0, import_node_path30.join)(currentDir, "node_modules", "@mariozechner", "pi-coding-agent", "package.json"));
154221
+ if ((0, import_node_path30.basename)(currentDir) === "node_modules") {
154222
+ addCandidate((0, import_node_path30.join)(currentDir, "@mariozechner", "pi-coding-agent", "package.json"));
154009
154223
  }
154010
- const parentDir = (0, import_node_path28.resolve)(currentDir, "..");
154224
+ const parentDir = (0, import_node_path30.resolve)(currentDir, "..");
154011
154225
  if (parentDir === currentDir) {
154012
154226
  break;
154013
154227
  }
154014
154228
  currentDir = parentDir;
154015
154229
  }
154016
154230
  };
154017
- addCandidate((0, import_node_path28.resolve)(cwd, "apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
154018
- addCandidate((0, import_node_path28.resolve)(dirname13, "../../../apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
154231
+ addCandidate((0, import_node_path30.resolve)(cwd, "apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
154232
+ addCandidate((0, import_node_path30.resolve)(dirname14, "../../../apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
154019
154233
  collectAncestorCandidates(cwd);
154020
- collectAncestorCandidates(dirname13);
154234
+ collectAncestorCandidates(dirname14);
154021
154235
  const resolvedPackageJson = candidates.find((candidate) => fileExists(candidate));
154022
154236
  if (!resolvedPackageJson) {
154023
154237
  throw new UserInputError(`Unable to locate the installed pi package root. Checked: ${candidates.join(", ")}`);
154024
154238
  }
154025
- return (0, import_node_path28.resolve)(resolvedPackageJson, "..");
154239
+ return (0, import_node_path30.resolve)(resolvedPackageJson, "..");
154026
154240
  }
154027
154241
  function createPiAgentRuntimeSkill(params) {
154028
154242
  const commandPrefix = params.scope === "global" ? "docyrus -g" : "docyrus";
154029
- const knowledgeDir = (0, import_node_path28.join)(params.cwd, "docyrus", "knowledge");
154243
+ const knowledgeDir = (0, import_node_path30.join)(params.cwd, "docyrus", "knowledge");
154030
154244
  const hasKnowledgeGraph = (0, import_node_fs17.existsSync)(knowledgeDir);
154031
154245
  const authLines = params.activeProfile ? [
154032
154246
  `- email: \`${params.activeProfile.email}\``,
@@ -154080,35 +154294,35 @@ function createPiAgentRuntimeSkill(params) {
154080
154294
  ].join("\n");
154081
154295
  }
154082
154296
  async function syncPackagedSkills(params) {
154083
- const sourceSkillsRoot = (0, import_node_path28.join)(params.resourceRoot, "skills");
154084
- const targetSkillsRoot = (0, import_node_path28.join)(params.agentRootPath, "skills");
154085
- await (0, import_promises22.mkdir)(targetSkillsRoot, {
154297
+ const sourceSkillsRoot = (0, import_node_path30.join)(params.resourceRoot, "skills");
154298
+ const targetSkillsRoot = (0, import_node_path30.join)(params.agentRootPath, "skills");
154299
+ await (0, import_promises24.mkdir)(targetSkillsRoot, {
154086
154300
  recursive: true,
154087
154301
  mode: 448
154088
154302
  });
154089
- const entries = await (0, import_promises22.readdir)(sourceSkillsRoot, {
154303
+ const entries = await (0, import_promises24.readdir)(sourceSkillsRoot, {
154090
154304
  withFileTypes: true
154091
154305
  });
154092
154306
  await Promise.all(DOCYRUS_MIGRATED_SKILL_NAMES.map(async (skillName) => {
154093
- await (0, import_promises22.rm)((0, import_node_path28.join)(targetSkillsRoot, skillName), {
154307
+ await (0, import_promises24.rm)((0, import_node_path30.join)(targetSkillsRoot, skillName), {
154094
154308
  recursive: true,
154095
154309
  force: true
154096
154310
  });
154097
154311
  }));
154098
154312
  await Promise.all(entries.map(async (entry) => {
154099
- await (0, import_promises22.cp)((0, import_node_path28.join)(sourceSkillsRoot, entry.name), (0, import_node_path28.join)(targetSkillsRoot, entry.name), {
154313
+ await (0, import_promises24.cp)((0, import_node_path30.join)(sourceSkillsRoot, entry.name), (0, import_node_path30.join)(targetSkillsRoot, entry.name), {
154100
154314
  recursive: true,
154101
154315
  force: true
154102
154316
  });
154103
154317
  }));
154104
154318
  }
154105
154319
  async function writeRuntimeSkill(params) {
154106
- const runtimeSkillDir = (0, import_node_path28.join)(params.agentRootPath, "skills", "docyrus-runtime-context");
154107
- await (0, import_promises22.mkdir)(runtimeSkillDir, {
154320
+ const runtimeSkillDir = (0, import_node_path30.join)(params.agentRootPath, "skills", "docyrus-runtime-context");
154321
+ await (0, import_promises24.mkdir)(runtimeSkillDir, {
154108
154322
  recursive: true,
154109
154323
  mode: 448
154110
154324
  });
154111
- await (0, import_promises22.writeFile)((0, import_node_path28.join)(runtimeSkillDir, "SKILL.md"), `${params.content}
154325
+ await (0, import_promises24.writeFile)((0, import_node_path30.join)(runtimeSkillDir, "SKILL.md"), `${params.content}
154112
154326
  `, {
154113
154327
  encoding: "utf8",
154114
154328
  mode: 384
@@ -154121,10 +154335,10 @@ function resolveNpmCommand() {
154121
154335
  return process.platform === "win32" ? "npm.cmd" : "npm";
154122
154336
  }
154123
154337
  function resolveManagedDiffityInstallRoot(agentRootPath) {
154124
- return (0, import_node_path28.join)(agentRootPath, "tools", "diffity");
154338
+ return (0, import_node_path30.join)(agentRootPath, "tools", "diffity");
154125
154339
  }
154126
154340
  function resolveManagedDiffityExecutablePath(agentRootPath) {
154127
- return (0, import_node_path28.join)(
154341
+ return (0, import_node_path30.join)(
154128
154342
  resolveManagedDiffityInstallRoot(agentRootPath),
154129
154343
  "node_modules",
154130
154344
  ".bin",
@@ -154132,10 +154346,10 @@ function resolveManagedDiffityExecutablePath(agentRootPath) {
154132
154346
  );
154133
154347
  }
154134
154348
  function prependPathEntry(entry, existingPath) {
154135
- const values = existingPath ? existingPath.split(import_node_path28.delimiter).filter((value2) => value2.trim().length > 0) : [];
154349
+ const values = existingPath ? existingPath.split(import_node_path30.delimiter).filter((value2) => value2.trim().length > 0) : [];
154136
154350
  const normalizedEntry = entry.trim();
154137
154351
  const remaining = values.filter((value2) => value2 !== normalizedEntry);
154138
- return [normalizedEntry, ...remaining].join(import_node_path28.delimiter);
154352
+ return [normalizedEntry, ...remaining].join(import_node_path30.delimiter);
154139
154353
  }
154140
154354
  function createDocyrusSkillsInstallArgs(scope) {
154141
154355
  const args2 = [
@@ -154173,7 +154387,7 @@ function createPackagedDocyrusPlatformInstallArgs(params) {
154173
154387
  return args2;
154174
154388
  }
154175
154389
  async function installExternalDocyrusSkillsOnce(params) {
154176
- const markerPath = (0, import_node_path28.join)(params.agentRootPath, DOCYRUS_EXTERNAL_SKILL_MARKER_FILE);
154390
+ const markerPath = (0, import_node_path30.join)(params.agentRootPath, DOCYRUS_EXTERNAL_SKILL_MARKER_FILE);
154177
154391
  if ((0, import_node_fs17.existsSync)(markerPath)) {
154178
154392
  return;
154179
154393
  }
@@ -154192,7 +154406,7 @@ async function installExternalDocyrusSkillsOnce(params) {
154192
154406
  );
154193
154407
  return;
154194
154408
  }
154195
- await (0, import_promises22.writeFile)(markerPath, `${JSON.stringify({
154409
+ await (0, import_promises24.writeFile)(markerPath, `${JSON.stringify({
154196
154410
  source: DOCYRUS_EXTERNAL_SKILL_SOURCE,
154197
154411
  skills: DOCYRUS_MIGRATED_SKILL_NAMES,
154198
154412
  agents: DOCYRUS_EXTERNAL_SKILL_AGENT_IDS,
@@ -154206,7 +154420,7 @@ async function installExternalDocyrusSkillsOnce(params) {
154206
154420
  }
154207
154421
  async function ensureManagedDiffityInstalled(params) {
154208
154422
  const executablePath = resolveManagedDiffityExecutablePath(params.agentRootPath);
154209
- const binDir = (0, import_node_path28.dirname)(executablePath);
154423
+ const binDir = (0, import_node_path30.dirname)(executablePath);
154210
154424
  if ((0, import_node_fs17.existsSync)(executablePath)) {
154211
154425
  return {
154212
154426
  available: true,
@@ -154245,19 +154459,19 @@ async function ensureManagedDiffityInstalled(params) {
154245
154459
  };
154246
154460
  }
154247
154461
  function resolvePackagedDocyrusPlatformSkillPath(resourceRoot) {
154248
- return (0, import_node_path28.join)(resourceRoot, "skills", DOCYRUS_PACKAGED_PLATFORM_SKILL_NAME);
154462
+ return (0, import_node_path30.join)(resourceRoot, "skills", DOCYRUS_PACKAGED_PLATFORM_SKILL_NAME);
154249
154463
  }
154250
154464
  function resolvePackagedOfficeCliRootPath(resourceRoot) {
154251
- return (0, import_node_path28.join)((0, import_node_path28.resolve)(resourceRoot, ".."), "officecli");
154465
+ return (0, import_node_path30.join)((0, import_node_path30.resolve)(resourceRoot, ".."), "officecli");
154252
154466
  }
154253
154467
  function resolvePackagedOfficeCliManifestPath(resourceRoot) {
154254
- return (0, import_node_path28.join)(resolvePackagedOfficeCliRootPath(resourceRoot), DOCYRUS_OFFICECLI_MANIFEST_FILE_NAME);
154468
+ return (0, import_node_path30.join)(resolvePackagedOfficeCliRootPath(resourceRoot), DOCYRUS_OFFICECLI_MANIFEST_FILE_NAME);
154255
154469
  }
154256
154470
  function resolveManagedOfficeCliInstallRoot(agentRootPath) {
154257
- return (0, import_node_path28.join)(agentRootPath, "tools", "officecli");
154471
+ return (0, import_node_path30.join)(agentRootPath, "tools", "officecli");
154258
154472
  }
154259
154473
  function resolveManagedOfficeCliExecutablePath(agentRootPath) {
154260
- return (0, import_node_path28.join)(
154474
+ return (0, import_node_path30.join)(
154261
154475
  resolveManagedOfficeCliInstallRoot(agentRootPath),
154262
154476
  process.platform === "win32" ? "officecli.exe" : "officecli"
154263
154477
  );
@@ -154299,14 +154513,14 @@ function resolveOfficeCliReleaseAssetName(options2 = {}) {
154299
154513
  throw new UserInputError(`OfficeCLI is not supported on ${platform2}/${arch}.`);
154300
154514
  }
154301
154515
  function resolvePackagedOfficeCliExecutablePath(resourceRoot, options2) {
154302
- return (0, import_node_path28.join)(
154516
+ return (0, import_node_path30.join)(
154303
154517
  resolvePackagedOfficeCliRootPath(resourceRoot),
154304
154518
  "bundled",
154305
154519
  resolveOfficeCliReleaseAssetName(options2)
154306
154520
  );
154307
154521
  }
154308
154522
  async function readPackagedOfficeCliVersion(resourceRoot) {
154309
- const manifestRaw = await (0, import_promises22.readFile)(resolvePackagedOfficeCliManifestPath(resourceRoot), "utf8");
154523
+ const manifestRaw = await (0, import_promises24.readFile)(resolvePackagedOfficeCliManifestPath(resourceRoot), "utf8");
154310
154524
  const manifest = JSON.parse(manifestRaw);
154311
154525
  const version2 = typeof manifest.version === "string" ? manifest.version.trim() : "";
154312
154526
  if (version2.length === 0) {
@@ -154322,12 +154536,12 @@ async function downloadOfficeCliBinary(params) {
154322
154536
  throw new UserInputError(`OfficeCLI download failed with status ${response.status}.`);
154323
154537
  }
154324
154538
  const binary2 = Buffer.from(await response.arrayBuffer());
154325
- await (0, import_promises22.writeFile)(params.destinationPath, binary2, {
154539
+ await (0, import_promises24.writeFile)(params.destinationPath, binary2, {
154326
154540
  mode: process.platform === "win32" ? 384 : 448
154327
154541
  });
154328
154542
  }
154329
154543
  function resolveManagedOfficeCliConfigMarkerPath(agentRootPath) {
154330
- return (0, import_node_path28.join)(resolveManagedOfficeCliInstallRoot(agentRootPath), ".docyrus-officecli-configured.json");
154544
+ return (0, import_node_path30.join)(resolveManagedOfficeCliInstallRoot(agentRootPath), ".docyrus-officecli-configured.json");
154331
154545
  }
154332
154546
  async function disableManagedOfficeCliAutoUpdate(params) {
154333
154547
  const markerPath = resolveManagedOfficeCliConfigMarkerPath(params.agentRootPath);
@@ -154350,7 +154564,7 @@ async function disableManagedOfficeCliAutoUpdate(params) {
154350
154564
  );
154351
154565
  return;
154352
154566
  }
154353
- await (0, import_promises22.writeFile)(markerPath, `${JSON.stringify({
154567
+ await (0, import_promises24.writeFile)(markerPath, `${JSON.stringify({
154354
154568
  configuredAt: (/* @__PURE__ */ new Date()).toISOString()
154355
154569
  }, null, 2)}
154356
154570
  `, {
@@ -154360,7 +154574,7 @@ async function disableManagedOfficeCliAutoUpdate(params) {
154360
154574
  }
154361
154575
  async function ensureManagedOfficeCliInstalled(params) {
154362
154576
  const executablePath = resolveManagedOfficeCliExecutablePath(params.agentRootPath);
154363
- const binDir = (0, import_node_path28.dirname)(executablePath);
154577
+ const binDir = (0, import_node_path30.dirname)(executablePath);
154364
154578
  if ((0, import_node_fs17.existsSync)(executablePath)) {
154365
154579
  await disableManagedOfficeCliAutoUpdate({
154366
154580
  agentRootPath: params.agentRootPath,
@@ -154376,13 +154590,13 @@ async function ensureManagedOfficeCliInstalled(params) {
154376
154590
  }
154377
154591
  const tempPath = `${executablePath}.download${process.platform === "win32" ? ".exe" : ""}`;
154378
154592
  try {
154379
- await (0, import_promises22.mkdir)(binDir, {
154593
+ await (0, import_promises24.mkdir)(binDir, {
154380
154594
  recursive: true,
154381
154595
  mode: 448
154382
154596
  });
154383
154597
  const bundledExecutablePath = resolvePackagedOfficeCliExecutablePath(params.resourceRoot);
154384
154598
  if ((0, import_node_fs17.existsSync)(bundledExecutablePath)) {
154385
- await (0, import_promises22.cp)(bundledExecutablePath, tempPath, {
154599
+ await (0, import_promises24.cp)(bundledExecutablePath, tempPath, {
154386
154600
  force: true
154387
154601
  });
154388
154602
  } else {
@@ -154392,7 +154606,7 @@ async function ensureManagedOfficeCliInstalled(params) {
154392
154606
  });
154393
154607
  }
154394
154608
  if (process.platform !== "win32") {
154395
- await (0, import_promises22.chmod)(tempPath, 448);
154609
+ await (0, import_promises24.chmod)(tempPath, 448);
154396
154610
  }
154397
154611
  const verificationResult = params.spawnCommand(tempPath, ["--version"], {
154398
154612
  stdio: ["ignore", "pipe", "pipe"],
@@ -154408,9 +154622,9 @@ async function ensureManagedOfficeCliInstalled(params) {
154408
154622
  verificationResult.error?.message || summarizeFailure3(verificationResult, "officecli --version")
154409
154623
  );
154410
154624
  }
154411
- await (0, import_promises22.rename)(tempPath, executablePath);
154625
+ await (0, import_promises24.rename)(tempPath, executablePath);
154412
154626
  if (process.platform !== "win32") {
154413
- await (0, import_promises22.chmod)(executablePath, 448);
154627
+ await (0, import_promises24.chmod)(executablePath, 448);
154414
154628
  }
154415
154629
  await disableManagedOfficeCliAutoUpdate({
154416
154630
  agentRootPath: params.agentRootPath,
@@ -154424,7 +154638,7 @@ async function ensureManagedOfficeCliInstalled(params) {
154424
154638
  binDir
154425
154639
  };
154426
154640
  } catch (error48) {
154427
- await (0, import_promises22.rm)(tempPath, {
154641
+ await (0, import_promises24.rm)(tempPath, {
154428
154642
  force: true
154429
154643
  });
154430
154644
  process.stderr.write(
@@ -154483,6 +154697,7 @@ function createPiAgentLauncher(options2) {
154483
154697
  const resolveLoaderPath = options2.resolveDocyrusPiLoaderEntryPathFn ?? resolveDocyrusPiLoaderEntryPath;
154484
154698
  const resolveCliEntryPath = options2.resolveDocyrusCliEntryPathFn ?? resolveDocyrusCliEntryPath;
154485
154699
  const resolvePiPackageRoot = options2.resolveInstalledPiPackageRootPathFn ?? resolveInstalledPiPackageRootPath;
154700
+ const resolveAgentRootPath = options2.resolveAgentRootPathFn ?? getDocyrusPiAgentGlobalRootPath;
154486
154701
  return async (request) => {
154487
154702
  validatePiAgentLaunchRequest({
154488
154703
  request,
@@ -154492,7 +154707,12 @@ function createPiAgentLauncher(options2) {
154492
154707
  const activeEnvironment = await options2.environmentConfigService.getActiveEnvironment();
154493
154708
  const activeProfile = await options2.authStore.getActiveProfile(activeEnvironment.apiBaseUrl);
154494
154709
  const settingsRootPath = options2.settingsPaths.rootPath;
154495
- const agentRootPath = resolveDocyrusPiAgentRootPath(settingsRootPath);
154710
+ const agentRootPath = resolveAgentRootPath();
154711
+ await migrateLegacyPiAgentDir({
154712
+ legacyRootPath: resolveDocyrusPiAgentRootPath(settingsRootPath),
154713
+ globalRootPath: agentRootPath
154714
+ }).catch(() => {
154715
+ });
154496
154716
  const resourceRoot = resolveResourceRoot({ cwd });
154497
154717
  spinner.update("Syncing skills...");
154498
154718
  await syncPackagedSkills({
@@ -154543,6 +154763,13 @@ function createPiAgentLauncher(options2) {
154543
154763
  cwd,
154544
154764
  spawnCommand
154545
154765
  });
154766
+ const soulId = request.soul?.trim() || await options2.environmentConfigService.getActiveSoulId();
154767
+ const systemPromptPath = await composeSystemPrompt({
154768
+ profile: request.profile,
154769
+ soulId,
154770
+ resourceRoot,
154771
+ agentRootPath
154772
+ });
154546
154773
  spinner.stop();
154547
154774
  const loaderEntryPath = resolveLoaderPath({ cwd });
154548
154775
  const cliEntryPath = resolveCliEntryPath({ cwd });
@@ -154556,8 +154783,13 @@ function createPiAgentLauncher(options2) {
154556
154783
  ...process.env,
154557
154784
  PI_CODING_AGENT_DIR: agentRootPath,
154558
154785
  PI_PACKAGE_DIR: piPackageRoot,
154786
+ // Disable pi-mono's install-telemetry ping (added in pi-mono v0.67.0).
154787
+ // Only users explicitly opting in via DOCYRUS_PI_ENABLE_TELEMETRY=1 will let it fire.
154788
+ PI_TELEMETRY: process.env.DOCYRUS_PI_ENABLE_TELEMETRY === "1" ? process.env.PI_TELEMETRY ?? "" : "0",
154559
154789
  DOCYRUS_PI_REQUEST: JSON.stringify(request),
154560
154790
  DOCYRUS_PI_VERSION: options2.version || "dev",
154791
+ DOCYRUS_PI_SYSTEM_PROMPT_PATH: systemPromptPath,
154792
+ DOCYRUS_PI_SOUL_ID: soulId,
154561
154793
  DOCYRUS_CLI_EXECUTABLE: processExecPath,
154562
154794
  DOCYRUS_CLI_ENTRY: cliEntryPath,
154563
154795
  DOCYRUS_CLI_SCOPE: options2.settingsPaths.scope,
@@ -154579,11 +154811,11 @@ function createPiAgentLauncher(options2) {
154579
154811
  // src/services/piAgentServerLauncher.ts
154580
154812
  var import_node_child_process9 = require("node:child_process");
154581
154813
  var import_node_fs18 = require("node:fs");
154582
- var import_node_path29 = require("node:path");
154814
+ var import_node_path31 = require("node:path");
154583
154815
  function serializePiAgentServerRequest(request) {
154584
154816
  return JSON.stringify(request);
154585
154817
  }
154586
- function resolveServerLoaderEntryPath(cwd, dirname13) {
154818
+ function resolveServerLoaderEntryPath(cwd, dirname14) {
154587
154819
  const seen = /* @__PURE__ */ new Set();
154588
154820
  const candidates = [];
154589
154821
  const addCandidate = (candidate) => {
@@ -154593,25 +154825,25 @@ function resolveServerLoaderEntryPath(cwd, dirname13) {
154593
154825
  }
154594
154826
  };
154595
154827
  const collectAncestorCandidates = (startDir) => {
154596
- let currentDir = (0, import_node_path29.resolve)(startDir);
154828
+ let currentDir = (0, import_node_path31.resolve)(startDir);
154597
154829
  while (true) {
154598
- addCandidate((0, import_node_path29.join)(currentDir, "dist", "apps", "api-cli", "server-loader.js"));
154599
- addCandidate((0, import_node_path29.join)(currentDir, "server-loader.js"));
154600
- if ((0, import_node_path29.basename)(currentDir) === "dist") {
154601
- addCandidate((0, import_node_path29.join)(currentDir, "apps", "api-cli", "server-loader.js"));
154830
+ addCandidate((0, import_node_path31.join)(currentDir, "dist", "apps", "api-cli", "server-loader.js"));
154831
+ addCandidate((0, import_node_path31.join)(currentDir, "server-loader.js"));
154832
+ if ((0, import_node_path31.basename)(currentDir) === "dist") {
154833
+ addCandidate((0, import_node_path31.join)(currentDir, "apps", "api-cli", "server-loader.js"));
154602
154834
  }
154603
- const parentDir = (0, import_node_path29.resolve)(currentDir, "..");
154835
+ const parentDir = (0, import_node_path31.resolve)(currentDir, "..");
154604
154836
  if (parentDir === currentDir) {
154605
154837
  break;
154606
154838
  }
154607
154839
  currentDir = parentDir;
154608
154840
  }
154609
154841
  };
154610
- addCandidate((0, import_node_path29.resolve)(cwd, "dist/apps/api-cli/server-loader.js"));
154611
- addCandidate((0, import_node_path29.resolve)(dirname13, "../server-loader.js"));
154612
- addCandidate((0, import_node_path29.resolve)(dirname13, "server-loader.js"));
154842
+ addCandidate((0, import_node_path31.resolve)(cwd, "dist/apps/api-cli/server-loader.js"));
154843
+ addCandidate((0, import_node_path31.resolve)(dirname14, "../server-loader.js"));
154844
+ addCandidate((0, import_node_path31.resolve)(dirname14, "server-loader.js"));
154613
154845
  collectAncestorCandidates(cwd);
154614
- collectAncestorCandidates(dirname13);
154846
+ collectAncestorCandidates(dirname14);
154615
154847
  const resolved = candidates.find((candidate) => (0, import_node_fs18.existsSync)(candidate));
154616
154848
  if (!resolved) {
154617
154849
  throw new UserInputError(`Unable to locate Docyrus pi server loader entry file. Checked: ${candidates.join(", ")}`);
@@ -154620,12 +154852,18 @@ function resolveServerLoaderEntryPath(cwd, dirname13) {
154620
154852
  }
154621
154853
  function createPiAgentServerLauncher(options2) {
154622
154854
  const cwd = options2.cwd ?? process.cwd();
154855
+ const resolveAgentRootPath = options2.resolveAgentRootPathFn ?? getDocyrusPiAgentGlobalRootPath;
154623
154856
  return async (request) => {
154624
154857
  const spinner = createSpinner("Initializing...");
154625
154858
  const activeEnvironment = await options2.environmentConfigService.getActiveEnvironment();
154626
154859
  const activeProfile = await options2.authStore.getActiveProfile(activeEnvironment.apiBaseUrl);
154627
154860
  const settingsRootPath = options2.settingsPaths.rootPath;
154628
- const agentRootPath = resolveDocyrusPiAgentRootPath(settingsRootPath);
154861
+ const agentRootPath = resolveAgentRootPath();
154862
+ await migrateLegacyPiAgentDir({
154863
+ legacyRootPath: resolveDocyrusPiAgentRootPath(settingsRootPath),
154864
+ globalRootPath: agentRootPath
154865
+ }).catch(() => {
154866
+ });
154629
154867
  const resourceRoot = resolvePackagedPiResourceRoot({ cwd });
154630
154868
  spinner.update("Syncing skills...");
154631
154869
  await syncPackagedSkills({
@@ -154665,13 +154903,20 @@ function createPiAgentServerLauncher(options2) {
154665
154903
  if (request.sandbox) {
154666
154904
  const browserConfigDir = settingsRootPath;
154667
154905
  (0, import_node_fs18.mkdirSync)(browserConfigDir, { recursive: true, mode: 448 });
154668
- const browserConfigPath = (0, import_node_path29.join)(browserConfigDir, "browser.json");
154906
+ const browserConfigPath = (0, import_node_path31.join)(browserConfigDir, "browser.json");
154669
154907
  const appId = process.env.DOCYRUS_SANDBOX_APP_ID || "";
154670
154908
  (0, import_node_fs18.writeFileSync)(browserConfigPath, JSON.stringify({ mode: "sandbox", appId }, null, 2) + "\n", {
154671
154909
  encoding: "utf8",
154672
154910
  mode: 384
154673
154911
  });
154674
154912
  }
154913
+ const soulId = request.soul?.trim() || await options2.environmentConfigService.getActiveSoulId();
154914
+ const systemPromptPath = await composeSystemPrompt({
154915
+ profile: request.profile,
154916
+ soulId,
154917
+ resourceRoot,
154918
+ agentRootPath
154919
+ });
154675
154920
  spinner.stop();
154676
154921
  const loaderEntryPath = resolveServerLoaderEntryPath(cwd, __dirname);
154677
154922
  const piPackageRoot = resolveInstalledPiPackageRootPath({ cwd });
@@ -154685,8 +154930,13 @@ function createPiAgentServerLauncher(options2) {
154685
154930
  PATH: runtimePath,
154686
154931
  PI_CODING_AGENT_DIR: agentRootPath,
154687
154932
  PI_PACKAGE_DIR: piPackageRoot,
154933
+ // Disable pi-mono's install-telemetry ping (added in pi-mono v0.67.0).
154934
+ // Only users explicitly opting in via DOCYRUS_PI_ENABLE_TELEMETRY=1 will let it fire.
154935
+ PI_TELEMETRY: process.env.DOCYRUS_PI_ENABLE_TELEMETRY === "1" ? process.env.PI_TELEMETRY ?? "" : "0",
154688
154936
  DOCYRUS_PI_REQUEST: serializePiAgentServerRequest(request),
154689
154937
  DOCYRUS_PI_VERSION: options2.version || "dev",
154938
+ DOCYRUS_PI_SYSTEM_PROMPT_PATH: systemPromptPath,
154939
+ DOCYRUS_PI_SOUL_ID: soulId,
154690
154940
  DOCYRUS_CLI_EXECUTABLE: process.execPath,
154691
154941
  DOCYRUS_CLI_ENTRY: cliEntryPath,
154692
154942
  DOCYRUS_CLI_SCOPE: options2.settingsPaths.scope,
@@ -154741,8 +154991,8 @@ async function runWithIncurSkillsOutOfDateWarningSuppressed(params) {
154741
154991
  }
154742
154992
 
154743
154993
  // src/services/tenantOpenApi.ts
154744
- var import_promises23 = require("node:fs/promises");
154745
- var import_node_path30 = require("node:path");
154994
+ var import_promises25 = require("node:fs/promises");
154995
+ var import_node_path32 = require("node:path");
154746
154996
  function resolveSourceUrl(tenantId, template) {
154747
154997
  return template.replace("{tenantId}", encodeURIComponent(tenantId));
154748
154998
  }
@@ -154767,16 +155017,16 @@ var TenantOpenApiService = class {
154767
155017
  params;
154768
155018
  async #writeOpenApiFile(tenantId, parsedContent) {
154769
155019
  const filePath = this.getTenantOpenApiFilePath(tenantId);
154770
- await (0, import_promises23.mkdir)((0, import_node_path30.dirname)(filePath), {
155020
+ await (0, import_promises25.mkdir)((0, import_node_path32.dirname)(filePath), {
154771
155021
  recursive: true,
154772
155022
  mode: 448
154773
155023
  });
154774
- await (0, import_promises23.writeFile)(filePath, `${JSON.stringify(parsedContent, null, 2)}
155024
+ await (0, import_promises25.writeFile)(filePath, `${JSON.stringify(parsedContent, null, 2)}
154775
155025
  `, {
154776
155026
  encoding: "utf8",
154777
155027
  mode: 384
154778
155028
  });
154779
- await (0, import_promises23.chmod)(filePath, 384);
155029
+ await (0, import_promises25.chmod)(filePath, 384);
154780
155030
  return filePath;
154781
155031
  }
154782
155032
  async #generateTenantOpenApiViaAuthenticatedEndpoint(tenantId, options2) {
@@ -154813,7 +155063,7 @@ var TenantOpenApiService = class {
154813
155063
  throw new AuthSessionError("Tenant ID is required to resolve OpenAPI spec path.");
154814
155064
  }
154815
155065
  const rootPath = this.params?.rootPath || TENANT_OPENAPI_ROOT_PATH;
154816
- return (0, import_node_path30.join)(rootPath, normalizedTenantId, "openapi.json");
155066
+ return (0, import_node_path32.join)(rootPath, normalizedTenantId, "openapi.json");
154817
155067
  }
154818
155068
  async downloadTenantOpenApi(tenantId, options2 = {}) {
154819
155069
  const normalizedTenantId = tenantId.trim();