poe-code 3.0.236 → 3.0.237

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
@@ -47493,6 +47493,7 @@ var init_src23 = __esm({
47493
47493
  });
47494
47494
 
47495
47495
  // packages/agent-code-review/src/config-scope.ts
47496
+ import { isAbsolute as isAbsolute3 } from "node:path";
47496
47497
  function parseHumanGate(value) {
47497
47498
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
47498
47499
  throw new Error("humanGate must be an object");
@@ -47509,13 +47510,23 @@ function parseHumanGate(value) {
47509
47510
  }
47510
47511
  return { provider: provider2 };
47511
47512
  }
47513
+ function parseCodeReviewProfileDirectories(value) {
47514
+ if (!Array.isArray(value) || value.some((directory) => typeof directory !== "string")) {
47515
+ throw new Error("codeReview.profileDirectories must be an array of strings");
47516
+ }
47517
+ const directories = value.map((directory) => directory.trim());
47518
+ if (directories.some((directory) => !directory || !isAbsolute3(directory))) {
47519
+ throw new Error("codeReview.profileDirectories entries must be absolute paths");
47520
+ }
47521
+ return [...new Set(directories)];
47522
+ }
47512
47523
  function parseCodeReviewConfigDocument(value) {
47513
47524
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
47514
47525
  throw new Error("codeReview must be an object");
47515
47526
  }
47516
47527
  const config = value;
47517
47528
  for (const key2 of Object.keys(config)) {
47518
- if (!["agent", "draftStore", "humanGate"].includes(key2)) {
47529
+ if (!["agent", "draftStore", "humanGate", "profileDirectories"].includes(key2)) {
47519
47530
  throw new Error(`codeReview.${key2} is not supported`);
47520
47531
  }
47521
47532
  }
@@ -47528,7 +47539,8 @@ function parseCodeReviewConfigDocument(value) {
47528
47539
  return {
47529
47540
  ...config.agent === void 0 ? {} : { agent: config.agent },
47530
47541
  ...config.draftStore === void 0 ? {} : { draftStore: config.draftStore },
47531
- ...config.humanGate === void 0 ? {} : { humanGate: parseHumanGate(config.humanGate) }
47542
+ ...config.humanGate === void 0 ? {} : { humanGate: parseHumanGate(config.humanGate) },
47543
+ ...config.profileDirectories === void 0 ? {} : { profileDirectories: parseCodeReviewProfileDirectories(config.profileDirectories) }
47532
47544
  };
47533
47545
  }
47534
47546
  var codeReviewConfigScope;
@@ -47552,6 +47564,12 @@ var init_config_scope2 = __esm({
47552
47564
  default: { provider: "none" },
47553
47565
  parse: parseHumanGate,
47554
47566
  doc: "External human-gate configuration for code review runs."
47567
+ },
47568
+ profileDirectories: {
47569
+ type: "json",
47570
+ default: [],
47571
+ parse: parseCodeReviewProfileDirectories,
47572
+ doc: "Absolute external reviewer profile directories, in precedence order after repo-local profiles."
47555
47573
  }
47556
47574
  });
47557
47575
  }
@@ -49331,14 +49349,14 @@ import {
49331
49349
  stat as stat6,
49332
49350
  unlink as unlink4
49333
49351
  } from "node:fs/promises";
49334
- import { basename as basename3, dirname, isAbsolute as isAbsolute3, parse as parse6, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
49352
+ import { basename as basename3, dirname, isAbsolute as isAbsolute4, parse as parse6, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
49335
49353
  function codeReviewFileName(prUrl) {
49336
49354
  const ref = requirePullRequestRef2(prUrl);
49337
49355
  return `${safeFilePart(ref.owner)}_${safeFilePart(ref.repo)}_PR${ref.number}.yaml`;
49338
49356
  }
49339
49357
  function resolveCodeReviewStoreDirectory(cwd, directory = DEFAULT_CODE_REVIEW_REVIEWS_DIRECTORY) {
49340
49358
  const root = resolve2(cwd, CODE_REVIEW_DIRECTORY);
49341
- const target = isAbsolute3(directory) ? resolve2(directory) : resolve2(cwd, directory);
49359
+ const target = isAbsolute4(directory) ? resolve2(directory) : resolve2(cwd, directory);
49342
49360
  const fromRoot = relative2(root, target);
49343
49361
  if (fromRoot.startsWith("..") || fromRoot.startsWith(sep2)) {
49344
49362
  throw new Error(`Code review draft store must stay under ${root}: ${target}`);
@@ -49504,7 +49522,7 @@ async function assertDirectoryPath(directory) {
49504
49522
  }
49505
49523
  }
49506
49524
  function containedPath(directory, name) {
49507
- if (!name || isAbsolute3(name)) {
49525
+ if (!name || isAbsolute4(name)) {
49508
49526
  throw new Error(`Code review path name is unsafe: ${name}`);
49509
49527
  }
49510
49528
  const root = resolve2(directory);
@@ -49932,7 +49950,8 @@ async function loadCodeReviewConfig(options) {
49932
49950
  return {
49933
49951
  ...agent3 ? { agent: agent3 } : {},
49934
49952
  draftStore,
49935
- humanGate: config.humanGate
49953
+ humanGate: config.humanGate,
49954
+ profileDirectories: config.profileDirectories
49936
49955
  };
49937
49956
  }
49938
49957
  async function validatePersistedCodeReviewConfig(options) {
@@ -49977,6 +49996,9 @@ async function resolveCodeReviewRunOptions(input, configOptions) {
49977
49996
  ...agent3 ? { agent: agent3 } : {},
49978
49997
  draftStore,
49979
49998
  humanGate: input.humanGate ?? config.humanGate,
49999
+ profileDirectories: parseCodeReviewProfileDirectories(
50000
+ input.profileDirectories ?? config.profileDirectories
50001
+ ),
49980
50002
  ...input.profilePath === void 0 ? {} : { profilePath: input.profilePath },
49981
50003
  ...input.promptPath === void 0 ? {} : { promptPath: input.promptPath },
49982
50004
  ...input.profiles === void 0 ? {} : { profiles: input.profiles },
@@ -49984,12 +50006,18 @@ async function resolveCodeReviewRunOptions(input, configOptions) {
49984
50006
  };
49985
50007
  }
49986
50008
  async function resolveCodeReviewRuntimeOptions(input) {
49987
- return resolveCodeReviewRunOptions(input, {
50009
+ return resolveCodeReviewRunOptions(input, runtimeConfigOptions(input.cwd));
50010
+ }
50011
+ async function loadCodeReviewRuntimeConfig(cwd) {
50012
+ return loadCodeReviewConfig(runtimeConfigOptions(cwd));
50013
+ }
50014
+ function runtimeConfigOptions(cwd) {
50015
+ return {
49988
50016
  fs: nativeConfigFs,
49989
50017
  filePath: resolveConfigPath(homedir4()),
49990
- projectFilePath: resolveProjectConfigPath(input.cwd),
50018
+ projectFilePath: resolveProjectConfigPath(cwd),
49991
50019
  env: process.env
49992
- });
50020
+ };
49993
50021
  }
49994
50022
  async function loadDefaultPoeCodeAgent(input) {
49995
50023
  const agent3 = await createConfigStore({
@@ -50089,8 +50117,40 @@ async function loadCodeReviewPrompt(filePath, reader) {
50089
50117
  return requireMarkdownBody(parsed.content, filePath);
50090
50118
  }
50091
50119
  async function discoverCodeReviewProfiles(input) {
50092
- const profilesDirectory = join2(codeReviewAssetsDirectory(input.cwd), "profiles");
50093
- await assertContainedAssetDirectoryOrMissing(resolve3(input.cwd), profilesDirectory);
50120
+ const cwd = resolve3(input.cwd);
50121
+ const directories = [
50122
+ { path: join2(codeReviewAssetsDirectory(cwd), "profiles"), source: "repo", root: cwd },
50123
+ ...parseCodeReviewProfileDirectories(input.profileDirectories ?? []).map((directory) => ({
50124
+ path: resolve3(directory),
50125
+ source: "external",
50126
+ root: resolve3(directory)
50127
+ }))
50128
+ ];
50129
+ const profiles = /* @__PURE__ */ new Map();
50130
+ const normalizedNames = /* @__PURE__ */ new Map();
50131
+ for (const directory of directories) {
50132
+ for (const profile of await discoverProfilesInDirectory(directory)) {
50133
+ const normalized = profile.name.normalize("NFKC").toLowerCase();
50134
+ const existingName = normalizedNames.get(normalized);
50135
+ if (existingName && existingName !== profile.name) {
50136
+ throw new Error(`Code review profile filenames normalize to the same name: ${profile.name}`);
50137
+ }
50138
+ normalizedNames.set(normalized, profile.name);
50139
+ if (!profiles.has(profile.name)) profiles.set(profile.name, profile);
50140
+ }
50141
+ }
50142
+ const availableNames = [...profiles.keys()];
50143
+ if (availableNames.length === 0) {
50144
+ validateProfileFilters(input.filters, ["generic"]);
50145
+ return [{ name: "generic", content: BUILT_IN_GENERIC_PROFILE, source: "built-in" }];
50146
+ }
50147
+ validateProfileFilters(input.filters, availableNames);
50148
+ const filterSet = input.filters?.length ? new Set(input.filters) : void 0;
50149
+ return [...profiles.values()].filter((profile) => !filterSet || filterSet.has(profile.name));
50150
+ }
50151
+ async function discoverProfilesInDirectory(input) {
50152
+ const profilesDirectory = input.path;
50153
+ await assertContainedAssetDirectoryOrMissing(input.root, profilesDirectory);
50094
50154
  let profileFileNames;
50095
50155
  try {
50096
50156
  const profileEntries = await readdir10(profilesDirectory, {
@@ -50108,40 +50168,18 @@ async function discoverCodeReviewProfiles(input) {
50108
50168
  }
50109
50169
  profileFileNames = [];
50110
50170
  }
50111
- const availableNames = profileFileNames.map(
50112
- (fileName) => requireSafeDocumentSegment(
50113
- profileNameFromFile(fileName),
50114
- `${join2(profilesDirectory, fileName)}: filename`
50115
- )
50116
- );
50117
- const normalizedNames = /* @__PURE__ */ new Set();
50118
- for (const name of availableNames) {
50119
- const normalized = name.normalize("NFKC").toLowerCase();
50120
- if (normalizedNames.has(normalized)) {
50121
- throw new Error(`Code review profile filenames normalize to the same name: ${name}`);
50122
- }
50123
- normalizedNames.add(normalized);
50124
- }
50125
- if (availableNames.length === 0) {
50126
- validateProfileFilters(input.filters, ["generic"]);
50127
- return [
50128
- {
50129
- name: "generic",
50130
- content: BUILT_IN_GENERIC_PROFILE,
50131
- source: "built-in"
50132
- }
50133
- ];
50134
- }
50135
- validateProfileFilters(input.filters, availableNames);
50136
- const filterSet = input.filters?.length ? new Set(input.filters) : void 0;
50137
50171
  return Promise.all(
50138
- profileFileNames.filter((fileName) => !filterSet || filterSet.has(profileNameFromFile(fileName))).map(async (fileName) => {
50172
+ profileFileNames.map(async (fileName) => {
50173
+ const name = requireSafeDocumentSegment(
50174
+ profileNameFromFile(fileName),
50175
+ `${join2(profilesDirectory, fileName)}: filename`
50176
+ );
50139
50177
  const filePath = join2(profilesDirectory, fileName);
50140
50178
  return {
50141
- name: profileNameFromFile(fileName),
50179
+ name,
50142
50180
  content: await loadCodeReviewProfile(filePath),
50143
50181
  filePath,
50144
- source: "repo"
50182
+ source: input.source
50145
50183
  };
50146
50184
  })
50147
50185
  );
@@ -50216,6 +50254,16 @@ async function ensureContainedDirectory(cwd, targetDirectory) {
50216
50254
  }
50217
50255
  }
50218
50256
  async function assertContainedAssetDirectoryOrMissing(cwd, targetDirectory) {
50257
+ let rootStatus;
50258
+ try {
50259
+ rootStatus = await lstat8(cwd);
50260
+ } catch (error3) {
50261
+ if (isMissingFileError4(error3)) return;
50262
+ throw error3;
50263
+ }
50264
+ if (!rootStatus.isDirectory()) {
50265
+ throw new Error(`Code review asset directory is not a regular directory: ${cwd}`);
50266
+ }
50219
50267
  const pathFromCwd = relative3(cwd, targetDirectory);
50220
50268
  if (pathFromCwd.startsWith("..") || pathFromCwd.startsWith(sep3)) {
50221
50269
  throw new Error(`Code review asset directory escapes repository: ${targetDirectory}`);
@@ -50365,6 +50413,7 @@ var init_assets = __esm({
50365
50413
  "packages/agent-code-review/src/assets.ts"() {
50366
50414
  "use strict";
50367
50415
  init_document_schemas();
50416
+ init_config_scope2();
50368
50417
  CODE_REVIEW_USER_FACING_OUTPUT_CONTRACT = "In user-facing review/profile output, do not mention dry-run, fake-submit, orchestration, subagents, internal tool flow, source GitHub usernames, source URLs, or generation details.";
50369
50418
  BUILT_IN_GENERIC_PROFILE = `# Generic review profile
50370
50419
 
@@ -55167,7 +55216,8 @@ function parseCodeReviewAgentMcpArgs(argv) {
55167
55216
  "--cwd",
55168
55217
  "--draft-store",
55169
55218
  "--agent",
55170
- "--profiles"
55219
+ "--profiles",
55220
+ "--profile-directories"
55171
55221
  ]);
55172
55222
  for (let index = 0; index < argv.length; index += 2) {
55173
55223
  const flag = argv[index];
@@ -55188,6 +55238,7 @@ function parseCodeReviewAgentMcpArgs(argv) {
55188
55238
  throw new Error(`Invalid code-review MCP role: ${role}`);
55189
55239
  }
55190
55240
  const profiles = values.get("--profiles")?.split(",");
55241
+ const profileDirectories = values.has("--profile-directories") ? parseCodeReviewProfileDirectories(JSON.parse(requiredValue(values, "--profile-directories"))) : void 0;
55191
55242
  if (values.has("--profiles") && profiles?.length === 0) {
55192
55243
  throw new Error("--profiles requires at least one profile");
55193
55244
  }
@@ -55198,6 +55249,7 @@ function parseCodeReviewAgentMcpArgs(argv) {
55198
55249
  cwd: requiredValue(values, "--cwd"),
55199
55250
  ...values.has("--draft-store") ? { draftStore: requiredValue(values, "--draft-store") } : {},
55200
55251
  agent: requiredValue(values, "--agent"),
55252
+ ...profileDirectories ? { profileDirectories } : {},
55201
55253
  ...profiles && profiles.length > 0 ? {
55202
55254
  profiles: [
55203
55255
  ...new Set(profiles.map((profile) => requireSafeDocumentSegment(profile, "--profiles")))
@@ -55223,6 +55275,9 @@ function createCodeReviewAgentMcpConfig(context) {
55223
55275
  if (context.profiles?.length) {
55224
55276
  args.push("--profiles", context.profiles.join(","));
55225
55277
  }
55278
+ if (context.profileDirectories?.length) {
55279
+ args.push("--profile-directories", JSON.stringify(context.profileDirectories));
55280
+ }
55226
55281
  return { transport: "stdio", command: "poe-code", args: ["code-review", ...args] };
55227
55282
  }
55228
55283
  function createCodeReviewAgentMcpGroup(context, dependencies = {}) {
@@ -55315,7 +55370,8 @@ function createCodeReviewAgentMcpGroup(context, dependencies = {}) {
55315
55370
  params: S.Object({}),
55316
55371
  handler: async () => discoverCodeReviewProfiles({
55317
55372
  cwd: context.cwd,
55318
- filters: context.profiles
55373
+ filters: context.profiles,
55374
+ profileDirectories: context.profileDirectories
55319
55375
  })
55320
55376
  });
55321
55377
  const agentSpawnCommand = defineCommand({
@@ -55331,7 +55387,8 @@ function createCodeReviewAgentMcpGroup(context, dependencies = {}) {
55331
55387
  const pr = canonicalPullRequestUrl(params.pr);
55332
55388
  const profiles = await discoverCodeReviewProfiles({
55333
55389
  cwd: context.cwd,
55334
- filters: context.profiles
55390
+ filters: context.profiles,
55391
+ profileDirectories: context.profileDirectories
55335
55392
  });
55336
55393
  const profile = profiles.find((candidate) => candidate.name === params.profile);
55337
55394
  if (!profile) {
@@ -55642,6 +55699,7 @@ var init_mcp3 = __esm({
55642
55699
  init_document_schemas();
55643
55700
  init_prompt_transport2();
55644
55701
  init_review_store();
55702
+ init_config_scope2();
55645
55703
  CODE_REVIEW_AGENT_MCP_ROLES = ["agent", "orchestrator", "subagent"];
55646
55704
  inlineCommentSchema = S.Object({
55647
55705
  path: S.String({ description: "Repository-relative path in the PR diff." }),
@@ -55675,7 +55733,8 @@ async function runCodeReview(input, dependencies = {}) {
55675
55733
  }
55676
55734
  const profiles = await discoverCodeReviewProfiles({
55677
55735
  cwd: options.cwd,
55678
- filters: options.profiles
55736
+ filters: options.profiles,
55737
+ profileDirectories: options.profileDirectories
55679
55738
  });
55680
55739
  const [profile, promptTemplate, prDetails, diff2, priorActivity] = await Promise.all([
55681
55740
  resolveProfile(input, options, profiles),
@@ -55714,6 +55773,7 @@ async function runCodeReview(input, dependencies = {}) {
55714
55773
  cwd: options.cwd,
55715
55774
  draftStore,
55716
55775
  agent: agent3,
55776
+ profileDirectories: options.profileDirectories,
55717
55777
  ...options.profiles ? { profiles: options.profiles } : {}
55718
55778
  });
55719
55779
  const spawnResult = await (dependencies.spawnAgent ?? spawnWithPoeCode3)(agent3, prompt, {
@@ -55918,6 +55978,7 @@ var init_cli = __esm({
55918
55978
  init_mcp3();
55919
55979
  init_review2();
55920
55980
  init_review_store();
55981
+ init_config4();
55921
55982
  agentMcpCommand = defineCommand({
55922
55983
  name: "agent-mcp",
55923
55984
  description: "Run the stdio MCP server used by code review agents.",
@@ -55930,7 +55991,8 @@ var init_cli = __esm({
55930
55991
  cwd: S.String({ description: "Repository working directory." }),
55931
55992
  draftStore: S.Optional(S.String({ description: "Absolute YAML review state directory." })),
55932
55993
  agent: S.String({ description: "Poe Code agent used for subagents." }),
55933
- profiles: S.Optional(S.String({ description: "Comma-separated allowed profile names." }))
55994
+ profiles: S.Optional(S.String({ description: "Comma-separated allowed profile names." })),
55995
+ profileDirectories: S.Optional(S.String({ description: "JSON array of external profile directories." }))
55934
55996
  }),
55935
55997
  scope: ["cli"],
55936
55998
  handler: async ({ params }) => runCodeReviewAgentMcp(
@@ -55946,7 +56008,8 @@ var init_cli = __esm({
55946
56008
  ...params.draftStore ? ["--draft-store", params.draftStore] : [],
55947
56009
  "--agent",
55948
56010
  params.agent,
55949
- ...params.profiles ? ["--profiles", params.profiles] : []
56011
+ ...params.profiles ? ["--profiles", params.profiles] : [],
56012
+ ...params.profileDirectories ? ["--profile-directories", params.profileDirectories] : []
55950
56013
  ])
55951
56014
  )
55952
56015
  });
@@ -55969,18 +56032,22 @@ var init_cli = __esm({
55969
56032
  });
55970
56033
  listCodeReviewProfilesCommand = defineCommand({
55971
56034
  name: "profiles",
55972
- description: "List repo-local code review profiles.",
56035
+ description: "List configured code review profiles.",
55973
56036
  params: S.Object({
55974
56037
  cwd: S.Optional(S.String({ description: "Repository root directory." }))
55975
56038
  }),
55976
56039
  scope: ["cli"],
55977
- handler: async ({ params }) => (await discoverCodeReviewProfiles({ cwd: params.cwd?.trim() || process.cwd() })).map(
55978
- ({ name, source, filePath }) => ({
55979
- name,
55980
- source,
55981
- ...filePath ? { filePath } : {}
55982
- })
55983
- )
56040
+ handler: async ({ params }) => {
56041
+ const cwd = params.cwd?.trim() || process.cwd();
56042
+ const config = await loadCodeReviewRuntimeConfig(cwd);
56043
+ return (await discoverCodeReviewProfiles({ cwd, profileDirectories: config.profileDirectories })).map(
56044
+ ({ name, source, filePath }) => ({
56045
+ name,
56046
+ source,
56047
+ ...filePath ? { filePath } : {}
56048
+ })
56049
+ );
56050
+ }
55984
56051
  });
55985
56052
  readCodeReviewDraftCommand = defineCommand({
55986
56053
  name: "drafts",
@@ -72063,9 +72130,9 @@ var init_registry5 = __esm({
72063
72130
 
72064
72131
  // packages/agent-eval/src/source/open.ts
72065
72132
  import nodeFs13 from "node:fs/promises";
72066
- import { isAbsolute as isAbsolute4 } from "node:path";
72133
+ import { isAbsolute as isAbsolute5 } from "node:path";
72067
72134
  async function openSource(dir, fs27 = nodeFs13) {
72068
- if (!isAbsolute4(dir)) {
72135
+ if (!isAbsolute5(dir)) {
72069
72136
  throw new Error(`Eval source path must be absolute, received "${dir}".`);
72070
72137
  }
72071
72138
  let stat33;
@@ -120208,7 +120275,7 @@ var init_fail = __esm({
120208
120275
  // packages/agent-script/src/modules/git.ts
120209
120276
  import { execFile as execFile3 } from "node:child_process";
120210
120277
  import { mkdir as mkdir34, realpath as realpath9, rm as rm12 } from "node:fs/promises";
120211
- import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute5, relative as relative5, resolve as resolve8, sep as sep6 } from "node:path";
120278
+ import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute6, relative as relative5, resolve as resolve8, sep as sep6 } from "node:path";
120212
120279
  function makeGitModule(cwd) {
120213
120280
  const normalizedCwd = readNonEmptyString6(cwd, "Git module cwd");
120214
120281
  return {
@@ -120424,11 +120491,11 @@ function parseBranchRef(ref) {
120424
120491
  }
120425
120492
  async function resolveWorktreePath(repoRoot, path154, label) {
120426
120493
  const resolvedRoot = resolve8(repoRoot);
120427
- const resolvedPath = isAbsolute5(path154) ? resolve8(path154) : resolve8(resolvedRoot, path154);
120494
+ const resolvedPath = isAbsolute6(path154) ? resolve8(path154) : resolve8(resolvedRoot, path154);
120428
120495
  const canonicalRoot = await realpath9(resolvedRoot);
120429
120496
  const canonicalPath = await resolveCanonicalPath(resolvedPath);
120430
120497
  const relativePath = relative5(canonicalRoot, canonicalPath);
120431
- if (relativePath.length === 0 || relativePath === ".." || relativePath.startsWith(`..${sep6}`) || isAbsolute5(relativePath)) {
120498
+ if (relativePath.length === 0 || relativePath === ".." || relativePath.startsWith(`..${sep6}`) || isAbsolute6(relativePath)) {
120432
120499
  throw new Error(`${label} must be inside the git repository.`);
120433
120500
  }
120434
120501
  return canonicalPath;
@@ -122930,7 +122997,7 @@ var init_package2 = __esm({
122930
122997
  "package.json"() {
122931
122998
  package_default2 = {
122932
122999
  name: "poe-code",
122933
- version: "3.0.236",
123000
+ version: "3.0.237",
122934
123001
  description: "CLI tool to configure Poe API for developer workflows.",
122935
123002
  type: "module",
122936
123003
  main: "./dist/index.js",