@codedrifters/configulator 0.0.291 → 0.0.292

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/lib/index.js CHANGED
@@ -210,6 +210,8 @@ __export(index_exports, {
210
210
  DEFAULT_DISPATCH_MODEL: () => DEFAULT_DISPATCH_MODEL,
211
211
  DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO: () => DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
212
212
  DEFAULT_HOUSEKEEPING_MODEL: () => DEFAULT_HOUSEKEEPING_MODEL,
213
+ DEFAULT_ISSUE_PRIORITY: () => DEFAULT_ISSUE_PRIORITY,
214
+ DEFAULT_ISSUE_STATUS: () => DEFAULT_ISSUE_STATUS,
213
215
  DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS: () => DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS,
214
216
  DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER: () => DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER,
215
217
  DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER: () => DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER,
@@ -226,6 +228,7 @@ __export(index_exports, {
226
228
  DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS: () => DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
227
229
  DEFAULT_PROGRESS_FILES_STATE_DIR: () => DEFAULT_PROGRESS_FILES_STATE_DIR,
228
230
  DEFAULT_REQUIRE_PRODUCT_CONTEXT: () => DEFAULT_REQUIRE_PRODUCT_CONTEXT,
231
+ DEFAULT_RESOLVED_ISSUE_DEFAULTS: () => DEFAULT_RESOLVED_ISSUE_DEFAULTS,
229
232
  DEFAULT_SAMPLE_COMPILER_OPTIONS: () => DEFAULT_SAMPLE_COMPILER_OPTIONS,
230
233
  DEFAULT_SCHEDULED_TASKS_ROOT: () => DEFAULT_SCHEDULED_TASKS_ROOT,
231
234
  DEFAULT_SCHEDULED_TASK_ENTRIES: () => DEFAULT_SCHEDULED_TASK_ENTRIES,
@@ -277,6 +280,8 @@ __export(index_exports, {
277
280
  TypeScriptConfig: () => TypeScriptConfig,
278
281
  TypeScriptProject: () => TypeScriptProject,
279
282
  UNKNOWN_TYPE_FALLBACK_TIER: () => UNKNOWN_TYPE_FALLBACK_TIER,
283
+ VALID_PRIORITY_VALUES: () => VALID_PRIORITY_VALUES,
284
+ VALID_STATUS_VALUES: () => VALID_STATUS_VALUES,
280
285
  VERSION: () => VERSION,
281
286
  VERSION_KEYS_SKIP: () => VERSION_KEYS_SKIP,
282
287
  VERSION_NPM_PACKAGES: () => VERSION_NPM_PACKAGES,
@@ -335,6 +340,7 @@ __export(index_exports, {
335
340
  githubWorkflowBundle: () => githubWorkflowBundle,
336
341
  industryDiscoveryBundle: () => industryDiscoveryBundle,
337
342
  jestBundle: () => jestBundle,
343
+ labelsForPhase: () => labelsForPhase,
338
344
  maintenanceAuditBundle: () => maintenanceAuditBundle,
339
345
  meetingAnalysisBundle: () => meetingAnalysisBundle,
340
346
  orchestratorBundle: () => orchestratorBundle,
@@ -388,6 +394,7 @@ __export(index_exports, {
388
394
  resolveAgentTiers: () => resolveAgentTiers,
389
395
  resolveAstroProjectOutdir: () => resolveAstroProjectOutdir,
390
396
  resolveAwsCdkProjectOutdir: () => resolveAwsCdkProjectOutdir,
397
+ resolveIssueDefaults: () => resolveIssueDefaults,
391
398
  resolveIssueTemplates: () => resolveIssueTemplates,
392
399
  resolveModelAlias: () => resolveModelAlias,
393
400
  resolveOrchestratorAssets: () => resolveOrchestratorAssets,
@@ -411,6 +418,7 @@ __export(index_exports, {
411
418
  typescriptBundle: () => typescriptBundle,
412
419
  upstreamConfigulatorDocsBundle: () => upstreamConfigulatorDocsBundle,
413
420
  validateAgentTierConfig: () => validateAgentTierConfig,
421
+ validateIssueDefaultsConfig: () => validateIssueDefaultsConfig,
414
422
  validateIssueTemplatesConfig: () => validateIssueTemplatesConfig,
415
423
  validateMonorepoLayout: () => validateMonorepoLayout,
416
424
  validateProgressFilesConfig: () => validateProgressFilesConfig,
@@ -3901,8 +3909,21 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
3901
3909
  "| `status:in-progress` | A worker has claimed the issue and a branch exists. Set when the worker starts; cleared only when the worker opens a PR or the issue fails. |",
3902
3910
  "| `status:ready-for-review` | A PR has been opened for this issue and is awaiting review and merge. Replaces `status:in-progress` at the moment the PR opens. |",
3903
3911
  "| `status:needs-attention` | Automated triage has flagged the issue for human review (stale, failed worker, or ambiguous state). Humans reset this label manually. |",
3912
+ "| `status:deferred` | Captured for provenance only; should not be auto-dispatched. Used by consumers that want a low-priority backlog (e.g. people-profile follow-ups in research-heavy planning repos) to stay out of the orchestrator's queue until a human or a consumer-configured scheduled task promotes it. |",
3904
3913
  "| `status:done` | The change has shipped. Set when the PR merges and the issue closes. |",
3905
3914
  "",
3915
+ "### Configurable filing-site defaults",
3916
+ "",
3917
+ "The bundle-shipped `gh issue create` recipes default to",
3918
+ "`status:ready` + `priority:medium`. Consumers can override the",
3919
+ "defaults per-phase-label via",
3920
+ "`AgentConfigOptions.issueDefaults` \u2014 e.g. flip every",
3921
+ "`people:research` filing to `status:deferred` + `priority:low`",
3922
+ "without touching the bundle source. See the **`issueDefaults`**",
3923
+ "section in the configulator agent-config docs for the full",
3924
+ "schema and consumer example. `status:deferred` is a valid",
3925
+ "override value reserved for this exact use case.",
3926
+ "",
3906
3927
  "### Blocking Rules",
3907
3928
  "",
3908
3929
  "Two rules force `status:blocked` \u2014 both are non-negotiable:",
@@ -5972,8 +5993,92 @@ function buildBusinessModelsBundle(paths = DEFAULT_AGENT_PATHS) {
5972
5993
  }
5973
5994
  var businessModelsBundle = buildBusinessModelsBundle();
5974
5995
 
5996
+ // src/agent/bundles/issue-defaults.ts
5997
+ var VALID_STATUS_VALUES = [
5998
+ "ready",
5999
+ "blocked",
6000
+ "in-progress",
6001
+ "ready-for-review",
6002
+ "needs-attention",
6003
+ "done",
6004
+ "deferred"
6005
+ ];
6006
+ var VALID_PRIORITY_VALUES = [
6007
+ "critical",
6008
+ "high",
6009
+ "medium",
6010
+ "low",
6011
+ "trivial"
6012
+ ];
6013
+ var DEFAULT_ISSUE_STATUS = "ready";
6014
+ var DEFAULT_ISSUE_PRIORITY = "medium";
6015
+ var DEFAULT_RESOLVED_ISSUE_DEFAULTS = {
6016
+ defaults: {
6017
+ status: DEFAULT_ISSUE_STATUS,
6018
+ priority: DEFAULT_ISSUE_PRIORITY
6019
+ },
6020
+ overrides: {}
6021
+ };
6022
+ function resolveIssueDefaults(config) {
6023
+ if (config === void 0) {
6024
+ return DEFAULT_RESOLVED_ISSUE_DEFAULTS;
6025
+ }
6026
+ const overrides = {};
6027
+ for (const [phaseLabel, override] of Object.entries(config)) {
6028
+ assertValidPhaseLabel(phaseLabel);
6029
+ assertValidOverride(phaseLabel, override);
6030
+ overrides[phaseLabel] = {
6031
+ status: override.status ?? DEFAULT_ISSUE_STATUS,
6032
+ priority: override.priority ?? DEFAULT_ISSUE_PRIORITY
6033
+ };
6034
+ }
6035
+ return {
6036
+ defaults: {
6037
+ status: DEFAULT_ISSUE_STATUS,
6038
+ priority: DEFAULT_ISSUE_PRIORITY
6039
+ },
6040
+ overrides
6041
+ };
6042
+ }
6043
+ function validateIssueDefaultsConfig(config) {
6044
+ return resolveIssueDefaults(config);
6045
+ }
6046
+ function labelsForPhase(resolved, phaseLabel) {
6047
+ return resolved.overrides[phaseLabel] ?? resolved.defaults;
6048
+ }
6049
+ function assertValidPhaseLabel(phaseLabel) {
6050
+ if (typeof phaseLabel !== "string" || phaseLabel.trim() === "") {
6051
+ throw new Error(
6052
+ "AgentConfigOptions.issueDefaults: phase-label keys must be non-empty strings (e.g. `people:research`)."
6053
+ );
6054
+ }
6055
+ }
6056
+ function assertValidOverride(phaseLabel, override) {
6057
+ if (override === null || typeof override !== "object" || Array.isArray(override)) {
6058
+ throw new Error(
6059
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"] must be an object with optional \`status\` and \`priority\` fields.`
6060
+ );
6061
+ }
6062
+ const { status, priority } = override;
6063
+ if (status === void 0 && priority === void 0) {
6064
+ throw new Error(
6065
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"] must declare at least one of \`status\` or \`priority\`. Empty entries are rejected because they are almost always a typo on the field name.`
6066
+ );
6067
+ }
6068
+ if (status !== void 0 && !VALID_STATUS_VALUES.includes(status)) {
6069
+ throw new Error(
6070
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"].status="${status}" is not a recognised status value. Allowed values: ${VALID_STATUS_VALUES.join(", ")}.`
6071
+ );
6072
+ }
6073
+ if (priority !== void 0 && !VALID_PRIORITY_VALUES.includes(priority)) {
6074
+ throw new Error(
6075
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"].priority="${priority}" is not a recognised priority value. Allowed values: ${VALID_PRIORITY_VALUES.join(", ")}.`
6076
+ );
6077
+ }
6078
+ }
6079
+
5975
6080
  // src/agent/bundles/company-profile.ts
5976
- function buildCompanyProfileAnalystSubAgent(paths) {
6081
+ function buildCompanyProfileAnalystSubAgent(paths, issueDefaults) {
5977
6082
  return {
5978
6083
  name: "company-profile-analyst",
5979
6084
  description: "Researches an external company (competitor, vendor, partner, customer, etc.) from public sources and produces a structured markdown profile, then enqueues downstream `people:research` and `software:research` issues for notable people and software products surfaced during profiling. Also handles profile enrichment against business-model canvases (`company:match`), maintenance refreshes on a configurable staleness cadence (`company:refresh`), and cross-profile competitive synthesis for a segment (`company:analyze`). One company or segment per session, tracked by company:* GitHub issue labels.",
@@ -6383,8 +6488,8 @@ function buildCompanyProfileAnalystSubAgent(paths) {
6383
6488
  "",
6384
6489
  " - `type:people-profile`",
6385
6490
  " - `people:research`",
6386
- " - `priority:medium`",
6387
- " - `status:ready`",
6491
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
6492
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
6388
6493
  "",
6389
6494
  " The issue body must include:",
6390
6495
  " - A **discovery source** line naming this company profile",
@@ -6400,8 +6505,8 @@ function buildCompanyProfileAnalystSubAgent(paths) {
6400
6505
  "",
6401
6506
  " - `type:software-profile`",
6402
6507
  " - `software:research`",
6403
- " - `priority:medium`",
6404
- " - `status:ready`",
6508
+ ` - \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\``,
6509
+ ` - \`status:${labelsForPhase(issueDefaults, "software:research").status}\``,
6405
6510
  "",
6406
6511
  " The issue body must include:",
6407
6512
  " - A **discovery source** line naming this company profile",
@@ -6842,47 +6947,52 @@ function buildCompanyProfileAnalystSubAgent(paths) {
6842
6947
  ].join("\n")
6843
6948
  };
6844
6949
  }
6845
- var PROFILE_COMPANY_EVALS_JSON = JSON.stringify(
6846
- {
6847
- skill_name: "profile-company",
6848
- evals: [
6849
- {
6850
- id: 1,
6851
- prompt: "/profile-company Acme Registration \u2014 they're a mid-market B2B event platform we ran into at a trade show last month. framing: competitive analysis for our self-service registration feature.",
6852
- expected_output: "A `company:research` issue is created with `type:company-profile`, `priority:medium`, and `status:ready`. The issue body carries the company name, an inferred or stated type (likely `competitor` given the framing), the framing text, and any supplied overrides. Phase 1 produces a research-notes file under the project's notes directory with sources annotated by tier (T1/T2/T3/T4) and date. Phase 2 opens a `company:draft` issue and may additionally open `people:research` issues for notable leaders surfaced and `software:research` issues for adjacent product mentions. The skill does not author person profiles, software profiles, or comparative analyses itself.",
6853
- files: [],
6854
- product_context_refs: [
6855
- "Mission",
6856
- "Domain Vocabulary",
6857
- "In-Scope Capabilities"
6858
- ]
6859
- },
6860
- {
6861
- id: 2,
6862
- prompt: "Profile a startup called Lumen Events. Their current company page lists a 150-person team but a TechCrunch article from six months ago said they were at 80 people. Handle the conflict.",
6863
- expected_output: "The `company:research` issue body captures the conflict up-front under a dedicated conflict-resolution note. The research notes file annotates the live company page as a T1 living source and the TechCrunch article as a T3 secondary source. Conflict resolution follows the documented hierarchy: T1 wins on headcount (a fast-decay claim), so the current-state profile records 150 employees. The profile adds an inline note flagging that the T3 source is six months old and may simply be stale. Sources section lists each citation with tier, access date or publish date, and URL.",
6864
- files: [],
6865
- product_context_refs: ["Domain Vocabulary"]
6866
- },
6867
- {
6868
- id: 3,
6869
- prompt: "/profile-company Acme Registration \u2014 we already have a profile for them but it's nine months old. Refresh it.",
6870
- expected_output: "The pipeline routes through the refresh phase (not a fresh profile). It reads the existing profile slug and refuses to create a second profile under a new slug. When the existing profile is younger than the configured staleness threshold and `force: true` is not set, the refresh phase exits early and appends a revision-history row noting the review. When the profile is past cadence (nine months qualifies for most fast-decay fields), the refresh updates fast-decay claims in place (headcount, leadership, pricing, product features) while preserving stable history, and appends a revision-history row citing what changed and which sources were re-checked. No new profile file is created.",
6871
- files: [],
6872
- product_context_refs: ["Domain Vocabulary"]
6873
- }
6874
- ]
6875
- },
6876
- null,
6877
- 2
6878
- );
6879
- var PROFILE_COMPANY_REFERENCE_FILES = [
6880
- {
6881
- path: "evals/evals.json",
6882
- content: PROFILE_COMPANY_EVALS_JSON
6883
- }
6884
- ];
6885
- function buildProfileCompanySkill(paths) {
6950
+ function buildProfileCompanyEvalsJson(issueDefaults) {
6951
+ const research = labelsForPhase(issueDefaults, "company:research");
6952
+ return JSON.stringify(
6953
+ {
6954
+ skill_name: "profile-company",
6955
+ evals: [
6956
+ {
6957
+ id: 1,
6958
+ prompt: "/profile-company Acme Registration \u2014 they're a mid-market B2B event platform we ran into at a trade show last month. framing: competitive analysis for our self-service registration feature.",
6959
+ expected_output: `A \`company:research\` issue is created with \`type:company-profile\`, \`priority:${research.priority}\`, and \`status:${research.status}\`. The issue body carries the company name, an inferred or stated type (likely \`competitor\` given the framing), the framing text, and any supplied overrides. Phase 1 produces a research-notes file under the project's notes directory with sources annotated by tier (T1/T2/T3/T4) and date. Phase 2 opens a \`company:draft\` issue and may additionally open \`people:research\` issues for notable leaders surfaced and \`software:research\` issues for adjacent product mentions. The skill does not author person profiles, software profiles, or comparative analyses itself.`,
6960
+ files: [],
6961
+ product_context_refs: [
6962
+ "Mission",
6963
+ "Domain Vocabulary",
6964
+ "In-Scope Capabilities"
6965
+ ]
6966
+ },
6967
+ {
6968
+ id: 2,
6969
+ prompt: "Profile a startup called Lumen Events. Their current company page lists a 150-person team but a TechCrunch article from six months ago said they were at 80 people. Handle the conflict.",
6970
+ expected_output: "The `company:research` issue body captures the conflict up-front under a dedicated conflict-resolution note. The research notes file annotates the live company page as a T1 living source and the TechCrunch article as a T3 secondary source. Conflict resolution follows the documented hierarchy: T1 wins on headcount (a fast-decay claim), so the current-state profile records 150 employees. The profile adds an inline note flagging that the T3 source is six months old and may simply be stale. Sources section lists each citation with tier, access date or publish date, and URL.",
6971
+ files: [],
6972
+ product_context_refs: ["Domain Vocabulary"]
6973
+ },
6974
+ {
6975
+ id: 3,
6976
+ prompt: "/profile-company Acme Registration \u2014 we already have a profile for them but it's nine months old. Refresh it.",
6977
+ expected_output: "The pipeline routes through the refresh phase (not a fresh profile). It reads the existing profile slug and refuses to create a second profile under a new slug. When the existing profile is younger than the configured staleness threshold and `force: true` is not set, the refresh phase exits early and appends a revision-history row noting the review. When the profile is past cadence (nine months qualifies for most fast-decay fields), the refresh updates fast-decay claims in place (headcount, leadership, pricing, product features) while preserving stable history, and appends a revision-history row citing what changed and which sources were re-checked. No new profile file is created.",
6978
+ files: [],
6979
+ product_context_refs: ["Domain Vocabulary"]
6980
+ }
6981
+ ]
6982
+ },
6983
+ null,
6984
+ 2
6985
+ );
6986
+ }
6987
+ function buildProfileCompanyReferenceFiles(issueDefaults) {
6988
+ return [
6989
+ {
6990
+ path: "evals/evals.json",
6991
+ content: buildProfileCompanyEvalsJson(issueDefaults)
6992
+ }
6993
+ ];
6994
+ }
6995
+ function buildProfileCompanySkill(paths, issueDefaults) {
6886
6996
  return {
6887
6997
  name: "profile-company",
6888
6998
  description: "Kick off a company-profile pipeline. Creates a company:research issue for the given company and dispatches Phase 1 (Research) in the company-profile-analyst agent.",
@@ -6891,7 +7001,7 @@ function buildProfileCompanySkill(paths) {
6891
7001
  context: "fork",
6892
7002
  agent: "company-profile-analyst",
6893
7003
  platforms: { cursor: { exclude: true } },
6894
- referenceFiles: PROFILE_COMPANY_REFERENCE_FILES,
7004
+ referenceFiles: buildProfileCompanyReferenceFiles(issueDefaults),
6895
7005
  instructions: [
6896
7006
  "# Profile Company",
6897
7007
  "",
@@ -6922,7 +7032,7 @@ function buildProfileCompanySkill(paths) {
6922
7032
  "## Steps",
6923
7033
  "",
6924
7034
  "1. Create a `company:research` issue with `type:company-profile`,",
6925
- " `priority:medium`, and `status:ready`. Body must include the",
7035
+ ` \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:research").status}\`. Body must include the`,
6926
7036
  " company name, selected type, framing, and any overrides.",
6927
7037
  "2. Execute Phase 1 (Research) of the company-profile-analyst agent.",
6928
7038
  "3. Phase 1 creates the `company:draft` issue. Phase 2 may create a",
@@ -6946,7 +7056,7 @@ function buildProfileCompanySkill(paths) {
6946
7056
  ].join("\n")
6947
7057
  };
6948
7058
  }
6949
- function buildMatchCompanySkill(paths) {
7059
+ function buildMatchCompanySkill(paths, issueDefaults) {
6950
7060
  return {
6951
7061
  name: "match-company",
6952
7062
  description: "Kick off a company-profile match (enrichment) cycle. Creates a company:match issue for an existing profile and dispatches Phase 4 (Match) in the company-profile-analyst agent. Match enriches the profile with business-model, segment, and size context from existing docs \u2014 no web searches.",
@@ -6996,7 +7106,7 @@ function buildMatchCompanySkill(paths) {
6996
7106
  "## Steps",
6997
7107
  "",
6998
7108
  "1. Create a `company:match` issue with `type:company-profile`,",
6999
- " `priority:medium`, and `status:ready`. Body must include the",
7109
+ ` \`priority:${labelsForPhase(issueDefaults, "company:match").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:match").status}\`. Body must include the`,
7000
7110
  " profile path and any overrides.",
7001
7111
  "2. Execute Phase 4 (Match) of the company-profile-analyst agent.",
7002
7112
  "",
@@ -7011,7 +7121,7 @@ function buildMatchCompanySkill(paths) {
7011
7121
  ].join("\n")
7012
7122
  };
7013
7123
  }
7014
- function buildRefreshCompanySkill(paths) {
7124
+ function buildRefreshCompanySkill(paths, issueDefaults) {
7015
7125
  return {
7016
7126
  name: "refresh-company",
7017
7127
  description: "Kick off a company-profile refresh cycle. Creates a company:refresh issue for an existing profile and dispatches Phase 5 (Refresh) in the company-profile-analyst agent. Refresh re-verifies the profile with 4\u20136 targeted web searches and updates it in place. Respects a configurable staleness threshold so profiles younger than the threshold exit early.",
@@ -7069,7 +7179,7 @@ function buildRefreshCompanySkill(paths) {
7069
7179
  "## Steps",
7070
7180
  "",
7071
7181
  "1. Create a `company:refresh` issue with `type:company-profile`,",
7072
- " `priority:medium`, and `status:ready`. Body must include the",
7182
+ ` \`priority:${labelsForPhase(issueDefaults, "company:refresh").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:refresh").status}\`. Body must include the`,
7073
7183
  " profile path and any overrides.",
7074
7184
  "2. Execute Phase 5 (Refresh) of the company-profile-analyst agent.",
7075
7185
  "",
@@ -7085,7 +7195,7 @@ function buildRefreshCompanySkill(paths) {
7085
7195
  ].join("\n")
7086
7196
  };
7087
7197
  }
7088
- function buildAnalyzeSegmentSkill(paths) {
7198
+ function buildAnalyzeSegmentSkill(paths, issueDefaults) {
7089
7199
  return {
7090
7200
  name: "analyze-segment",
7091
7201
  description: "Kick off a segment-level competitive-analysis cycle. Creates a company:analyze issue for the target segment and dispatches Phase 6 (Analyze) in the company-profile-analyst agent. Analyze synthesizes every profile in the segment into one competitive-analysis document. Blocks on open company:draft issues for the segment.",
@@ -7142,7 +7252,7 @@ function buildAnalyzeSegmentSkill(paths) {
7142
7252
  "## Steps",
7143
7253
  "",
7144
7254
  "1. Create a `company:analyze` issue with `type:company-profile`,",
7145
- " `priority:medium`, and `status:ready`. Body must include the",
7255
+ ` \`priority:${labelsForPhase(issueDefaults, "company:analyze").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:analyze").status}\`. Body must include the`,
7146
7256
  " segment slug and any overrides.",
7147
7257
  "2. Execute Phase 6 (Analyze) of the company-profile-analyst agent.",
7148
7258
  "",
@@ -7159,7 +7269,7 @@ function buildAnalyzeSegmentSkill(paths) {
7159
7269
  ].join("\n")
7160
7270
  };
7161
7271
  }
7162
- function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS) {
7272
+ function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
7163
7273
  return {
7164
7274
  name: "company-profile",
7165
7275
  description: "Company research and profiling pipeline: research, draft profile, followup, match, refresh, analyze. Enabled by default; domain-neutral; filesystem-durable between phases. Phase 3 (Followup) hands surfaced people and software products off to the `people-profile` and `software-profile` bundles via `people:research` and `software:research` issues. Phase 4 (Match) enriches profiles against business-model canvases. Phase 5 (Refresh) re-verifies profiles on a configurable staleness cadence. Phase 6 (Analyze) synthesizes profiles in a segment into a competitive-analysis document.",
@@ -7212,12 +7322,12 @@ function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS) {
7212
7322
  }
7213
7323
  ],
7214
7324
  skills: [
7215
- buildProfileCompanySkill(paths),
7216
- buildMatchCompanySkill(paths),
7217
- buildRefreshCompanySkill(paths),
7218
- buildAnalyzeSegmentSkill(paths)
7325
+ buildProfileCompanySkill(paths, issueDefaults),
7326
+ buildMatchCompanySkill(paths, issueDefaults),
7327
+ buildRefreshCompanySkill(paths, issueDefaults),
7328
+ buildAnalyzeSegmentSkill(paths, issueDefaults)
7219
7329
  ],
7220
- subAgents: [buildCompanyProfileAnalystSubAgent(paths)],
7330
+ subAgents: [buildCompanyProfileAnalystSubAgent(paths, issueDefaults)],
7221
7331
  labels: [
7222
7332
  {
7223
7333
  name: "type:company-profile",
@@ -7397,7 +7507,8 @@ var CUSTOMER_PROFILE_REFERENCE_FILES = [
7397
7507
  content: TEMPLATE_CUSTOMER_PROFILE
7398
7508
  }
7399
7509
  ];
7400
- function buildCustomerProfileAnalystSubAgent(paths) {
7510
+ function buildCustomerProfileAnalystSubAgent(paths, issueDefaults) {
7511
+ void issueDefaults;
7401
7512
  return {
7402
7513
  name: "customer-profile-analyst",
7403
7514
  description: "Authors customer-archetype research through a 3-phase pipeline (discover \u2192 profile \u2192 competitors). Segments customer archetypes, profiles each archetype's goals, jobs-to-be-done, constraints, and buying process, then maps competitor features (from the shared software-profile feature matrix) to each archetype's needs and hands off unmet-need gaps to the requirements-analyst as req:scan seeds. One phase per session, tracked by customer:* GitHub issue labels with filesystem-based durability between phases.",
@@ -7980,7 +8091,7 @@ function buildCustomerProfileAnalystSubAgent(paths) {
7980
8091
  ].join("\n")
7981
8092
  };
7982
8093
  }
7983
- function buildDiscoverCustomersSkill(paths) {
8094
+ function buildDiscoverCustomersSkill(paths, issueDefaults) {
7984
8095
  return {
7985
8096
  name: "discover-customers",
7986
8097
  description: "Kick off the discover phase of a customer-research campaign. Creates a customer:discover issue for the supplied scope (industry, segment, or the consuming project as a whole) and dispatches Phase 1 of the customer-profile-analyst, which scans existing documentation for archetype candidates, writes a discovery report, and creates downstream customer:profile issues.",
@@ -8022,7 +8133,7 @@ function buildDiscoverCustomersSkill(paths) {
8022
8133
  "## Steps",
8023
8134
  "",
8024
8135
  "1. Create a `customer:discover` issue with `type:customer-profile`,",
8025
- " `priority:medium`, and `status:ready`. The body must include the",
8136
+ ` \`priority:${labelsForPhase(issueDefaults, "customer:discover").priority}\`, and \`status:${labelsForPhase(issueDefaults, "customer:discover").status}\`. The body must include the`,
8026
8137
  " scope slug and any known archetypes to include or exclude.",
8027
8138
  "2. Execute Phase 1 (Discover) of the customer-profile-analyst agent.",
8028
8139
  "3. Phase 1 writes the discovery report and creates one",
@@ -8037,7 +8148,7 @@ function buildDiscoverCustomersSkill(paths) {
8037
8148
  ].join("\n")
8038
8149
  };
8039
8150
  }
8040
- function buildProfileCustomerSkill(paths) {
8151
+ function buildProfileCustomerSkill(paths, issueDefaults) {
8041
8152
  return {
8042
8153
  name: "profile-customer",
8043
8154
  description: "Kick off the profile phase for one customer archetype. Creates a customer:profile issue for the supplied archetype and dispatches Phase 2 of the customer-profile-analyst, which populates the archetype page with segment, goals, jobs-to-be-done, constraints, buying process, technology landscape, and regulatory applicability using the ship-with customer-profile-page template.",
@@ -8097,7 +8208,7 @@ function buildProfileCustomerSkill(paths) {
8097
8208
  "## Steps",
8098
8209
  "",
8099
8210
  "1. Create a `customer:profile` issue with `type:customer-profile`,",
8100
- " `priority:medium`, and `status:ready`. The body must include the",
8211
+ ` \`priority:${labelsForPhase(issueDefaults, "customer:profile").priority}\`, and \`status:${labelsForPhase(issueDefaults, "customer:profile").status}\`. The body must include the`,
8101
8212
  " archetype slug and (optionally) the segment slug.",
8102
8213
  "2. Execute Phase 2 (Profile) of the customer-profile-analyst agent.",
8103
8214
  " The agent runs 4\u20138 targeted web searches and populates the",
@@ -8117,7 +8228,7 @@ function buildProfileCustomerSkill(paths) {
8117
8228
  ].join("\n")
8118
8229
  };
8119
8230
  }
8120
- function buildAnalyzeCustomerCompetitorsSkill(paths) {
8231
+ function buildAnalyzeCustomerCompetitorsSkill(paths, issueDefaults) {
8121
8232
  return {
8122
8233
  name: "analyze-customer-competitors",
8123
8234
  description: "Kick off the competitors phase for one customer archetype. Creates a customer:competitors issue for the supplied archetype and dispatches Phase 3 of the customer-profile-analyst, which maps rows from the shared software-profile feature matrix to the archetype's needs, identifies unmet needs, and hands off each unmet need as a req:scan seed to the requirements-analyst bundle.",
@@ -8171,8 +8282,8 @@ function buildAnalyzeCustomerCompetitorsSkill(paths) {
8171
8282
  "## Steps",
8172
8283
  "",
8173
8284
  "1. Create a `customer:competitors` issue with",
8174
- " `type:customer-profile`, `priority:medium`, and",
8175
- " `status:ready` (or `status:blocked` when still dependent on a",
8285
+ ` \`type:customer-profile\`, \`priority:${labelsForPhase(issueDefaults, "customer:competitors").priority}\`, and`,
8286
+ ` \`status:${labelsForPhase(issueDefaults, "customer:competitors").status}\` (or \`status:blocked\` when still dependent on a`,
8176
8287
  " Phase 2 profile issue). Body must include the archetype page",
8177
8288
  " path.",
8178
8289
  "2. Execute Phase 3 (Competitors) of the customer-profile-analyst",
@@ -8197,7 +8308,7 @@ function buildAnalyzeCustomerCompetitorsSkill(paths) {
8197
8308
  ].join("\n")
8198
8309
  };
8199
8310
  }
8200
- function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS) {
8311
+ function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
8201
8312
  return {
8202
8313
  name: "customer-profile",
8203
8314
  description: "Customer-archetype research pipeline: discover, profile, competitors. 3 phases with customer:* phase labels. Segments customer archetypes, profiles each archetype's goals, jobs-to-be-done, constraints, and buying process, then maps competitor features (from the shared software-profile feature matrix) to each archetype's needs and hands off unmet-need gaps to the requirements-analyst bundle as req:scan seeds. Enabled by default; domain-neutral; customer-centric (distinct from company-profile); filesystem-durable between phases.",
@@ -8268,11 +8379,11 @@ function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS) {
8268
8379
  }
8269
8380
  ],
8270
8381
  skills: [
8271
- buildDiscoverCustomersSkill(paths),
8272
- buildProfileCustomerSkill(paths),
8273
- buildAnalyzeCustomerCompetitorsSkill(paths)
8382
+ buildDiscoverCustomersSkill(paths, issueDefaults),
8383
+ buildProfileCustomerSkill(paths, issueDefaults),
8384
+ buildAnalyzeCustomerCompetitorsSkill(paths, issueDefaults)
8274
8385
  ],
8275
- subAgents: [buildCustomerProfileAnalystSubAgent(paths)],
8386
+ subAgents: [buildCustomerProfileAnalystSubAgent(paths, issueDefaults)],
8276
8387
  labels: [
8277
8388
  {
8278
8389
  name: "type:customer-profile",
@@ -9478,7 +9589,7 @@ var githubWorkflowBundle = {
9478
9589
  };
9479
9590
 
9480
9591
  // src/agent/bundles/industry-discovery.ts
9481
- function buildIndustryDiscoveryAnalystSubAgent(paths) {
9592
+ function buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults) {
9482
9593
  return {
9483
9594
  name: "industry-discovery-analyst",
9484
9595
  description: "Discovers candidate industry verticals, scores each against a configurable capability/fit rubric, and creates planning issues for verticals that clear the threshold. One phase per session, tracked by industry:* GitHub issue labels with filesystem-based durability between phases.",
@@ -9816,8 +9927,8 @@ function buildIndustryDiscoveryAnalystSubAgent(paths) {
9816
9927
  "4. **Create one `research:scope` issue per cleared vertical.** This",
9817
9928
  " assumes the `research-pipeline` bundle is enabled in the consuming",
9818
9929
  " project. Each downstream issue should:",
9819
- " - Carry `type:research`, `research:scope`, `priority:medium`, and",
9820
- " `status:ready` labels",
9930
+ ` - Carry \`type:research\`, \`research:scope\`, \`priority:${labelsForPhase(issueDefaults, "research:scope").priority}\`, and`,
9931
+ ` \`status:${labelsForPhase(issueDefaults, "research:scope").status}\` labels`,
9821
9932
  " - Include the research question framed for the vertical (what the",
9822
9933
  " downstream research needs to answer)",
9823
9934
  " - Cite the evaluation row that justified advancing the vertical",
@@ -9868,7 +9979,7 @@ function buildIndustryDiscoveryAnalystSubAgent(paths) {
9868
9979
  ].join("\n")
9869
9980
  };
9870
9981
  }
9871
- function buildDiscoverIndustriesSkill(paths) {
9982
+ function buildDiscoverIndustriesSkill(paths, issueDefaults) {
9872
9983
  return {
9873
9984
  name: "discover-industries",
9874
9985
  description: "Kick off an industry-discovery pipeline. Creates an industry:discover issue carrying the discovery scope and dispatches Phase 1 (Discover) in the industry-discovery-analyst agent.",
@@ -9910,7 +10021,7 @@ function buildDiscoverIndustriesSkill(paths) {
9910
10021
  "## Steps",
9911
10022
  "",
9912
10023
  "1. Create an `industry:discover` issue with `type:industry-discovery`,",
9913
- " `priority:medium`, and `status:ready`. Body must include the",
10024
+ ` \`priority:${labelsForPhase(issueDefaults, "industry:discover").priority}\`, and \`status:${labelsForPhase(issueDefaults, "industry:discover").status}\`. Body must include the`,
9914
10025
  " verbatim scope, authorized sources, and any overrides.",
9915
10026
  "2. Execute Phase 1 (Discover) of the industry-discovery-analyst",
9916
10027
  " agent.",
@@ -9931,7 +10042,7 @@ function buildDiscoverIndustriesSkill(paths) {
9931
10042
  ].join("\n")
9932
10043
  };
9933
10044
  }
9934
- function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS) {
10045
+ function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
9935
10046
  return {
9936
10047
  name: "industry-discovery",
9937
10048
  description: "Industry-vertical discovery pipeline: discover candidates, evaluate against a fit rubric, plan downstream research. Enabled by default; domain-neutral; filesystem-durable between phases.",
@@ -9965,8 +10076,8 @@ function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS) {
9965
10076
  tags: ["workflow"]
9966
10077
  }
9967
10078
  ],
9968
- skills: [buildDiscoverIndustriesSkill(paths)],
9969
- subAgents: [buildIndustryDiscoveryAnalystSubAgent(paths)],
10079
+ skills: [buildDiscoverIndustriesSkill(paths, issueDefaults)],
10080
+ subAgents: [buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults)],
9970
10081
  labels: [
9971
10082
  {
9972
10083
  name: "type:industry-discovery",
@@ -13145,80 +13256,81 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
13145
13256
  "}",
13146
13257
  "",
13147
13258
  "cmd_eligible() {",
13148
- " local issues",
13149
- ' issues=$(gh issue list --label "status:ready" --state open \\',
13150
- ' --search "sort:created-asc" \\',
13151
- ' --json number,title,body,labels --limit 50 2>/dev/null || echo "[]")',
13152
- "",
13153
- " local count",
13154
- ` count=$(echo "$issues" | jq 'length')`,
13155
- ' if [[ "$count" -eq 0 ]]; then',
13156
- ' echo "NO_READY_ISSUES"',
13157
- " return 0",
13158
- " fi",
13259
+ " # Bucketed scan: walk priority levels critical \u2192 high \u2192 medium \u2192 low \u2192",
13260
+ " # trivial, fetching one bucket at a time. The first bucket with at",
13261
+ " # least one survivor (after the Depends-on filter) short-circuits the",
13262
+ " # loop \u2014 lower-priority buckets are never queried in the common case.",
13263
+ " # This guarantees that every higher-priority issue is visible even",
13264
+ " # when the global ready backlog exceeds 50, at the cost of up to one",
13265
+ " # extra `gh issue list` call per empty bucket above the first hit.",
13266
+ " local level",
13267
+ " for level in critical high medium low trivial; do",
13268
+ " local issues",
13269
+ ' issues=$(gh issue list --label "status:ready" --label "priority:${level}" --state open \\',
13270
+ ' --search "sort:created-asc" \\',
13271
+ ' --json number,title,body,labels --limit 50 2>/dev/null || echo "[]")',
13272
+ "",
13273
+ " local count",
13274
+ ` count=$(echo "$issues" | jq 'length')`,
13275
+ ' if [[ "$count" -eq 0 ]]; then',
13276
+ " continue",
13277
+ " fi",
13159
13278
  "",
13160
- " local issue_data",
13161
- ` issue_data=$(echo "$issues" | jq -r '`,
13162
- " .[] |",
13163
- ' (.body | split("\\n") | map(select(test("Depends on:"; "i"))) | .[0] // "") as $dep_line |',
13164
- ' (.labels | map(.name) | join(",")) as $label_str |',
13165
- ' (.labels | map(.name) | map(select(startswith("type:"))) | .[0] // "") as $type_label |',
13166
- ' "\\(.number)\\t\\(.title)\\t\\($dep_line)\\t\\($label_str)\\t\\($type_label)"',
13167
- " ')",
13279
+ " local issue_data",
13280
+ ` issue_data=$(echo "$issues" | jq -r '`,
13281
+ " .[] |",
13282
+ ' (.body | split("\\n") | map(select(test("Depends on:"; "i"))) | .[0] // "") as $dep_line |',
13283
+ ' (.labels | map(.name) | map(select(startswith("type:"))) | .[0] // "") as $type_label |',
13284
+ ' "\\(.number)\\t\\(.title)\\t\\($dep_line)\\t\\($type_label)"',
13285
+ " ')",
13168
13286
  "",
13169
- ' local results=""',
13170
- " while IFS=$'\\t' read -r num title dep_line labels_str type_label; do",
13171
- ' [[ -z "$num" ]] && continue',
13287
+ ' local results=""',
13288
+ " while IFS=$'\\t' read -r num title dep_line type_label; do",
13289
+ ' [[ -z "$num" ]] && continue',
13172
13290
  "",
13173
- ' local deps=""',
13174
- ' if [[ -n "$dep_line" ]]; then',
13175
- ' deps=$(parse_deps "$dep_line")',
13176
- " fi",
13291
+ ' local deps=""',
13292
+ ' if [[ -n "$dep_line" ]]; then',
13293
+ ' deps=$(parse_deps "$dep_line")',
13294
+ " fi",
13177
13295
  "",
13178
- " # Check if any dep is still open.",
13179
- " local has_open_dep=false",
13180
- ' local open_deps=""',
13181
- ' if [[ -n "${deps// /}" ]]; then',
13182
- " for dep in $deps; do",
13183
- ' if ! is_closed "$dep"; then',
13184
- " has_open_dep=true",
13185
- ' open_deps="${open_deps}#${dep} "',
13186
- " fi",
13187
- " done",
13188
- " fi",
13296
+ " # Check if any dep is still open.",
13297
+ " local has_open_dep=false",
13298
+ ' local open_deps=""',
13299
+ ' if [[ -n "${deps// /}" ]]; then',
13300
+ " for dep in $deps; do",
13301
+ ' if ! is_closed "$dep"; then',
13302
+ " has_open_dep=true",
13303
+ ' open_deps="${open_deps}#${dep} "',
13304
+ " fi",
13305
+ " done",
13306
+ " fi",
13189
13307
  "",
13190
- " if $has_open_dep; then",
13191
- ' echo "SKIP #${num} \u2014 dep ${open_deps% } still open"',
13192
- " continue",
13193
- " fi",
13308
+ " if $has_open_dep; then",
13309
+ ' echo "SKIP #${num} \u2014 dep ${open_deps% } still open"',
13310
+ " continue",
13311
+ " fi",
13194
13312
  "",
13195
- " # 5-level priority sort key.",
13196
- " local priority_key=2",
13197
- ' local priority="medium"',
13198
- ' case "$labels_str" in',
13199
- ' *priority:critical*) priority_key=0; priority="critical" ;;',
13200
- ' *priority:high*) priority_key=1; priority="high" ;;',
13201
- ' *priority:medium*) priority_key=2; priority="medium" ;;',
13202
- ' *priority:low*) priority_key=3; priority="low" ;;',
13203
- ' *priority:trivial*) priority_key=4; priority="trivial" ;;',
13204
- " esac",
13313
+ " # Funnel-tier sort key (0-4; 0 dispatches first within a bucket).",
13314
+ ' local type_value="${type_label#type:}"',
13315
+ " local tier_key",
13316
+ ' tier_key=$(tier_of "$type_value")',
13205
13317
  "",
13206
- " # Funnel-tier sort key (0-4; 0 dispatches first on priority tie).",
13207
- ' local type_value="${type_label#type:}"',
13208
- " local tier_key",
13209
- ' tier_key=$(tier_of "$type_value")',
13318
+ ' local label_info=""',
13319
+ ' [[ -n "$type_label" ]] && label_info=" ${type_label}"',
13210
13320
  "",
13211
- ' local label_info=""',
13212
- ' [[ -n "$type_label" ]] && label_info=" ${type_label}"',
13321
+ ' results="${results}${tier_key}\\t${num}\\tPICK #${num} priority:${level} tier:${tier_key}${label_info} \\"${title}\\"\\n"',
13322
+ ' done <<< "$issue_data"',
13213
13323
  "",
13214
- ' results="${results}${priority_key}\\t${tier_key}\\t${num}\\tPICK #${num} priority:${priority} tier:${tier_key}${label_info} \\"${title}\\"\\n"',
13215
- ' done <<< "$issue_data"',
13324
+ " # Within this bucket: sort by funnel tier asc \u2192 issue number asc",
13325
+ " # (FIFO). If any PICK lines survived the Depends-on filter, emit",
13326
+ " # them and short-circuit before querying lower-priority buckets.",
13327
+ ' if [[ -n "$results" ]]; then',
13328
+ ` printf '%b' "$results" | sort -t$'\\t' -k1,1n -k2,2n | cut -f3`,
13329
+ " return 0",
13330
+ " fi",
13331
+ " done",
13216
13332
  "",
13217
- " # Sort by priority (asc, lower priority_key wins), then funnel tier",
13218
- " # (asc, lower tier wins on priority tie), then issue number (FIFO).",
13219
- ' if [[ -n "$results" ]]; then',
13220
- ` printf '%b' "$results" | sort -t$'\\t' -k1,1n -k2,2n -k3,3n | cut -f4`,
13221
- " fi",
13333
+ ' echo "NO_READY_ISSUES"',
13222
13334
  "}",
13223
13335
  "",
13224
13336
  "cmd_stale() {",
@@ -13653,9 +13765,25 @@ var orchestratorSubAgent = {
13653
13765
  ".claude/procedures/check-blocked.sh eligible",
13654
13766
  "```",
13655
13767
  "",
13768
+ "The script walks the priority buckets **critical \u2192 high \u2192 medium \u2192 low",
13769
+ "\u2192 trivial** in order, querying one bucket at a time and short-circuiting",
13770
+ "on the first non-empty bucket whose survivors clear the `Depends on:`",
13771
+ "filter. Each bucket is fetched with",
13772
+ '`gh issue list --label "status:ready" --label "priority:<level>" --limit 50`,',
13773
+ "so every higher-priority issue is visible even when the global ready",
13774
+ "backlog exceeds 50 \u2014 a `priority:critical` filing can never be hidden",
13775
+ "behind 50 older medium/low issues. The cost in the common case (the",
13776
+ "first bucket the script queries is non-empty) is **one `gh issue list`",
13777
+ "call**, identical to the previous single-fetch implementation; the",
13778
+ "worst case is five calls when every higher-priority bucket is empty",
13779
+ "or fully dep-blocked. Per-priority bucket size is still capped at 50",
13780
+ "issues \u2014 see the **Orchestrator Conventions** section in `CLAUDE.md`.",
13781
+ "",
13656
13782
  "The script emits `PICK` lines sorted by **priority desc \u2192 funnel tier asc",
13657
- "\u2192 issue number asc**. Each line carries both `priority:<level>` and",
13658
- "`tier:<n>` so the sort is legible at a glance:",
13783
+ "\u2192 issue number asc** (priority order is enforced by the bucket walk;",
13784
+ "the in-bucket sort handles funnel tier and FIFO). Each line carries",
13785
+ "both `priority:<level>` and `tier:<n>` so the sort is legible at a",
13786
+ "glance:",
13659
13787
  "",
13660
13788
  "```",
13661
13789
  'PICK #42 priority:high tier:1 type:research "FHIR extension analysis"',
@@ -14286,7 +14414,7 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
14286
14414
  "- The orchestrator **never** implements code, creates branches, pushes commits, **or merges PRs** \u2014 it triages issues, picks the next work item, and delegates implementation to other sub-agents. Approved-PR merging is owned by the `pr-reviewer` sub-agent (invoked via `/review-pr` / `/review-prs`).",
14287
14415
  "- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
14288
14416
  "- The queue scan reads only `priority:*` and `status:*` labels \u2014 type-routing (which typed agent handles a given `type:*` label) is the `issue-worker`'s concern, not the orchestrator's. The orchestrator's funnel-tier sort is a tie-breaker on `priority:*`, not a routing decision.",
14289
- "- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number",
14417
+ "- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number. Phase E's queue scan walks each priority bucket in turn (one `gh issue list` call per bucket, **capped at 50 issues per bucket**) and short-circuits on the first bucket whose survivors clear the `Depends on:` filter, so every higher-priority issue is visible even when the global ready backlog is much larger than 50.",
14290
14418
  "- Stale thresholds: 72h for in-progress, 168h for blocked",
14291
14419
  "- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset",
14292
14420
  "",
@@ -14373,7 +14501,7 @@ var orchestratorBundle = {
14373
14501
  };
14374
14502
 
14375
14503
  // src/agent/bundles/people-profile.ts
14376
- function buildPeopleProfileAnalystSubAgent(paths) {
14504
+ function buildPeopleProfileAnalystSubAgent(paths, issueDefaults) {
14377
14505
  return {
14378
14506
  name: "people-profile-analyst",
14379
14507
  description: "Researches an individual person (colleague, customer contact, vendor contact, partner contact, industry expert, or connector) from public sources and produces a structured markdown profile cross-linked to companies, software, and meeting notes, then enqueues downstream `company:research` and `software:research` issues for unprofiled companies and software products surfaced during profiling. Also handles maintenance refreshes on a configurable staleness cadence (`people:refresh`). One person per session, tracked by people:* GitHub issue labels.",
@@ -14810,8 +14938,8 @@ function buildPeopleProfileAnalystSubAgent(paths) {
14810
14938
  "",
14811
14939
  " - `type:company-profile`",
14812
14940
  " - `company:research`",
14813
- " - `priority:medium`",
14814
- " - `status:ready`",
14941
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
14942
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
14815
14943
  "",
14816
14944
  " The issue body must include:",
14817
14945
  " - A **discovery source** line naming this person profile",
@@ -14830,8 +14958,8 @@ function buildPeopleProfileAnalystSubAgent(paths) {
14830
14958
  "",
14831
14959
  " - `type:software-profile`",
14832
14960
  " - `software:research`",
14833
- " - `priority:medium`",
14834
- " - `status:ready`",
14961
+ ` - \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\``,
14962
+ ` - \`status:${labelsForPhase(issueDefaults, "software:research").status}\``,
14835
14963
  "",
14836
14964
  " The issue body must include:",
14837
14965
  " - A **discovery source** line naming this person profile",
@@ -15050,7 +15178,7 @@ function buildPeopleProfileAnalystSubAgent(paths) {
15050
15178
  ].join("\n")
15051
15179
  };
15052
15180
  }
15053
- function buildProfilePersonSkill(paths) {
15181
+ function buildProfilePersonSkill(paths, issueDefaults) {
15054
15182
  return {
15055
15183
  name: "profile-person",
15056
15184
  description: "Kick off a people-profile pipeline. Creates a people:research issue for the given person and dispatches Phase 1 (Research) in the people-profile-analyst agent. Phase 3 (Followup) enqueues downstream `company:research` and `software:research` issues for unprofiled, genuinely-relevant entities surfaced in the profile.",
@@ -15101,7 +15229,7 @@ function buildProfilePersonSkill(paths) {
15101
15229
  "## Steps",
15102
15230
  "",
15103
15231
  "1. Create a `people:research` issue with `type:people-profile`,",
15104
- " `priority:medium`, and `status:ready`. Body must include the",
15232
+ ` \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "people:research").status}\`. Body must include the`,
15105
15233
  " person's name, selected role, primary company, framing, and any",
15106
15234
  " overrides.",
15107
15235
  "2. Execute Phase 1 (Research) of the people-profile-analyst agent.",
@@ -15126,7 +15254,7 @@ function buildProfilePersonSkill(paths) {
15126
15254
  ].join("\n")
15127
15255
  };
15128
15256
  }
15129
- function buildRefreshPersonSkill(paths) {
15257
+ function buildRefreshPersonSkill(paths, issueDefaults) {
15130
15258
  return {
15131
15259
  name: "refresh-person",
15132
15260
  description: "Kick off a people-profile refresh cycle. Creates a people:refresh issue for an existing profile and dispatches Phase 4 (Refresh) in the people-profile-analyst agent. Refresh re-verifies the profile's narrow delta set (role, employer, primary public channel) with 3\u20135 targeted web searches and updates it in place. Respects a configurable staleness threshold so profiles younger than the threshold exit early.",
@@ -15193,7 +15321,7 @@ function buildRefreshPersonSkill(paths) {
15193
15321
  "## Steps",
15194
15322
  "",
15195
15323
  "1. Create a `people:refresh` issue with `type:people-profile`,",
15196
- " `priority:medium`, and `status:ready`. Body must include the",
15324
+ ` \`priority:${labelsForPhase(issueDefaults, "people:refresh").priority}\`, and \`status:${labelsForPhase(issueDefaults, "people:refresh").status}\`. Body must include the`,
15197
15325
  " profile path and any overrides.",
15198
15326
  "2. Execute Phase 4 (Refresh) of the people-profile-analyst agent.",
15199
15327
  "",
@@ -15207,7 +15335,7 @@ function buildRefreshPersonSkill(paths) {
15207
15335
  ].join("\n")
15208
15336
  };
15209
15337
  }
15210
- function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS) {
15338
+ function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
15211
15339
  return {
15212
15340
  name: "people-profile",
15213
15341
  description: "People research and profiling pipeline: research, draft profile, followup, refresh. Enabled by default; domain-neutral; filesystem-durable between phases. Cross-references existing companies, software, and meeting notes, and Phase 3 (Followup) hands unprofiled, genuinely-relevant companies and software products off to the `company-profile` and `software-profile` bundles via `company:research` and `software:research` issues. Phase 4 (Refresh) re-verifies profiles on a configurable staleness cadence.",
@@ -15251,8 +15379,11 @@ function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS) {
15251
15379
  tags: ["workflow"]
15252
15380
  }
15253
15381
  ],
15254
- skills: [buildProfilePersonSkill(paths), buildRefreshPersonSkill(paths)],
15255
- subAgents: [buildPeopleProfileAnalystSubAgent(paths)],
15382
+ skills: [
15383
+ buildProfilePersonSkill(paths, issueDefaults),
15384
+ buildRefreshPersonSkill(paths, issueDefaults)
15385
+ ],
15386
+ subAgents: [buildPeopleProfileAnalystSubAgent(paths, issueDefaults)],
15256
15387
  labels: [
15257
15388
  {
15258
15389
  name: "type:people-profile",
@@ -17417,7 +17548,8 @@ var REGULATORY_RESEARCH_REFERENCE_FILES = [
17417
17548
  content: TEMPLATE_REGULATION
17418
17549
  }
17419
17550
  ];
17420
- function buildRegulatoryResearchAnalystSubAgent(paths) {
17551
+ function buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults) {
17552
+ void issueDefaults;
17421
17553
  return {
17422
17554
  name: "regulatory-research-analyst",
17423
17555
  description: "Authors jurisdictional compliance research through a 3-phase pipeline (scan \u2192 research \u2192 impact). Enumerates applicable regulations by jurisdiction and business activity, researches each in depth, and produces an impact analysis that hands off actionable obligations to the requirements-analyst as req:scan seeds in the SEC category. One phase per session, tracked by regulatory:* GitHub issue labels with filesystem-based durability between phases.",
@@ -17977,7 +18109,7 @@ function buildRegulatoryResearchAnalystSubAgent(paths) {
17977
18109
  ].join("\n")
17978
18110
  };
17979
18111
  }
17980
- function buildScanRegulatoryLandscapeSkill(paths) {
18112
+ function buildScanRegulatoryLandscapeSkill(paths, issueDefaults) {
17981
18113
  return {
17982
18114
  name: "scan-regulatory-landscape",
17983
18115
  description: "Kick off the scan phase of a regulatory-research campaign. Creates a regulatory:scan issue for the supplied scope (industry, jurisdiction, or platform) and dispatches Phase 1 of the regulatory-research-analyst, which writes a scan report and creates downstream regulatory:research issues.",
@@ -18024,7 +18156,7 @@ function buildScanRegulatoryLandscapeSkill(paths) {
18024
18156
  "## Steps",
18025
18157
  "",
18026
18158
  "1. Create a `regulatory:scan` issue with `type:regulatory-research`,",
18027
- " `priority:medium`, and `status:ready`. The body must include the",
18159
+ ` \`priority:${labelsForPhase(issueDefaults, "regulatory:scan").priority}\`, and \`status:${labelsForPhase(issueDefaults, "regulatory:scan").status}\`. The body must include the`,
18028
18160
  " scope slug, the scope type, and any known regulations to include",
18029
18161
  " or exclude.",
18030
18162
  "2. Execute Phase 1 (Scan) of the regulatory-research-analyst agent.",
@@ -18041,7 +18173,7 @@ function buildScanRegulatoryLandscapeSkill(paths) {
18041
18173
  ].join("\n")
18042
18174
  };
18043
18175
  }
18044
- function buildResearchRegulationSkill(paths) {
18176
+ function buildResearchRegulationSkill(paths, issueDefaults) {
18045
18177
  return {
18046
18178
  name: "research-regulation",
18047
18179
  description: "Kick off the research phase for one regulation. Creates a regulatory:research issue for the supplied scope and regulation and dispatches Phase 2 of the regulatory-research-analyst, which populates the regulation page with scope, triggers, key requirements, jurisdiction variations, enforcement, and penalties using the ship-with regulation-page template.",
@@ -18100,8 +18232,8 @@ function buildResearchRegulationSkill(paths) {
18100
18232
  "## Steps",
18101
18233
  "",
18102
18234
  "1. Create a `regulatory:research` issue with",
18103
- " `type:regulatory-research`, `priority:medium`, and",
18104
- " `status:ready`. The body must include the scope slug and the",
18235
+ ` \`type:regulatory-research\`, \`priority:${labelsForPhase(issueDefaults, "regulatory:research").priority}\`, and`,
18236
+ ` \`status:${labelsForPhase(issueDefaults, "regulatory:research").status}\`. The body must include the scope slug and the`,
18105
18237
  " regulation slug.",
18106
18238
  "2. Execute Phase 2 (Research) of the regulatory-research-analyst",
18107
18239
  " agent. The agent runs 6\u201312 targeted web searches and populates",
@@ -18119,7 +18251,7 @@ function buildResearchRegulationSkill(paths) {
18119
18251
  ].join("\n")
18120
18252
  };
18121
18253
  }
18122
- function buildImpactRegulationSkill(paths) {
18254
+ function buildImpactRegulationSkill(paths, issueDefaults) {
18123
18255
  return {
18124
18256
  name: "impact-regulation",
18125
18257
  description: "Kick off the impact phase for one regulation. Creates a regulatory:impact issue for the supplied regulation and dispatches Phase 3 of the regulatory-research-analyst, which assesses product impact, documents capability gaps, and hands off each actionable obligation as a req:scan seed in the SEC (security & compliance) category for the requirements-analyst bundle to consume.",
@@ -18166,8 +18298,8 @@ function buildImpactRegulationSkill(paths) {
18166
18298
  "## Steps",
18167
18299
  "",
18168
18300
  "1. Create a `regulatory:impact` issue with",
18169
- " `type:regulatory-research`, `priority:medium`, and",
18170
- " `status:ready` (or `status:blocked` when still dependent on a",
18301
+ ` \`type:regulatory-research\`, \`priority:${labelsForPhase(issueDefaults, "regulatory:impact").priority}\`, and`,
18302
+ ` \`status:${labelsForPhase(issueDefaults, "regulatory:impact").status}\` (or \`status:blocked\` when still dependent on a`,
18171
18303
  " Phase 2 research issue). Body must include the regulation page",
18172
18304
  " path.",
18173
18305
  "2. Execute Phase 3 (Impact) of the regulatory-research-analyst",
@@ -18188,7 +18320,7 @@ function buildImpactRegulationSkill(paths) {
18188
18320
  ].join("\n")
18189
18321
  };
18190
18322
  }
18191
- function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS) {
18323
+ function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
18192
18324
  return {
18193
18325
  name: "regulatory-research",
18194
18326
  description: "Regulatory compliance research pipeline: scan, research, impact. 3 phases with regulatory:* phase labels. Enumerates jurisdictional regulations by industry and activity, researches each in depth with specific section citations, and hands off actionable obligations to the requirements-analyst bundle as req:scan seeds that become SEC (security & compliance) requirements. Enabled by default; domain-neutral; documents obligations without interpreting them; filesystem-durable between phases.",
@@ -18255,11 +18387,11 @@ function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS) {
18255
18387
  }
18256
18388
  ],
18257
18389
  skills: [
18258
- buildScanRegulatoryLandscapeSkill(paths),
18259
- buildResearchRegulationSkill(paths),
18260
- buildImpactRegulationSkill(paths)
18390
+ buildScanRegulatoryLandscapeSkill(paths, issueDefaults),
18391
+ buildResearchRegulationSkill(paths, issueDefaults),
18392
+ buildImpactRegulationSkill(paths, issueDefaults)
18261
18393
  ],
18262
- subAgents: [buildRegulatoryResearchAnalystSubAgent(paths)],
18394
+ subAgents: [buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults)],
18263
18395
  labels: [
18264
18396
  {
18265
18397
  name: "type:regulatory-research",
@@ -23561,7 +23693,7 @@ var slackBundle = {
23561
23693
  };
23562
23694
 
23563
23695
  // src/agent/bundles/software-profile.ts
23564
- function buildSoftwareProfileAnalystSubAgent(paths) {
23696
+ function buildSoftwareProfileAnalystSubAgent(paths, issueDefaults) {
23565
23697
  return {
23566
23698
  name: "software-profile-analyst",
23567
23699
  description: "Researches a software product (competitor, adjacent, incumbent, enabler, infrastructure, or ecosystem-tool) from public sources, produces a structured markdown profile, contributes rows to a shared feature matrix ranked against configurable segment-importance weights, maps features back to the BCM capability model and flags unmapped features, then enqueues downstream `bcm:outline`, `company:research`, and `people:research` issues for new sub-capabilities, the vendor company, and primary-attribution founders/leaders surfaced during profiling. One product per session, tracked by software:* GitHub issue labels.",
@@ -24100,8 +24232,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24100
24232
  "",
24101
24233
  " - `type:bcm-document`",
24102
24234
  " - `bcm:outline`",
24103
- " - `priority:medium`",
24104
- " - `status:ready`",
24235
+ ` - \`priority:${labelsForPhase(issueDefaults, "bcm:outline").priority}\``,
24236
+ ` - \`status:${labelsForPhase(issueDefaults, "bcm:outline").status}\``,
24105
24237
  "",
24106
24238
  " The issue body must include:",
24107
24239
  " - A **discovery source** line naming this software profile",
@@ -24169,7 +24301,7 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24169
24301
  " `Follow-up Candidates > Adjacent products to evaluate`. Each new",
24170
24302
  " issue follows the same 4-phase pipeline \u2014 start it in the",
24171
24303
  " `software:research` phase with `type:software-profile`,",
24172
- " `priority:medium`, and `status:ready`.",
24304
+ ` \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:research").status}\`.`,
24173
24305
  "",
24174
24306
  "3. **Enqueue a `company:research` issue for the vendor company** if",
24175
24307
  " no matching profile already exists under `<COMPANY_PROFILES_DIR>/`.",
@@ -24180,8 +24312,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24180
24312
  "",
24181
24313
  " - `type:company-profile`",
24182
24314
  " - `company:research`",
24183
- " - `priority:medium`",
24184
- " - `status:ready`",
24315
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
24316
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
24185
24317
  "",
24186
24318
  " The issue body must include:",
24187
24319
  " - A **discovery source** line naming this software profile",
@@ -24199,8 +24331,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24199
24331
  "",
24200
24332
  " - `type:people-profile`",
24201
24333
  " - `people:research`",
24202
- " - `priority:medium`",
24203
- " - `status:ready`",
24334
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
24335
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
24204
24336
  "",
24205
24337
  " The issue body must include:",
24206
24338
  " - A **discovery source** line naming this software profile",
@@ -24343,7 +24475,7 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24343
24475
  ].join("\n")
24344
24476
  };
24345
24477
  }
24346
- function buildProfileSoftwareSkill(paths) {
24478
+ function buildProfileSoftwareSkill(paths, issueDefaults) {
24347
24479
  return {
24348
24480
  name: "profile-software",
24349
24481
  description: "Kick off a software-profile pipeline. Creates a software:research issue for the given product and dispatches Phase 1 (Research) in the software-profile-analyst agent. Phase 4 (Map) writes a BCM capability mapping onto the profile and enqueues `bcm:outline` issues for unmapped features. Phase 5 (Followup) enqueues downstream `company:research` and `people:research` issues for the vendor company and primary-attribution founders/leaders surfaced in the profile.",
@@ -24390,7 +24522,7 @@ function buildProfileSoftwareSkill(paths) {
24390
24522
  "## Steps",
24391
24523
  "",
24392
24524
  "1. Create a `software:research` issue with `type:software-profile`,",
24393
- " `priority:medium`, and `status:ready`. Body must include the",
24525
+ ` \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:research").status}\`. Body must include the`,
24394
24526
  " product name, selected type, framing, and any overrides.",
24395
24527
  "2. Execute Phase 1 (Research) of the software-profile-analyst",
24396
24528
  " agent.",
@@ -24423,7 +24555,7 @@ function buildProfileSoftwareSkill(paths) {
24423
24555
  ].join("\n")
24424
24556
  };
24425
24557
  }
24426
- function buildMapSoftwareSkill(paths) {
24558
+ function buildMapSoftwareSkill(paths, issueDefaults) {
24427
24559
  return {
24428
24560
  name: "map-software",
24429
24561
  description: "Kick off a standalone software-capability mapping session. Creates a software:map issue for an already-profiled product and dispatches Phase 4 (Map) in the software-profile-analyst agent. Produces the `## Capability Mapping` section on the profile and enqueues `bcm:outline` issues for unmapped features above the configured threshold.",
@@ -24478,7 +24610,7 @@ function buildMapSoftwareSkill(paths) {
24478
24610
  "## Steps",
24479
24611
  "",
24480
24612
  "1. Create a `software:map` issue with `type:software-profile`,",
24481
- " `priority:medium`, and `status:ready`. Body must include the",
24613
+ ` \`priority:${labelsForPhase(issueDefaults, "software:map").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:map").status}\`. Body must include the`,
24482
24614
  " profile path and any overrides.",
24483
24615
  "2. Execute Phase 4 (Map) of the software-profile-analyst agent.",
24484
24616
  "3. Phase 4 writes the `## Capability Mapping` section, enqueues",
@@ -24500,7 +24632,7 @@ function buildMapSoftwareSkill(paths) {
24500
24632
  ].join("\n")
24501
24633
  };
24502
24634
  }
24503
- function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS) {
24635
+ function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
24504
24636
  return {
24505
24637
  name: "software-profile",
24506
24638
  description: "Software research, profiling, feature-matrix, and capability-mapping pipeline: research, profile, matrix, map, followup. Enabled by default; domain-neutral; filesystem-durable between phases; ranks features against configurable segment-importance weights and maps features back to the BCM capability model. Phase 4 (Map) hands unmapped features off to the `bcm-writer` bundle via `bcm:outline` issues. Phase 5 (Followup) hands the vendor company and primary-attribution founders/leaders off to the `company-profile` and `people-profile` bundles via `company:research` and `people:research` issues.",
@@ -24553,8 +24685,11 @@ function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS) {
24553
24685
  tags: ["workflow"]
24554
24686
  }
24555
24687
  ],
24556
- skills: [buildProfileSoftwareSkill(paths), buildMapSoftwareSkill(paths)],
24557
- subAgents: [buildSoftwareProfileAnalystSubAgent(paths)],
24688
+ skills: [
24689
+ buildProfileSoftwareSkill(paths, issueDefaults),
24690
+ buildMapSoftwareSkill(paths, issueDefaults)
24691
+ ],
24692
+ subAgents: [buildSoftwareProfileAnalystSubAgent(paths, issueDefaults)],
24558
24693
  labels: [
24559
24694
  {
24560
24695
  name: "type:software-profile",
@@ -24712,7 +24847,8 @@ var STANDARDS_COMPARE_REFERENCE_FILES = [
24712
24847
  content: TEMPLATE_COMPARISON_GRID
24713
24848
  }
24714
24849
  ];
24715
- function buildStandardsResearchAnalystSubAgent(paths) {
24850
+ function buildStandardsResearchAnalystSubAgent(paths, issueDefaults) {
24851
+ void issueDefaults;
24716
24852
  return {
24717
24853
  name: "standards-research-analyst",
24718
24854
  description: "Authors version-aware interoperability standards research through a 5-phase pipeline (scope \u2192 research \u2192 compare \u2192 extension \u2192 organizations). Researches one standard version per session, synthesizes cross-version comparisons, profiles extensions/profiles/implementation guides, and profiles standards-body organizations. Hands off canonical company and people profiles to the company-profile and people-profile bundles via company:research and people:research issues. One phase per session, tracked by standards:* GitHub issue labels with filesystem-based durability between phases.",
@@ -25499,7 +25635,7 @@ function buildStandardsResearchAnalystSubAgent(paths) {
25499
25635
  ].join("\n")
25500
25636
  };
25501
25637
  }
25502
- function buildScopeStandardsResearchSkill(paths) {
25638
+ function buildScopeStandardsResearchSkill(paths, issueDefaults) {
25503
25639
  return {
25504
25640
  name: "scope-standards-research",
25505
25641
  description: "Kick off the scope phase of an interoperability-standards research campaign. Creates a standards:scope issue for the supplied standard and dispatches Phase 1 of the standards-research-analyst, which writes a query plan and creates downstream standards:research, standards:compare, and standards:organizations issues.",
@@ -25546,7 +25682,7 @@ function buildScopeStandardsResearchSkill(paths) {
25546
25682
  "## Steps",
25547
25683
  "",
25548
25684
  "1. Create a `standards:scope` issue with `type:standards-research`,",
25549
- " `priority:medium`, and `status:ready`. The body must include the",
25685
+ ` \`priority:${labelsForPhase(issueDefaults, "standards:scope").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:scope").status}\`. The body must include the`,
25550
25686
  " standard slug, the list of target versions (or a request to",
25551
25687
  " enumerate), and any known governance bodies.",
25552
25688
  "2. Execute Phase 1 (Scope) of the standards-research-analyst agent.",
@@ -25565,7 +25701,7 @@ function buildScopeStandardsResearchSkill(paths) {
25565
25701
  ].join("\n")
25566
25702
  };
25567
25703
  }
25568
- function buildResearchStandardSkill(paths) {
25704
+ function buildResearchStandardSkill(paths, issueDefaults) {
25569
25705
  return {
25570
25706
  name: "research-standard",
25571
25707
  description: "Kick off the research phase for one version of an interoperability standard. Creates a standards:research issue for the supplied standard and version and dispatches Phase 2 of the standards-research-analyst, which populates the version page with status, key changes, resources, adoption, and governance touch-points.",
@@ -25611,7 +25747,7 @@ function buildResearchStandardSkill(paths) {
25611
25747
  "## Steps",
25612
25748
  "",
25613
25749
  "1. Create a `standards:research` issue with",
25614
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25750
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:research").status}\`.`,
25615
25751
  " The body must include the standard slug and the version slug.",
25616
25752
  "2. Execute Phase 2 (Research) of the standards-research-analyst",
25617
25753
  " agent. The agent runs 6\u201310 targeted web searches and populates",
@@ -25630,7 +25766,7 @@ function buildResearchStandardSkill(paths) {
25630
25766
  ].join("\n")
25631
25767
  };
25632
25768
  }
25633
- function buildCompareStandardsSkill(paths) {
25769
+ function buildCompareStandardsSkill(paths, issueDefaults) {
25634
25770
  return {
25635
25771
  name: "compare-standards",
25636
25772
  description: "Kick off the compare phase across researched versions of an interoperability standard. Creates a standards:compare issue for the supplied standard and dispatches Phase 3 of the standards-research-analyst, which synthesizes the overview page using the ship-with comparison-grid template.",
@@ -25683,7 +25819,7 @@ function buildCompareStandardsSkill(paths) {
25683
25819
  "## Steps",
25684
25820
  "",
25685
25821
  "1. Create a `standards:compare` issue with",
25686
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25822
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:compare").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:compare").status}\`.`,
25687
25823
  " Body must include the standard slug and the list of version",
25688
25824
  " pages under comparison.",
25689
25825
  "2. Execute Phase 3 (Compare) of the standards-research-analyst",
@@ -25700,7 +25836,7 @@ function buildCompareStandardsSkill(paths) {
25700
25836
  ].join("\n")
25701
25837
  };
25702
25838
  }
25703
- function buildExtensionStandardSkill(paths) {
25839
+ function buildExtensionStandardSkill(paths, issueDefaults) {
25704
25840
  return {
25705
25841
  name: "extension-standard",
25706
25842
  description: "Kick off the extension phase for one domain entity against an interoperability standard. Creates a standards:extension issue for the supplied standard and domain entity and dispatches Phase 4 of the standards-research-analyst, which analyzes the gap and hands off a Proposed ADR to the requirements pipeline.",
@@ -25750,7 +25886,7 @@ function buildExtensionStandardSkill(paths) {
25750
25886
  "## Steps",
25751
25887
  "",
25752
25888
  "1. Create a `standards:extension` issue with",
25753
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25889
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:extension").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:extension").status}\`.`,
25754
25890
  " The body must include the standard slug, the entity slug, the",
25755
25891
  " closest resource, and a link to the source BCM or canvas",
25756
25892
  " document.",
@@ -25770,7 +25906,7 @@ function buildExtensionStandardSkill(paths) {
25770
25906
  ].join("\n")
25771
25907
  };
25772
25908
  }
25773
- function buildOrganizationsStandardSkill(paths) {
25909
+ function buildOrganizationsStandardSkill(paths, issueDefaults) {
25774
25910
  return {
25775
25911
  name: "organizations-standard",
25776
25912
  description: "Kick off the organizations phase for one standards-body organization. Creates a standards:organizations issue for the supplied standard and organization and dispatches Phase 5 of the standards-research-analyst, which writes a standards-organization page and hands off canonical company and people profiles to the company-profile and people-profile bundles.",
@@ -25816,7 +25952,7 @@ function buildOrganizationsStandardSkill(paths) {
25816
25952
  "## Steps",
25817
25953
  "",
25818
25954
  "1. Create a `standards:organizations` issue with",
25819
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25955
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:organizations").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:organizations").status}\`.`,
25820
25956
  " Body must include the standard slug, the organization slug, and",
25821
25957
  " the organization's governance role.",
25822
25958
  "2. Execute Phase 5 (Organizations) of the",
@@ -25837,7 +25973,7 @@ function buildOrganizationsStandardSkill(paths) {
25837
25973
  ].join("\n")
25838
25974
  };
25839
25975
  }
25840
- function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS) {
25976
+ function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
25841
25977
  return {
25842
25978
  name: "standards-research",
25843
25979
  description: "Interoperability-standards research pipeline: scope, research, compare, extension, organizations. 5 phases with standards:* phase labels. Version-aware research, cross-version comparison, extension/profile profiling, and standards-body organization profiling. Hands off canonical profiles to company-profile and people-profile via company:research and people:research issues, extension ADRs to requirements-writer via req:write, and domain-entity mappings to bcm-writer. Enabled by default; domain-neutral; filesystem-durable between phases.",
@@ -25903,13 +26039,13 @@ function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS) {
25903
26039
  }
25904
26040
  ],
25905
26041
  skills: [
25906
- buildScopeStandardsResearchSkill(paths),
25907
- buildResearchStandardSkill(paths),
25908
- buildCompareStandardsSkill(paths),
25909
- buildExtensionStandardSkill(paths),
25910
- buildOrganizationsStandardSkill(paths)
26042
+ buildScopeStandardsResearchSkill(paths, issueDefaults),
26043
+ buildResearchStandardSkill(paths, issueDefaults),
26044
+ buildCompareStandardsSkill(paths, issueDefaults),
26045
+ buildExtensionStandardSkill(paths, issueDefaults),
26046
+ buildOrganizationsStandardSkill(paths, issueDefaults)
25911
26047
  ],
25912
- subAgents: [buildStandardsResearchAnalystSubAgent(paths)],
26048
+ subAgents: [buildStandardsResearchAnalystSubAgent(paths, issueDefaults)],
25913
26049
  labels: [
25914
26050
  {
25915
26051
  name: "type:standards-research",
@@ -27133,7 +27269,7 @@ function renderPriorityRulesSection(rules) {
27133
27269
  }
27134
27270
 
27135
27271
  // src/agent/bundles/index.ts
27136
- function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS) {
27272
+ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
27137
27273
  return [
27138
27274
  buildBaseBundle(paths),
27139
27275
  upstreamConfigulatorDocsBundle,
@@ -27154,15 +27290,15 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS) {
27154
27290
  buildRequirementsWriterBundle(paths),
27155
27291
  buildRequirementsReviewerBundle(paths),
27156
27292
  buildResearchPipelineBundle(paths),
27157
- buildCompanyProfileBundle(paths),
27158
- buildCustomerProfileBundle(paths),
27159
- buildPeopleProfileBundle(paths),
27160
- buildSoftwareProfileBundle(paths),
27161
- buildIndustryDiscoveryBundle(paths),
27293
+ buildCompanyProfileBundle(paths, issueDefaults),
27294
+ buildCustomerProfileBundle(paths, issueDefaults),
27295
+ buildPeopleProfileBundle(paths, issueDefaults),
27296
+ buildSoftwareProfileBundle(paths, issueDefaults),
27297
+ buildIndustryDiscoveryBundle(paths, issueDefaults),
27162
27298
  buildBusinessModelsBundle(paths),
27163
27299
  buildBcmWriterBundle(paths),
27164
- buildStandardsResearchBundle(paths),
27165
- buildRegulatoryResearchBundle(paths),
27300
+ buildStandardsResearchBundle(paths, issueDefaults),
27301
+ buildRegulatoryResearchBundle(paths, issueDefaults),
27166
27302
  buildMaintenanceAuditBundle(paths),
27167
27303
  buildDocsSyncBundle(paths)
27168
27304
  ];
@@ -27201,6 +27337,152 @@ function prefix(rel, entry) {
27201
27337
  return path.posix.join(rel, entry);
27202
27338
  }
27203
27339
 
27340
+ // src/agent/renderers/cursor-renderer.ts
27341
+ var import_projen6 = require("projen");
27342
+ var import_textfile2 = require("projen/lib/textfile");
27343
+ var GENERATED_MARKER = "# ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~";
27344
+ var CursorRenderer = class _CursorRenderer {
27345
+ /**
27346
+ * Render all Cursor configuration files.
27347
+ */
27348
+ static render(component, rules, skills, subAgents, mcpServers, settings) {
27349
+ _CursorRenderer.renderRules(component, rules);
27350
+ _CursorRenderer.renderSkills(component, skills);
27351
+ _CursorRenderer.renderSubAgents(component, subAgents);
27352
+ _CursorRenderer.renderMcpServers(component, mcpServers);
27353
+ _CursorRenderer.renderHooks(component, settings);
27354
+ _CursorRenderer.renderIgnoreFiles(component, settings);
27355
+ }
27356
+ static renderRules(component, rules) {
27357
+ for (const rule of rules) {
27358
+ if (rule.platforms?.cursor?.exclude) continue;
27359
+ const lines = [];
27360
+ const description = rule.platforms?.cursor?.description ?? rule.description;
27361
+ const isAlways = rule.scope === AGENT_RULE_SCOPE.ALWAYS;
27362
+ lines.push("---");
27363
+ lines.push(`description: "${description}"`);
27364
+ lines.push(`alwaysApply: ${isAlways}`);
27365
+ if (!isAlways && rule.filePatterns && rule.filePatterns.length > 0) {
27366
+ lines.push(`path: ${JSON.stringify([...rule.filePatterns])}`);
27367
+ }
27368
+ lines.push("---");
27369
+ lines.push("");
27370
+ lines.push(...rule.content.split("\n"));
27371
+ new import_textfile2.TextFile(component, `.cursor/rules/${rule.name}.mdc`, { lines });
27372
+ }
27373
+ }
27374
+ static renderSkills(component, skills) {
27375
+ for (const skill of skills) {
27376
+ if (skill.platforms?.cursor?.exclude) continue;
27377
+ const lines = [];
27378
+ lines.push("---");
27379
+ lines.push(`name: "${skill.name}"`);
27380
+ lines.push(`description: "${skill.description}"`);
27381
+ if (skill.disableModelInvocation) {
27382
+ lines.push(`disable-model-invocation: true`);
27383
+ }
27384
+ if (skill.userInvocable === false) {
27385
+ lines.push(`user-invocable: false`);
27386
+ }
27387
+ if (skill.context) {
27388
+ lines.push(`context: "${skill.context}"`);
27389
+ }
27390
+ if (skill.agent) {
27391
+ lines.push(`agent: "${skill.agent}"`);
27392
+ }
27393
+ if (skill.shell) {
27394
+ lines.push(`shell: "${skill.shell}"`);
27395
+ }
27396
+ if (skill.allowedTools && skill.allowedTools.length > 0) {
27397
+ lines.push(`allowed-tools:`);
27398
+ for (const tool of skill.allowedTools) {
27399
+ lines.push(` - "${tool}"`);
27400
+ }
27401
+ }
27402
+ lines.push("---");
27403
+ lines.push("");
27404
+ lines.push(...skill.instructions.split("\n"));
27405
+ new import_textfile2.TextFile(component, `.cursor/skills/${skill.name}/SKILL.md`, {
27406
+ lines
27407
+ });
27408
+ if (skill.referenceFiles && skill.referenceFiles.length > 0) {
27409
+ for (const file of skill.referenceFiles) {
27410
+ new import_textfile2.TextFile(component, `.cursor/skills/${skill.name}/${file.path}`, {
27411
+ lines: file.content.split("\n")
27412
+ });
27413
+ }
27414
+ }
27415
+ }
27416
+ }
27417
+ static renderSubAgents(component, subAgents) {
27418
+ for (const agent of subAgents) {
27419
+ if (agent.platforms?.cursor?.exclude) continue;
27420
+ const lines = [];
27421
+ lines.push("---");
27422
+ lines.push(`name: ${agent.name}`);
27423
+ lines.push(`description: >-`);
27424
+ lines.push(` ${agent.description}`);
27425
+ if (agent.platforms?.cursor?.readonly) {
27426
+ lines.push(`readonly: true`);
27427
+ }
27428
+ if (agent.platforms?.cursor?.isBackground) {
27429
+ lines.push(`is_background: true`);
27430
+ }
27431
+ lines.push("---");
27432
+ lines.push("");
27433
+ lines.push(...agent.prompt.split("\n"));
27434
+ new import_textfile2.TextFile(component, `.cursor/agents/${agent.name}.md`, { lines });
27435
+ }
27436
+ }
27437
+ static renderMcpServers(component, mcpServers) {
27438
+ const serverNames = Object.keys(mcpServers);
27439
+ if (serverNames.length === 0) return;
27440
+ const obj = { mcpServers: {} };
27441
+ const servers = obj.mcpServers;
27442
+ for (const [name, config] of Object.entries(mcpServers)) {
27443
+ const server = {};
27444
+ if (config.transport) server.transport = config.transport;
27445
+ if (config.command) server.command = config.command;
27446
+ if (config.args) server.args = [...config.args];
27447
+ if (config.url) server.url = config.url;
27448
+ if (config.headers && Object.keys(config.headers).length > 0) {
27449
+ server.headers = { ...config.headers };
27450
+ }
27451
+ if (config.env) server.env = { ...config.env };
27452
+ servers[name] = server;
27453
+ }
27454
+ new import_projen6.JsonFile(component, ".cursor/mcp.json", { obj });
27455
+ }
27456
+ static renderHooks(component, settings) {
27457
+ if (!settings?.hooks) return;
27458
+ const hooks = {};
27459
+ const hookEntries = settings.hooks;
27460
+ for (const [event, actions] of Object.entries(hookEntries)) {
27461
+ if (actions && actions.length > 0) {
27462
+ hooks[event] = actions.map((h) => ({
27463
+ command: h.command
27464
+ }));
27465
+ }
27466
+ }
27467
+ if (Object.keys(hooks).length === 0) return;
27468
+ new import_projen6.JsonFile(component, ".cursor/hooks.json", {
27469
+ obj: { version: 1, hooks }
27470
+ });
27471
+ }
27472
+ static renderIgnoreFiles(component, settings) {
27473
+ if (settings?.ignorePatterns && settings.ignorePatterns.length > 0) {
27474
+ new import_textfile2.TextFile(component, ".cursorignore", {
27475
+ lines: [GENERATED_MARKER, "", ...settings.ignorePatterns]
27476
+ });
27477
+ }
27478
+ if (settings?.indexingIgnorePatterns && settings.indexingIgnorePatterns.length > 0) {
27479
+ new import_textfile2.TextFile(component, ".cursorindexingignore", {
27480
+ lines: [GENERATED_MARKER, "", ...settings.indexingIgnorePatterns]
27481
+ });
27482
+ }
27483
+ }
27484
+ };
27485
+
27204
27486
  // src/agent/template-resolver.ts
27205
27487
  var FALLBACKS = {
27206
27488
  "repository.owner": "<owner>",
@@ -27256,9 +27538,9 @@ function resolveTemplateVariables(template, metadata) {
27256
27538
  }
27257
27539
 
27258
27540
  // src/agent/renderers/claude-renderer.ts
27259
- var import_projen6 = require("projen");
27260
- var import_textfile2 = require("projen/lib/textfile");
27261
- var GENERATED_MARKER = "<!-- ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~ -->";
27541
+ var import_projen7 = require("projen");
27542
+ var import_textfile3 = require("projen/lib/textfile");
27543
+ var GENERATED_MARKER2 = "<!-- ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~ -->";
27262
27544
  var ClaudeRenderer = class _ClaudeRenderer {
27263
27545
  /**
27264
27546
  * Render all Claude Code configuration files.
@@ -27280,12 +27562,12 @@ var ClaudeRenderer = class _ClaudeRenderer {
27280
27562
  return target === CLAUDE_RULE_TARGET.CLAUDE_MD;
27281
27563
  });
27282
27564
  if (claudeMdRules.length === 0) return;
27283
- const lines = [GENERATED_MARKER, ""];
27565
+ const lines = [GENERATED_MARKER2, ""];
27284
27566
  for (let i = 0; i < claudeMdRules.length; i++) {
27285
27567
  if (i > 0) lines.push("", "---", "");
27286
27568
  lines.push(...claudeMdRules[i].content.split("\n"));
27287
27569
  }
27288
- new import_textfile2.TextFile(component, "CLAUDE.md", { lines });
27570
+ new import_textfile3.TextFile(component, "CLAUDE.md", { lines });
27289
27571
  }
27290
27572
  static renderScopedRules(component, rules) {
27291
27573
  const scopedRules = rules.filter((r) => {
@@ -27305,7 +27587,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27305
27587
  lines.push("");
27306
27588
  }
27307
27589
  lines.push(...rule.content.split("\n"));
27308
- new import_textfile2.TextFile(component, `.claude/rules/${rule.name}.md`, { lines });
27590
+ new import_textfile3.TextFile(component, `.claude/rules/${rule.name}.md`, { lines });
27309
27591
  }
27310
27592
  }
27311
27593
  static renderSettings(component, mcpServers, settings) {
@@ -27430,7 +27712,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27430
27712
  hasContent = true;
27431
27713
  }
27432
27714
  if (!hasContent) return;
27433
- new import_projen6.JsonFile(component, ".claude/settings.json", { obj });
27715
+ new import_projen7.JsonFile(component, ".claude/settings.json", { obj });
27434
27716
  }
27435
27717
  static buildSandboxObj(sandbox) {
27436
27718
  const obj = {};
@@ -27517,12 +27799,12 @@ var ClaudeRenderer = class _ClaudeRenderer {
27517
27799
  lines.push("---");
27518
27800
  lines.push("");
27519
27801
  lines.push(...skill.instructions.split("\n"));
27520
- new import_textfile2.TextFile(component, `.claude/skills/${skill.name}/SKILL.md`, {
27802
+ new import_textfile3.TextFile(component, `.claude/skills/${skill.name}/SKILL.md`, {
27521
27803
  lines
27522
27804
  });
27523
27805
  if (skill.referenceFiles && skill.referenceFiles.length > 0) {
27524
27806
  for (const file of skill.referenceFiles) {
27525
- new import_textfile2.TextFile(component, `.claude/skills/${skill.name}/${file.path}`, {
27807
+ new import_textfile3.TextFile(component, `.claude/skills/${skill.name}/${file.path}`, {
27526
27808
  lines: file.content.split("\n")
27527
27809
  });
27528
27810
  }
@@ -27580,7 +27862,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27580
27862
  lines.push("---");
27581
27863
  lines.push("");
27582
27864
  lines.push(...agent.prompt.split("\n"));
27583
- new import_textfile2.TextFile(component, `.claude/agents/${agent.name}.md`, { lines });
27865
+ new import_textfile3.TextFile(component, `.claude/agents/${agent.name}.md`, { lines });
27584
27866
  }
27585
27867
  }
27586
27868
  static buildMcpServerObj(config) {
@@ -27597,7 +27879,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27597
27879
  }
27598
27880
  static renderProcedures(component, procedures) {
27599
27881
  for (const proc of procedures) {
27600
- new import_textfile2.TextFile(component, `.claude/procedures/${proc.name}`, {
27882
+ new import_textfile3.TextFile(component, `.claude/procedures/${proc.name}`, {
27601
27883
  lines: proc.content.split("\n"),
27602
27884
  executable: true
27603
27885
  });
@@ -27624,152 +27906,6 @@ var CopilotRenderer = class {
27624
27906
  }
27625
27907
  };
27626
27908
 
27627
- // src/agent/renderers/cursor-renderer.ts
27628
- var import_projen7 = require("projen");
27629
- var import_textfile3 = require("projen/lib/textfile");
27630
- var GENERATED_MARKER2 = "# ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~";
27631
- var CursorRenderer = class _CursorRenderer {
27632
- /**
27633
- * Render all Cursor configuration files.
27634
- */
27635
- static render(component, rules, skills, subAgents, mcpServers, settings) {
27636
- _CursorRenderer.renderRules(component, rules);
27637
- _CursorRenderer.renderSkills(component, skills);
27638
- _CursorRenderer.renderSubAgents(component, subAgents);
27639
- _CursorRenderer.renderMcpServers(component, mcpServers);
27640
- _CursorRenderer.renderHooks(component, settings);
27641
- _CursorRenderer.renderIgnoreFiles(component, settings);
27642
- }
27643
- static renderRules(component, rules) {
27644
- for (const rule of rules) {
27645
- if (rule.platforms?.cursor?.exclude) continue;
27646
- const lines = [];
27647
- const description = rule.platforms?.cursor?.description ?? rule.description;
27648
- const isAlways = rule.scope === AGENT_RULE_SCOPE.ALWAYS;
27649
- lines.push("---");
27650
- lines.push(`description: "${description}"`);
27651
- lines.push(`alwaysApply: ${isAlways}`);
27652
- if (!isAlways && rule.filePatterns && rule.filePatterns.length > 0) {
27653
- lines.push(`path: ${JSON.stringify([...rule.filePatterns])}`);
27654
- }
27655
- lines.push("---");
27656
- lines.push("");
27657
- lines.push(...rule.content.split("\n"));
27658
- new import_textfile3.TextFile(component, `.cursor/rules/${rule.name}.mdc`, { lines });
27659
- }
27660
- }
27661
- static renderSkills(component, skills) {
27662
- for (const skill of skills) {
27663
- if (skill.platforms?.cursor?.exclude) continue;
27664
- const lines = [];
27665
- lines.push("---");
27666
- lines.push(`name: "${skill.name}"`);
27667
- lines.push(`description: "${skill.description}"`);
27668
- if (skill.disableModelInvocation) {
27669
- lines.push(`disable-model-invocation: true`);
27670
- }
27671
- if (skill.userInvocable === false) {
27672
- lines.push(`user-invocable: false`);
27673
- }
27674
- if (skill.context) {
27675
- lines.push(`context: "${skill.context}"`);
27676
- }
27677
- if (skill.agent) {
27678
- lines.push(`agent: "${skill.agent}"`);
27679
- }
27680
- if (skill.shell) {
27681
- lines.push(`shell: "${skill.shell}"`);
27682
- }
27683
- if (skill.allowedTools && skill.allowedTools.length > 0) {
27684
- lines.push(`allowed-tools:`);
27685
- for (const tool of skill.allowedTools) {
27686
- lines.push(` - "${tool}"`);
27687
- }
27688
- }
27689
- lines.push("---");
27690
- lines.push("");
27691
- lines.push(...skill.instructions.split("\n"));
27692
- new import_textfile3.TextFile(component, `.cursor/skills/${skill.name}/SKILL.md`, {
27693
- lines
27694
- });
27695
- if (skill.referenceFiles && skill.referenceFiles.length > 0) {
27696
- for (const file of skill.referenceFiles) {
27697
- new import_textfile3.TextFile(component, `.cursor/skills/${skill.name}/${file.path}`, {
27698
- lines: file.content.split("\n")
27699
- });
27700
- }
27701
- }
27702
- }
27703
- }
27704
- static renderSubAgents(component, subAgents) {
27705
- for (const agent of subAgents) {
27706
- if (agent.platforms?.cursor?.exclude) continue;
27707
- const lines = [];
27708
- lines.push("---");
27709
- lines.push(`name: ${agent.name}`);
27710
- lines.push(`description: >-`);
27711
- lines.push(` ${agent.description}`);
27712
- if (agent.platforms?.cursor?.readonly) {
27713
- lines.push(`readonly: true`);
27714
- }
27715
- if (agent.platforms?.cursor?.isBackground) {
27716
- lines.push(`is_background: true`);
27717
- }
27718
- lines.push("---");
27719
- lines.push("");
27720
- lines.push(...agent.prompt.split("\n"));
27721
- new import_textfile3.TextFile(component, `.cursor/agents/${agent.name}.md`, { lines });
27722
- }
27723
- }
27724
- static renderMcpServers(component, mcpServers) {
27725
- const serverNames = Object.keys(mcpServers);
27726
- if (serverNames.length === 0) return;
27727
- const obj = { mcpServers: {} };
27728
- const servers = obj.mcpServers;
27729
- for (const [name, config] of Object.entries(mcpServers)) {
27730
- const server = {};
27731
- if (config.transport) server.transport = config.transport;
27732
- if (config.command) server.command = config.command;
27733
- if (config.args) server.args = [...config.args];
27734
- if (config.url) server.url = config.url;
27735
- if (config.headers && Object.keys(config.headers).length > 0) {
27736
- server.headers = { ...config.headers };
27737
- }
27738
- if (config.env) server.env = { ...config.env };
27739
- servers[name] = server;
27740
- }
27741
- new import_projen7.JsonFile(component, ".cursor/mcp.json", { obj });
27742
- }
27743
- static renderHooks(component, settings) {
27744
- if (!settings?.hooks) return;
27745
- const hooks = {};
27746
- const hookEntries = settings.hooks;
27747
- for (const [event, actions] of Object.entries(hookEntries)) {
27748
- if (actions && actions.length > 0) {
27749
- hooks[event] = actions.map((h) => ({
27750
- command: h.command
27751
- }));
27752
- }
27753
- }
27754
- if (Object.keys(hooks).length === 0) return;
27755
- new import_projen7.JsonFile(component, ".cursor/hooks.json", {
27756
- obj: { version: 1, hooks }
27757
- });
27758
- }
27759
- static renderIgnoreFiles(component, settings) {
27760
- if (settings?.ignorePatterns && settings.ignorePatterns.length > 0) {
27761
- new import_textfile3.TextFile(component, ".cursorignore", {
27762
- lines: [GENERATED_MARKER2, "", ...settings.ignorePatterns]
27763
- });
27764
- }
27765
- if (settings?.indexingIgnorePatterns && settings.indexingIgnorePatterns.length > 0) {
27766
- new import_textfile3.TextFile(component, ".cursorindexingignore", {
27767
- lines: [GENERATED_MARKER2, "", ...settings.indexingIgnorePatterns]
27768
- });
27769
- }
27770
- }
27771
- };
27772
-
27773
27909
  // src/agent/agent-config.ts
27774
27910
  var DEFAULT_CLAUDE_ALLOW = [
27775
27911
  // ── Git ──────────────────────────────────────────────────────────────
@@ -27995,7 +28131,10 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
27995
28131
  */
27996
28132
  get pathAwareBundles() {
27997
28133
  if (!this.cachedBundles) {
27998
- this.cachedBundles = buildBuiltInBundles(this.resolvedPaths);
28134
+ this.cachedBundles = buildBuiltInBundles(
28135
+ this.resolvedPaths,
28136
+ resolveIssueDefaults(this.options.issueDefaults)
28137
+ );
27999
28138
  }
28000
28139
  return this.cachedBundles;
28001
28140
  }
@@ -28041,6 +28180,7 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
28041
28180
  this.project.gitignore.addPatterns(`/${resolvedRunRatio.stateFilePath}`);
28042
28181
  }
28043
28182
  validateUnblockDependentsConfig(this.options.unblockDependents);
28183
+ validateIssueDefaultsConfig(this.options.issueDefaults);
28044
28184
  const resolvedProgressFiles = validateProgressFilesConfig(
28045
28185
  this.options.progressFiles
28046
28186
  );
@@ -32916,6 +33056,8 @@ var TypeScriptConfig = class extends import_projen23.Component {
32916
33056
  DEFAULT_DISPATCH_MODEL,
32917
33057
  DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
32918
33058
  DEFAULT_HOUSEKEEPING_MODEL,
33059
+ DEFAULT_ISSUE_PRIORITY,
33060
+ DEFAULT_ISSUE_STATUS,
32919
33061
  DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS,
32920
33062
  DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER,
32921
33063
  DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER,
@@ -32932,6 +33074,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
32932
33074
  DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
32933
33075
  DEFAULT_PROGRESS_FILES_STATE_DIR,
32934
33076
  DEFAULT_REQUIRE_PRODUCT_CONTEXT,
33077
+ DEFAULT_RESOLVED_ISSUE_DEFAULTS,
32935
33078
  DEFAULT_SAMPLE_COMPILER_OPTIONS,
32936
33079
  DEFAULT_SCHEDULED_TASKS_ROOT,
32937
33080
  DEFAULT_SCHEDULED_TASK_ENTRIES,
@@ -32983,6 +33126,8 @@ var TypeScriptConfig = class extends import_projen23.Component {
32983
33126
  TypeScriptConfig,
32984
33127
  TypeScriptProject,
32985
33128
  UNKNOWN_TYPE_FALLBACK_TIER,
33129
+ VALID_PRIORITY_VALUES,
33130
+ VALID_STATUS_VALUES,
32986
33131
  VERSION,
32987
33132
  VERSION_KEYS_SKIP,
32988
33133
  VERSION_NPM_PACKAGES,
@@ -33041,6 +33186,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
33041
33186
  githubWorkflowBundle,
33042
33187
  industryDiscoveryBundle,
33043
33188
  jestBundle,
33189
+ labelsForPhase,
33044
33190
  maintenanceAuditBundle,
33045
33191
  meetingAnalysisBundle,
33046
33192
  orchestratorBundle,
@@ -33094,6 +33240,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
33094
33240
  resolveAgentTiers,
33095
33241
  resolveAstroProjectOutdir,
33096
33242
  resolveAwsCdkProjectOutdir,
33243
+ resolveIssueDefaults,
33097
33244
  resolveIssueTemplates,
33098
33245
  resolveModelAlias,
33099
33246
  resolveOrchestratorAssets,
@@ -33117,6 +33264,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
33117
33264
  typescriptBundle,
33118
33265
  upstreamConfigulatorDocsBundle,
33119
33266
  validateAgentTierConfig,
33267
+ validateIssueDefaultsConfig,
33120
33268
  validateIssueTemplatesConfig,
33121
33269
  validateMonorepoLayout,
33122
33270
  validateProgressFilesConfig,