@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.d.mts +189 -9
- package/lib/index.d.ts +190 -10
- package/lib/index.js +521 -373
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +513 -373
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -3648,8 +3648,21 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
3648
3648
|
"| `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. |",
|
|
3649
3649
|
"| `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. |",
|
|
3650
3650
|
"| `status:needs-attention` | Automated triage has flagged the issue for human review (stale, failed worker, or ambiguous state). Humans reset this label manually. |",
|
|
3651
|
+
"| `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. |",
|
|
3651
3652
|
"| `status:done` | The change has shipped. Set when the PR merges and the issue closes. |",
|
|
3652
3653
|
"",
|
|
3654
|
+
"### Configurable filing-site defaults",
|
|
3655
|
+
"",
|
|
3656
|
+
"The bundle-shipped `gh issue create` recipes default to",
|
|
3657
|
+
"`status:ready` + `priority:medium`. Consumers can override the",
|
|
3658
|
+
"defaults per-phase-label via",
|
|
3659
|
+
"`AgentConfigOptions.issueDefaults` \u2014 e.g. flip every",
|
|
3660
|
+
"`people:research` filing to `status:deferred` + `priority:low`",
|
|
3661
|
+
"without touching the bundle source. See the **`issueDefaults`**",
|
|
3662
|
+
"section in the configulator agent-config docs for the full",
|
|
3663
|
+
"schema and consumer example. `status:deferred` is a valid",
|
|
3664
|
+
"override value reserved for this exact use case.",
|
|
3665
|
+
"",
|
|
3653
3666
|
"### Blocking Rules",
|
|
3654
3667
|
"",
|
|
3655
3668
|
"Two rules force `status:blocked` \u2014 both are non-negotiable:",
|
|
@@ -5719,8 +5732,92 @@ function buildBusinessModelsBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5719
5732
|
}
|
|
5720
5733
|
var businessModelsBundle = buildBusinessModelsBundle();
|
|
5721
5734
|
|
|
5735
|
+
// src/agent/bundles/issue-defaults.ts
|
|
5736
|
+
var VALID_STATUS_VALUES = [
|
|
5737
|
+
"ready",
|
|
5738
|
+
"blocked",
|
|
5739
|
+
"in-progress",
|
|
5740
|
+
"ready-for-review",
|
|
5741
|
+
"needs-attention",
|
|
5742
|
+
"done",
|
|
5743
|
+
"deferred"
|
|
5744
|
+
];
|
|
5745
|
+
var VALID_PRIORITY_VALUES = [
|
|
5746
|
+
"critical",
|
|
5747
|
+
"high",
|
|
5748
|
+
"medium",
|
|
5749
|
+
"low",
|
|
5750
|
+
"trivial"
|
|
5751
|
+
];
|
|
5752
|
+
var DEFAULT_ISSUE_STATUS = "ready";
|
|
5753
|
+
var DEFAULT_ISSUE_PRIORITY = "medium";
|
|
5754
|
+
var DEFAULT_RESOLVED_ISSUE_DEFAULTS = {
|
|
5755
|
+
defaults: {
|
|
5756
|
+
status: DEFAULT_ISSUE_STATUS,
|
|
5757
|
+
priority: DEFAULT_ISSUE_PRIORITY
|
|
5758
|
+
},
|
|
5759
|
+
overrides: {}
|
|
5760
|
+
};
|
|
5761
|
+
function resolveIssueDefaults(config) {
|
|
5762
|
+
if (config === void 0) {
|
|
5763
|
+
return DEFAULT_RESOLVED_ISSUE_DEFAULTS;
|
|
5764
|
+
}
|
|
5765
|
+
const overrides = {};
|
|
5766
|
+
for (const [phaseLabel, override] of Object.entries(config)) {
|
|
5767
|
+
assertValidPhaseLabel(phaseLabel);
|
|
5768
|
+
assertValidOverride(phaseLabel, override);
|
|
5769
|
+
overrides[phaseLabel] = {
|
|
5770
|
+
status: override.status ?? DEFAULT_ISSUE_STATUS,
|
|
5771
|
+
priority: override.priority ?? DEFAULT_ISSUE_PRIORITY
|
|
5772
|
+
};
|
|
5773
|
+
}
|
|
5774
|
+
return {
|
|
5775
|
+
defaults: {
|
|
5776
|
+
status: DEFAULT_ISSUE_STATUS,
|
|
5777
|
+
priority: DEFAULT_ISSUE_PRIORITY
|
|
5778
|
+
},
|
|
5779
|
+
overrides
|
|
5780
|
+
};
|
|
5781
|
+
}
|
|
5782
|
+
function validateIssueDefaultsConfig(config) {
|
|
5783
|
+
return resolveIssueDefaults(config);
|
|
5784
|
+
}
|
|
5785
|
+
function labelsForPhase(resolved, phaseLabel) {
|
|
5786
|
+
return resolved.overrides[phaseLabel] ?? resolved.defaults;
|
|
5787
|
+
}
|
|
5788
|
+
function assertValidPhaseLabel(phaseLabel) {
|
|
5789
|
+
if (typeof phaseLabel !== "string" || phaseLabel.trim() === "") {
|
|
5790
|
+
throw new Error(
|
|
5791
|
+
"AgentConfigOptions.issueDefaults: phase-label keys must be non-empty strings (e.g. `people:research`)."
|
|
5792
|
+
);
|
|
5793
|
+
}
|
|
5794
|
+
}
|
|
5795
|
+
function assertValidOverride(phaseLabel, override) {
|
|
5796
|
+
if (override === null || typeof override !== "object" || Array.isArray(override)) {
|
|
5797
|
+
throw new Error(
|
|
5798
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"] must be an object with optional \`status\` and \`priority\` fields.`
|
|
5799
|
+
);
|
|
5800
|
+
}
|
|
5801
|
+
const { status, priority } = override;
|
|
5802
|
+
if (status === void 0 && priority === void 0) {
|
|
5803
|
+
throw new Error(
|
|
5804
|
+
`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.`
|
|
5805
|
+
);
|
|
5806
|
+
}
|
|
5807
|
+
if (status !== void 0 && !VALID_STATUS_VALUES.includes(status)) {
|
|
5808
|
+
throw new Error(
|
|
5809
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"].status="${status}" is not a recognised status value. Allowed values: ${VALID_STATUS_VALUES.join(", ")}.`
|
|
5810
|
+
);
|
|
5811
|
+
}
|
|
5812
|
+
if (priority !== void 0 && !VALID_PRIORITY_VALUES.includes(priority)) {
|
|
5813
|
+
throw new Error(
|
|
5814
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"].priority="${priority}" is not a recognised priority value. Allowed values: ${VALID_PRIORITY_VALUES.join(", ")}.`
|
|
5815
|
+
);
|
|
5816
|
+
}
|
|
5817
|
+
}
|
|
5818
|
+
|
|
5722
5819
|
// src/agent/bundles/company-profile.ts
|
|
5723
|
-
function buildCompanyProfileAnalystSubAgent(paths) {
|
|
5820
|
+
function buildCompanyProfileAnalystSubAgent(paths, issueDefaults) {
|
|
5724
5821
|
return {
|
|
5725
5822
|
name: "company-profile-analyst",
|
|
5726
5823
|
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.",
|
|
@@ -6130,8 +6227,8 @@ function buildCompanyProfileAnalystSubAgent(paths) {
|
|
|
6130
6227
|
"",
|
|
6131
6228
|
" - `type:people-profile`",
|
|
6132
6229
|
" - `people:research`",
|
|
6133
|
-
|
|
6134
|
-
|
|
6230
|
+
` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
|
|
6231
|
+
` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
|
|
6135
6232
|
"",
|
|
6136
6233
|
" The issue body must include:",
|
|
6137
6234
|
" - A **discovery source** line naming this company profile",
|
|
@@ -6147,8 +6244,8 @@ function buildCompanyProfileAnalystSubAgent(paths) {
|
|
|
6147
6244
|
"",
|
|
6148
6245
|
" - `type:software-profile`",
|
|
6149
6246
|
" - `software:research`",
|
|
6150
|
-
|
|
6151
|
-
|
|
6247
|
+
` - \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\``,
|
|
6248
|
+
` - \`status:${labelsForPhase(issueDefaults, "software:research").status}\``,
|
|
6152
6249
|
"",
|
|
6153
6250
|
" The issue body must include:",
|
|
6154
6251
|
" - A **discovery source** line naming this company profile",
|
|
@@ -6589,47 +6686,52 @@ function buildCompanyProfileAnalystSubAgent(paths) {
|
|
|
6589
6686
|
].join("\n")
|
|
6590
6687
|
};
|
|
6591
6688
|
}
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6689
|
+
function buildProfileCompanyEvalsJson(issueDefaults) {
|
|
6690
|
+
const research = labelsForPhase(issueDefaults, "company:research");
|
|
6691
|
+
return JSON.stringify(
|
|
6692
|
+
{
|
|
6693
|
+
skill_name: "profile-company",
|
|
6694
|
+
evals: [
|
|
6695
|
+
{
|
|
6696
|
+
id: 1,
|
|
6697
|
+
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.",
|
|
6698
|
+
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.`,
|
|
6699
|
+
files: [],
|
|
6700
|
+
product_context_refs: [
|
|
6701
|
+
"Mission",
|
|
6702
|
+
"Domain Vocabulary",
|
|
6703
|
+
"In-Scope Capabilities"
|
|
6704
|
+
]
|
|
6705
|
+
},
|
|
6706
|
+
{
|
|
6707
|
+
id: 2,
|
|
6708
|
+
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.",
|
|
6709
|
+
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.",
|
|
6710
|
+
files: [],
|
|
6711
|
+
product_context_refs: ["Domain Vocabulary"]
|
|
6712
|
+
},
|
|
6713
|
+
{
|
|
6714
|
+
id: 3,
|
|
6715
|
+
prompt: "/profile-company Acme Registration \u2014 we already have a profile for them but it's nine months old. Refresh it.",
|
|
6716
|
+
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.",
|
|
6717
|
+
files: [],
|
|
6718
|
+
product_context_refs: ["Domain Vocabulary"]
|
|
6719
|
+
}
|
|
6720
|
+
]
|
|
6721
|
+
},
|
|
6722
|
+
null,
|
|
6723
|
+
2
|
|
6724
|
+
);
|
|
6725
|
+
}
|
|
6726
|
+
function buildProfileCompanyReferenceFiles(issueDefaults) {
|
|
6727
|
+
return [
|
|
6728
|
+
{
|
|
6729
|
+
path: "evals/evals.json",
|
|
6730
|
+
content: buildProfileCompanyEvalsJson(issueDefaults)
|
|
6731
|
+
}
|
|
6732
|
+
];
|
|
6733
|
+
}
|
|
6734
|
+
function buildProfileCompanySkill(paths, issueDefaults) {
|
|
6633
6735
|
return {
|
|
6634
6736
|
name: "profile-company",
|
|
6635
6737
|
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.",
|
|
@@ -6638,7 +6740,7 @@ function buildProfileCompanySkill(paths) {
|
|
|
6638
6740
|
context: "fork",
|
|
6639
6741
|
agent: "company-profile-analyst",
|
|
6640
6742
|
platforms: { cursor: { exclude: true } },
|
|
6641
|
-
referenceFiles:
|
|
6743
|
+
referenceFiles: buildProfileCompanyReferenceFiles(issueDefaults),
|
|
6642
6744
|
instructions: [
|
|
6643
6745
|
"# Profile Company",
|
|
6644
6746
|
"",
|
|
@@ -6669,7 +6771,7 @@ function buildProfileCompanySkill(paths) {
|
|
|
6669
6771
|
"## Steps",
|
|
6670
6772
|
"",
|
|
6671
6773
|
"1. Create a `company:research` issue with `type:company-profile`,",
|
|
6672
|
-
|
|
6774
|
+
` \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:research").status}\`. Body must include the`,
|
|
6673
6775
|
" company name, selected type, framing, and any overrides.",
|
|
6674
6776
|
"2. Execute Phase 1 (Research) of the company-profile-analyst agent.",
|
|
6675
6777
|
"3. Phase 1 creates the `company:draft` issue. Phase 2 may create a",
|
|
@@ -6693,7 +6795,7 @@ function buildProfileCompanySkill(paths) {
|
|
|
6693
6795
|
].join("\n")
|
|
6694
6796
|
};
|
|
6695
6797
|
}
|
|
6696
|
-
function buildMatchCompanySkill(paths) {
|
|
6798
|
+
function buildMatchCompanySkill(paths, issueDefaults) {
|
|
6697
6799
|
return {
|
|
6698
6800
|
name: "match-company",
|
|
6699
6801
|
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.",
|
|
@@ -6743,7 +6845,7 @@ function buildMatchCompanySkill(paths) {
|
|
|
6743
6845
|
"## Steps",
|
|
6744
6846
|
"",
|
|
6745
6847
|
"1. Create a `company:match` issue with `type:company-profile`,",
|
|
6746
|
-
|
|
6848
|
+
` \`priority:${labelsForPhase(issueDefaults, "company:match").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:match").status}\`. Body must include the`,
|
|
6747
6849
|
" profile path and any overrides.",
|
|
6748
6850
|
"2. Execute Phase 4 (Match) of the company-profile-analyst agent.",
|
|
6749
6851
|
"",
|
|
@@ -6758,7 +6860,7 @@ function buildMatchCompanySkill(paths) {
|
|
|
6758
6860
|
].join("\n")
|
|
6759
6861
|
};
|
|
6760
6862
|
}
|
|
6761
|
-
function buildRefreshCompanySkill(paths) {
|
|
6863
|
+
function buildRefreshCompanySkill(paths, issueDefaults) {
|
|
6762
6864
|
return {
|
|
6763
6865
|
name: "refresh-company",
|
|
6764
6866
|
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.",
|
|
@@ -6816,7 +6918,7 @@ function buildRefreshCompanySkill(paths) {
|
|
|
6816
6918
|
"## Steps",
|
|
6817
6919
|
"",
|
|
6818
6920
|
"1. Create a `company:refresh` issue with `type:company-profile`,",
|
|
6819
|
-
|
|
6921
|
+
` \`priority:${labelsForPhase(issueDefaults, "company:refresh").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:refresh").status}\`. Body must include the`,
|
|
6820
6922
|
" profile path and any overrides.",
|
|
6821
6923
|
"2. Execute Phase 5 (Refresh) of the company-profile-analyst agent.",
|
|
6822
6924
|
"",
|
|
@@ -6832,7 +6934,7 @@ function buildRefreshCompanySkill(paths) {
|
|
|
6832
6934
|
].join("\n")
|
|
6833
6935
|
};
|
|
6834
6936
|
}
|
|
6835
|
-
function buildAnalyzeSegmentSkill(paths) {
|
|
6937
|
+
function buildAnalyzeSegmentSkill(paths, issueDefaults) {
|
|
6836
6938
|
return {
|
|
6837
6939
|
name: "analyze-segment",
|
|
6838
6940
|
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.",
|
|
@@ -6889,7 +6991,7 @@ function buildAnalyzeSegmentSkill(paths) {
|
|
|
6889
6991
|
"## Steps",
|
|
6890
6992
|
"",
|
|
6891
6993
|
"1. Create a `company:analyze` issue with `type:company-profile`,",
|
|
6892
|
-
|
|
6994
|
+
` \`priority:${labelsForPhase(issueDefaults, "company:analyze").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:analyze").status}\`. Body must include the`,
|
|
6893
6995
|
" segment slug and any overrides.",
|
|
6894
6996
|
"2. Execute Phase 6 (Analyze) of the company-profile-analyst agent.",
|
|
6895
6997
|
"",
|
|
@@ -6906,7 +7008,7 @@ function buildAnalyzeSegmentSkill(paths) {
|
|
|
6906
7008
|
].join("\n")
|
|
6907
7009
|
};
|
|
6908
7010
|
}
|
|
6909
|
-
function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
7011
|
+
function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
6910
7012
|
return {
|
|
6911
7013
|
name: "company-profile",
|
|
6912
7014
|
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.",
|
|
@@ -6959,12 +7061,12 @@ function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
6959
7061
|
}
|
|
6960
7062
|
],
|
|
6961
7063
|
skills: [
|
|
6962
|
-
buildProfileCompanySkill(paths),
|
|
6963
|
-
buildMatchCompanySkill(paths),
|
|
6964
|
-
buildRefreshCompanySkill(paths),
|
|
6965
|
-
buildAnalyzeSegmentSkill(paths)
|
|
7064
|
+
buildProfileCompanySkill(paths, issueDefaults),
|
|
7065
|
+
buildMatchCompanySkill(paths, issueDefaults),
|
|
7066
|
+
buildRefreshCompanySkill(paths, issueDefaults),
|
|
7067
|
+
buildAnalyzeSegmentSkill(paths, issueDefaults)
|
|
6966
7068
|
],
|
|
6967
|
-
subAgents: [buildCompanyProfileAnalystSubAgent(paths)],
|
|
7069
|
+
subAgents: [buildCompanyProfileAnalystSubAgent(paths, issueDefaults)],
|
|
6968
7070
|
labels: [
|
|
6969
7071
|
{
|
|
6970
7072
|
name: "type:company-profile",
|
|
@@ -7144,7 +7246,8 @@ var CUSTOMER_PROFILE_REFERENCE_FILES = [
|
|
|
7144
7246
|
content: TEMPLATE_CUSTOMER_PROFILE
|
|
7145
7247
|
}
|
|
7146
7248
|
];
|
|
7147
|
-
function buildCustomerProfileAnalystSubAgent(paths) {
|
|
7249
|
+
function buildCustomerProfileAnalystSubAgent(paths, issueDefaults) {
|
|
7250
|
+
void issueDefaults;
|
|
7148
7251
|
return {
|
|
7149
7252
|
name: "customer-profile-analyst",
|
|
7150
7253
|
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.",
|
|
@@ -7727,7 +7830,7 @@ function buildCustomerProfileAnalystSubAgent(paths) {
|
|
|
7727
7830
|
].join("\n")
|
|
7728
7831
|
};
|
|
7729
7832
|
}
|
|
7730
|
-
function buildDiscoverCustomersSkill(paths) {
|
|
7833
|
+
function buildDiscoverCustomersSkill(paths, issueDefaults) {
|
|
7731
7834
|
return {
|
|
7732
7835
|
name: "discover-customers",
|
|
7733
7836
|
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.",
|
|
@@ -7769,7 +7872,7 @@ function buildDiscoverCustomersSkill(paths) {
|
|
|
7769
7872
|
"## Steps",
|
|
7770
7873
|
"",
|
|
7771
7874
|
"1. Create a `customer:discover` issue with `type:customer-profile`,",
|
|
7772
|
-
|
|
7875
|
+
` \`priority:${labelsForPhase(issueDefaults, "customer:discover").priority}\`, and \`status:${labelsForPhase(issueDefaults, "customer:discover").status}\`. The body must include the`,
|
|
7773
7876
|
" scope slug and any known archetypes to include or exclude.",
|
|
7774
7877
|
"2. Execute Phase 1 (Discover) of the customer-profile-analyst agent.",
|
|
7775
7878
|
"3. Phase 1 writes the discovery report and creates one",
|
|
@@ -7784,7 +7887,7 @@ function buildDiscoverCustomersSkill(paths) {
|
|
|
7784
7887
|
].join("\n")
|
|
7785
7888
|
};
|
|
7786
7889
|
}
|
|
7787
|
-
function buildProfileCustomerSkill(paths) {
|
|
7890
|
+
function buildProfileCustomerSkill(paths, issueDefaults) {
|
|
7788
7891
|
return {
|
|
7789
7892
|
name: "profile-customer",
|
|
7790
7893
|
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.",
|
|
@@ -7844,7 +7947,7 @@ function buildProfileCustomerSkill(paths) {
|
|
|
7844
7947
|
"## Steps",
|
|
7845
7948
|
"",
|
|
7846
7949
|
"1. Create a `customer:profile` issue with `type:customer-profile`,",
|
|
7847
|
-
|
|
7950
|
+
` \`priority:${labelsForPhase(issueDefaults, "customer:profile").priority}\`, and \`status:${labelsForPhase(issueDefaults, "customer:profile").status}\`. The body must include the`,
|
|
7848
7951
|
" archetype slug and (optionally) the segment slug.",
|
|
7849
7952
|
"2. Execute Phase 2 (Profile) of the customer-profile-analyst agent.",
|
|
7850
7953
|
" The agent runs 4\u20138 targeted web searches and populates the",
|
|
@@ -7864,7 +7967,7 @@ function buildProfileCustomerSkill(paths) {
|
|
|
7864
7967
|
].join("\n")
|
|
7865
7968
|
};
|
|
7866
7969
|
}
|
|
7867
|
-
function buildAnalyzeCustomerCompetitorsSkill(paths) {
|
|
7970
|
+
function buildAnalyzeCustomerCompetitorsSkill(paths, issueDefaults) {
|
|
7868
7971
|
return {
|
|
7869
7972
|
name: "analyze-customer-competitors",
|
|
7870
7973
|
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.",
|
|
@@ -7918,8 +8021,8 @@ function buildAnalyzeCustomerCompetitorsSkill(paths) {
|
|
|
7918
8021
|
"## Steps",
|
|
7919
8022
|
"",
|
|
7920
8023
|
"1. Create a `customer:competitors` issue with",
|
|
7921
|
-
|
|
7922
|
-
|
|
8024
|
+
` \`type:customer-profile\`, \`priority:${labelsForPhase(issueDefaults, "customer:competitors").priority}\`, and`,
|
|
8025
|
+
` \`status:${labelsForPhase(issueDefaults, "customer:competitors").status}\` (or \`status:blocked\` when still dependent on a`,
|
|
7923
8026
|
" Phase 2 profile issue). Body must include the archetype page",
|
|
7924
8027
|
" path.",
|
|
7925
8028
|
"2. Execute Phase 3 (Competitors) of the customer-profile-analyst",
|
|
@@ -7944,7 +8047,7 @@ function buildAnalyzeCustomerCompetitorsSkill(paths) {
|
|
|
7944
8047
|
].join("\n")
|
|
7945
8048
|
};
|
|
7946
8049
|
}
|
|
7947
|
-
function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
8050
|
+
function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
7948
8051
|
return {
|
|
7949
8052
|
name: "customer-profile",
|
|
7950
8053
|
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.",
|
|
@@ -8015,11 +8118,11 @@ function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
8015
8118
|
}
|
|
8016
8119
|
],
|
|
8017
8120
|
skills: [
|
|
8018
|
-
buildDiscoverCustomersSkill(paths),
|
|
8019
|
-
buildProfileCustomerSkill(paths),
|
|
8020
|
-
buildAnalyzeCustomerCompetitorsSkill(paths)
|
|
8121
|
+
buildDiscoverCustomersSkill(paths, issueDefaults),
|
|
8122
|
+
buildProfileCustomerSkill(paths, issueDefaults),
|
|
8123
|
+
buildAnalyzeCustomerCompetitorsSkill(paths, issueDefaults)
|
|
8021
8124
|
],
|
|
8022
|
-
subAgents: [buildCustomerProfileAnalystSubAgent(paths)],
|
|
8125
|
+
subAgents: [buildCustomerProfileAnalystSubAgent(paths, issueDefaults)],
|
|
8023
8126
|
labels: [
|
|
8024
8127
|
{
|
|
8025
8128
|
name: "type:customer-profile",
|
|
@@ -9225,7 +9328,7 @@ var githubWorkflowBundle = {
|
|
|
9225
9328
|
};
|
|
9226
9329
|
|
|
9227
9330
|
// src/agent/bundles/industry-discovery.ts
|
|
9228
|
-
function buildIndustryDiscoveryAnalystSubAgent(paths) {
|
|
9331
|
+
function buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults) {
|
|
9229
9332
|
return {
|
|
9230
9333
|
name: "industry-discovery-analyst",
|
|
9231
9334
|
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.",
|
|
@@ -9563,8 +9666,8 @@ function buildIndustryDiscoveryAnalystSubAgent(paths) {
|
|
|
9563
9666
|
"4. **Create one `research:scope` issue per cleared vertical.** This",
|
|
9564
9667
|
" assumes the `research-pipeline` bundle is enabled in the consuming",
|
|
9565
9668
|
" project. Each downstream issue should:",
|
|
9566
|
-
|
|
9567
|
-
|
|
9669
|
+
` - Carry \`type:research\`, \`research:scope\`, \`priority:${labelsForPhase(issueDefaults, "research:scope").priority}\`, and`,
|
|
9670
|
+
` \`status:${labelsForPhase(issueDefaults, "research:scope").status}\` labels`,
|
|
9568
9671
|
" - Include the research question framed for the vertical (what the",
|
|
9569
9672
|
" downstream research needs to answer)",
|
|
9570
9673
|
" - Cite the evaluation row that justified advancing the vertical",
|
|
@@ -9615,7 +9718,7 @@ function buildIndustryDiscoveryAnalystSubAgent(paths) {
|
|
|
9615
9718
|
].join("\n")
|
|
9616
9719
|
};
|
|
9617
9720
|
}
|
|
9618
|
-
function buildDiscoverIndustriesSkill(paths) {
|
|
9721
|
+
function buildDiscoverIndustriesSkill(paths, issueDefaults) {
|
|
9619
9722
|
return {
|
|
9620
9723
|
name: "discover-industries",
|
|
9621
9724
|
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.",
|
|
@@ -9657,7 +9760,7 @@ function buildDiscoverIndustriesSkill(paths) {
|
|
|
9657
9760
|
"## Steps",
|
|
9658
9761
|
"",
|
|
9659
9762
|
"1. Create an `industry:discover` issue with `type:industry-discovery`,",
|
|
9660
|
-
|
|
9763
|
+
` \`priority:${labelsForPhase(issueDefaults, "industry:discover").priority}\`, and \`status:${labelsForPhase(issueDefaults, "industry:discover").status}\`. Body must include the`,
|
|
9661
9764
|
" verbatim scope, authorized sources, and any overrides.",
|
|
9662
9765
|
"2. Execute Phase 1 (Discover) of the industry-discovery-analyst",
|
|
9663
9766
|
" agent.",
|
|
@@ -9678,7 +9781,7 @@ function buildDiscoverIndustriesSkill(paths) {
|
|
|
9678
9781
|
].join("\n")
|
|
9679
9782
|
};
|
|
9680
9783
|
}
|
|
9681
|
-
function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
9784
|
+
function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
9682
9785
|
return {
|
|
9683
9786
|
name: "industry-discovery",
|
|
9684
9787
|
description: "Industry-vertical discovery pipeline: discover candidates, evaluate against a fit rubric, plan downstream research. Enabled by default; domain-neutral; filesystem-durable between phases.",
|
|
@@ -9712,8 +9815,8 @@ function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
9712
9815
|
tags: ["workflow"]
|
|
9713
9816
|
}
|
|
9714
9817
|
],
|
|
9715
|
-
skills: [buildDiscoverIndustriesSkill(paths)],
|
|
9716
|
-
subAgents: [buildIndustryDiscoveryAnalystSubAgent(paths)],
|
|
9818
|
+
skills: [buildDiscoverIndustriesSkill(paths, issueDefaults)],
|
|
9819
|
+
subAgents: [buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults)],
|
|
9717
9820
|
labels: [
|
|
9718
9821
|
{
|
|
9719
9822
|
name: "type:industry-discovery",
|
|
@@ -12892,80 +12995,81 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
12892
12995
|
"}",
|
|
12893
12996
|
"",
|
|
12894
12997
|
"cmd_eligible() {",
|
|
12895
|
-
"
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
"",
|
|
12900
|
-
"
|
|
12901
|
-
|
|
12902
|
-
|
|
12903
|
-
|
|
12904
|
-
"
|
|
12905
|
-
"
|
|
12998
|
+
" # Bucketed scan: walk priority levels critical \u2192 high \u2192 medium \u2192 low \u2192",
|
|
12999
|
+
" # trivial, fetching one bucket at a time. The first bucket with at",
|
|
13000
|
+
" # least one survivor (after the Depends-on filter) short-circuits the",
|
|
13001
|
+
" # loop \u2014 lower-priority buckets are never queried in the common case.",
|
|
13002
|
+
" # This guarantees that every higher-priority issue is visible even",
|
|
13003
|
+
" # when the global ready backlog exceeds 50, at the cost of up to one",
|
|
13004
|
+
" # extra `gh issue list` call per empty bucket above the first hit.",
|
|
13005
|
+
" local level",
|
|
13006
|
+
" for level in critical high medium low trivial; do",
|
|
13007
|
+
" local issues",
|
|
13008
|
+
' issues=$(gh issue list --label "status:ready" --label "priority:${level}" --state open \\',
|
|
13009
|
+
' --search "sort:created-asc" \\',
|
|
13010
|
+
' --json number,title,body,labels --limit 50 2>/dev/null || echo "[]")',
|
|
13011
|
+
"",
|
|
13012
|
+
" local count",
|
|
13013
|
+
` count=$(echo "$issues" | jq 'length')`,
|
|
13014
|
+
' if [[ "$count" -eq 0 ]]; then',
|
|
13015
|
+
" continue",
|
|
13016
|
+
" fi",
|
|
12906
13017
|
"",
|
|
12907
|
-
"
|
|
12908
|
-
`
|
|
12909
|
-
"
|
|
12910
|
-
'
|
|
12911
|
-
'
|
|
12912
|
-
'
|
|
12913
|
-
'
|
|
12914
|
-
" ')",
|
|
13018
|
+
" local issue_data",
|
|
13019
|
+
` issue_data=$(echo "$issues" | jq -r '`,
|
|
13020
|
+
" .[] |",
|
|
13021
|
+
' (.body | split("\\n") | map(select(test("Depends on:"; "i"))) | .[0] // "") as $dep_line |',
|
|
13022
|
+
' (.labels | map(.name) | map(select(startswith("type:"))) | .[0] // "") as $type_label |',
|
|
13023
|
+
' "\\(.number)\\t\\(.title)\\t\\($dep_line)\\t\\($type_label)"',
|
|
13024
|
+
" ')",
|
|
12915
13025
|
"",
|
|
12916
|
-
'
|
|
12917
|
-
"
|
|
12918
|
-
'
|
|
13026
|
+
' local results=""',
|
|
13027
|
+
" while IFS=$'\\t' read -r num title dep_line type_label; do",
|
|
13028
|
+
' [[ -z "$num" ]] && continue',
|
|
12919
13029
|
"",
|
|
12920
|
-
'
|
|
12921
|
-
'
|
|
12922
|
-
'
|
|
12923
|
-
"
|
|
13030
|
+
' local deps=""',
|
|
13031
|
+
' if [[ -n "$dep_line" ]]; then',
|
|
13032
|
+
' deps=$(parse_deps "$dep_line")',
|
|
13033
|
+
" fi",
|
|
12924
13034
|
"",
|
|
12925
|
-
"
|
|
12926
|
-
"
|
|
12927
|
-
'
|
|
12928
|
-
'
|
|
12929
|
-
"
|
|
12930
|
-
'
|
|
12931
|
-
"
|
|
12932
|
-
'
|
|
12933
|
-
"
|
|
12934
|
-
"
|
|
12935
|
-
"
|
|
13035
|
+
" # Check if any dep is still open.",
|
|
13036
|
+
" local has_open_dep=false",
|
|
13037
|
+
' local open_deps=""',
|
|
13038
|
+
' if [[ -n "${deps// /}" ]]; then',
|
|
13039
|
+
" for dep in $deps; do",
|
|
13040
|
+
' if ! is_closed "$dep"; then',
|
|
13041
|
+
" has_open_dep=true",
|
|
13042
|
+
' open_deps="${open_deps}#${dep} "',
|
|
13043
|
+
" fi",
|
|
13044
|
+
" done",
|
|
13045
|
+
" fi",
|
|
12936
13046
|
"",
|
|
12937
|
-
"
|
|
12938
|
-
'
|
|
12939
|
-
"
|
|
12940
|
-
"
|
|
13047
|
+
" if $has_open_dep; then",
|
|
13048
|
+
' echo "SKIP #${num} \u2014 dep ${open_deps% } still open"',
|
|
13049
|
+
" continue",
|
|
13050
|
+
" fi",
|
|
12941
13051
|
"",
|
|
12942
|
-
"
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
'
|
|
12946
|
-
' *priority:critical*) priority_key=0; priority="critical" ;;',
|
|
12947
|
-
' *priority:high*) priority_key=1; priority="high" ;;',
|
|
12948
|
-
' *priority:medium*) priority_key=2; priority="medium" ;;',
|
|
12949
|
-
' *priority:low*) priority_key=3; priority="low" ;;',
|
|
12950
|
-
' *priority:trivial*) priority_key=4; priority="trivial" ;;',
|
|
12951
|
-
" esac",
|
|
13052
|
+
" # Funnel-tier sort key (0-4; 0 dispatches first within a bucket).",
|
|
13053
|
+
' local type_value="${type_label#type:}"',
|
|
13054
|
+
" local tier_key",
|
|
13055
|
+
' tier_key=$(tier_of "$type_value")',
|
|
12952
13056
|
"",
|
|
12953
|
-
|
|
12954
|
-
'
|
|
12955
|
-
" local tier_key",
|
|
12956
|
-
' tier_key=$(tier_of "$type_value")',
|
|
13057
|
+
' local label_info=""',
|
|
13058
|
+
' [[ -n "$type_label" ]] && label_info=" ${type_label}"',
|
|
12957
13059
|
"",
|
|
12958
|
-
'
|
|
12959
|
-
'
|
|
13060
|
+
' results="${results}${tier_key}\\t${num}\\tPICK #${num} priority:${level} tier:${tier_key}${label_info} \\"${title}\\"\\n"',
|
|
13061
|
+
' done <<< "$issue_data"',
|
|
12960
13062
|
"",
|
|
12961
|
-
|
|
12962
|
-
|
|
13063
|
+
" # Within this bucket: sort by funnel tier asc \u2192 issue number asc",
|
|
13064
|
+
" # (FIFO). If any PICK lines survived the Depends-on filter, emit",
|
|
13065
|
+
" # them and short-circuit before querying lower-priority buckets.",
|
|
13066
|
+
' if [[ -n "$results" ]]; then',
|
|
13067
|
+
` printf '%b' "$results" | sort -t$'\\t' -k1,1n -k2,2n | cut -f3`,
|
|
13068
|
+
" return 0",
|
|
13069
|
+
" fi",
|
|
13070
|
+
" done",
|
|
12963
13071
|
"",
|
|
12964
|
-
|
|
12965
|
-
" # (asc, lower tier wins on priority tie), then issue number (FIFO).",
|
|
12966
|
-
' if [[ -n "$results" ]]; then',
|
|
12967
|
-
` printf '%b' "$results" | sort -t$'\\t' -k1,1n -k2,2n -k3,3n | cut -f4`,
|
|
12968
|
-
" fi",
|
|
13072
|
+
' echo "NO_READY_ISSUES"',
|
|
12969
13073
|
"}",
|
|
12970
13074
|
"",
|
|
12971
13075
|
"cmd_stale() {",
|
|
@@ -13400,9 +13504,25 @@ var orchestratorSubAgent = {
|
|
|
13400
13504
|
".claude/procedures/check-blocked.sh eligible",
|
|
13401
13505
|
"```",
|
|
13402
13506
|
"",
|
|
13507
|
+
"The script walks the priority buckets **critical \u2192 high \u2192 medium \u2192 low",
|
|
13508
|
+
"\u2192 trivial** in order, querying one bucket at a time and short-circuiting",
|
|
13509
|
+
"on the first non-empty bucket whose survivors clear the `Depends on:`",
|
|
13510
|
+
"filter. Each bucket is fetched with",
|
|
13511
|
+
'`gh issue list --label "status:ready" --label "priority:<level>" --limit 50`,',
|
|
13512
|
+
"so every higher-priority issue is visible even when the global ready",
|
|
13513
|
+
"backlog exceeds 50 \u2014 a `priority:critical` filing can never be hidden",
|
|
13514
|
+
"behind 50 older medium/low issues. The cost in the common case (the",
|
|
13515
|
+
"first bucket the script queries is non-empty) is **one `gh issue list`",
|
|
13516
|
+
"call**, identical to the previous single-fetch implementation; the",
|
|
13517
|
+
"worst case is five calls when every higher-priority bucket is empty",
|
|
13518
|
+
"or fully dep-blocked. Per-priority bucket size is still capped at 50",
|
|
13519
|
+
"issues \u2014 see the **Orchestrator Conventions** section in `CLAUDE.md`.",
|
|
13520
|
+
"",
|
|
13403
13521
|
"The script emits `PICK` lines sorted by **priority desc \u2192 funnel tier asc",
|
|
13404
|
-
"\u2192 issue number asc
|
|
13405
|
-
"
|
|
13522
|
+
"\u2192 issue number asc** (priority order is enforced by the bucket walk;",
|
|
13523
|
+
"the in-bucket sort handles funnel tier and FIFO). Each line carries",
|
|
13524
|
+
"both `priority:<level>` and `tier:<n>` so the sort is legible at a",
|
|
13525
|
+
"glance:",
|
|
13406
13526
|
"",
|
|
13407
13527
|
"```",
|
|
13408
13528
|
'PICK #42 priority:high tier:1 type:research "FHIR extension analysis"',
|
|
@@ -14033,7 +14153,7 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
|
|
|
14033
14153
|
"- 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`).",
|
|
14034
14154
|
"- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
|
|
14035
14155
|
"- 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.",
|
|
14036
|
-
"- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number",
|
|
14156
|
+
"- 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.",
|
|
14037
14157
|
"- Stale thresholds: 72h for in-progress, 168h for blocked",
|
|
14038
14158
|
"- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset",
|
|
14039
14159
|
"",
|
|
@@ -14120,7 +14240,7 @@ var orchestratorBundle = {
|
|
|
14120
14240
|
};
|
|
14121
14241
|
|
|
14122
14242
|
// src/agent/bundles/people-profile.ts
|
|
14123
|
-
function buildPeopleProfileAnalystSubAgent(paths) {
|
|
14243
|
+
function buildPeopleProfileAnalystSubAgent(paths, issueDefaults) {
|
|
14124
14244
|
return {
|
|
14125
14245
|
name: "people-profile-analyst",
|
|
14126
14246
|
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.",
|
|
@@ -14557,8 +14677,8 @@ function buildPeopleProfileAnalystSubAgent(paths) {
|
|
|
14557
14677
|
"",
|
|
14558
14678
|
" - `type:company-profile`",
|
|
14559
14679
|
" - `company:research`",
|
|
14560
|
-
|
|
14561
|
-
|
|
14680
|
+
` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
|
|
14681
|
+
` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
|
|
14562
14682
|
"",
|
|
14563
14683
|
" The issue body must include:",
|
|
14564
14684
|
" - A **discovery source** line naming this person profile",
|
|
@@ -14577,8 +14697,8 @@ function buildPeopleProfileAnalystSubAgent(paths) {
|
|
|
14577
14697
|
"",
|
|
14578
14698
|
" - `type:software-profile`",
|
|
14579
14699
|
" - `software:research`",
|
|
14580
|
-
|
|
14581
|
-
|
|
14700
|
+
` - \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\``,
|
|
14701
|
+
` - \`status:${labelsForPhase(issueDefaults, "software:research").status}\``,
|
|
14582
14702
|
"",
|
|
14583
14703
|
" The issue body must include:",
|
|
14584
14704
|
" - A **discovery source** line naming this person profile",
|
|
@@ -14797,7 +14917,7 @@ function buildPeopleProfileAnalystSubAgent(paths) {
|
|
|
14797
14917
|
].join("\n")
|
|
14798
14918
|
};
|
|
14799
14919
|
}
|
|
14800
|
-
function buildProfilePersonSkill(paths) {
|
|
14920
|
+
function buildProfilePersonSkill(paths, issueDefaults) {
|
|
14801
14921
|
return {
|
|
14802
14922
|
name: "profile-person",
|
|
14803
14923
|
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.",
|
|
@@ -14848,7 +14968,7 @@ function buildProfilePersonSkill(paths) {
|
|
|
14848
14968
|
"## Steps",
|
|
14849
14969
|
"",
|
|
14850
14970
|
"1. Create a `people:research` issue with `type:people-profile`,",
|
|
14851
|
-
|
|
14971
|
+
` \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "people:research").status}\`. Body must include the`,
|
|
14852
14972
|
" person's name, selected role, primary company, framing, and any",
|
|
14853
14973
|
" overrides.",
|
|
14854
14974
|
"2. Execute Phase 1 (Research) of the people-profile-analyst agent.",
|
|
@@ -14873,7 +14993,7 @@ function buildProfilePersonSkill(paths) {
|
|
|
14873
14993
|
].join("\n")
|
|
14874
14994
|
};
|
|
14875
14995
|
}
|
|
14876
|
-
function buildRefreshPersonSkill(paths) {
|
|
14996
|
+
function buildRefreshPersonSkill(paths, issueDefaults) {
|
|
14877
14997
|
return {
|
|
14878
14998
|
name: "refresh-person",
|
|
14879
14999
|
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.",
|
|
@@ -14940,7 +15060,7 @@ function buildRefreshPersonSkill(paths) {
|
|
|
14940
15060
|
"## Steps",
|
|
14941
15061
|
"",
|
|
14942
15062
|
"1. Create a `people:refresh` issue with `type:people-profile`,",
|
|
14943
|
-
|
|
15063
|
+
` \`priority:${labelsForPhase(issueDefaults, "people:refresh").priority}\`, and \`status:${labelsForPhase(issueDefaults, "people:refresh").status}\`. Body must include the`,
|
|
14944
15064
|
" profile path and any overrides.",
|
|
14945
15065
|
"2. Execute Phase 4 (Refresh) of the people-profile-analyst agent.",
|
|
14946
15066
|
"",
|
|
@@ -14954,7 +15074,7 @@ function buildRefreshPersonSkill(paths) {
|
|
|
14954
15074
|
].join("\n")
|
|
14955
15075
|
};
|
|
14956
15076
|
}
|
|
14957
|
-
function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
15077
|
+
function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
14958
15078
|
return {
|
|
14959
15079
|
name: "people-profile",
|
|
14960
15080
|
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.",
|
|
@@ -14998,8 +15118,11 @@ function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
14998
15118
|
tags: ["workflow"]
|
|
14999
15119
|
}
|
|
15000
15120
|
],
|
|
15001
|
-
skills: [
|
|
15002
|
-
|
|
15121
|
+
skills: [
|
|
15122
|
+
buildProfilePersonSkill(paths, issueDefaults),
|
|
15123
|
+
buildRefreshPersonSkill(paths, issueDefaults)
|
|
15124
|
+
],
|
|
15125
|
+
subAgents: [buildPeopleProfileAnalystSubAgent(paths, issueDefaults)],
|
|
15003
15126
|
labels: [
|
|
15004
15127
|
{
|
|
15005
15128
|
name: "type:people-profile",
|
|
@@ -17164,7 +17287,8 @@ var REGULATORY_RESEARCH_REFERENCE_FILES = [
|
|
|
17164
17287
|
content: TEMPLATE_REGULATION
|
|
17165
17288
|
}
|
|
17166
17289
|
];
|
|
17167
|
-
function buildRegulatoryResearchAnalystSubAgent(paths) {
|
|
17290
|
+
function buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults) {
|
|
17291
|
+
void issueDefaults;
|
|
17168
17292
|
return {
|
|
17169
17293
|
name: "regulatory-research-analyst",
|
|
17170
17294
|
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.",
|
|
@@ -17724,7 +17848,7 @@ function buildRegulatoryResearchAnalystSubAgent(paths) {
|
|
|
17724
17848
|
].join("\n")
|
|
17725
17849
|
};
|
|
17726
17850
|
}
|
|
17727
|
-
function buildScanRegulatoryLandscapeSkill(paths) {
|
|
17851
|
+
function buildScanRegulatoryLandscapeSkill(paths, issueDefaults) {
|
|
17728
17852
|
return {
|
|
17729
17853
|
name: "scan-regulatory-landscape",
|
|
17730
17854
|
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.",
|
|
@@ -17771,7 +17895,7 @@ function buildScanRegulatoryLandscapeSkill(paths) {
|
|
|
17771
17895
|
"## Steps",
|
|
17772
17896
|
"",
|
|
17773
17897
|
"1. Create a `regulatory:scan` issue with `type:regulatory-research`,",
|
|
17774
|
-
|
|
17898
|
+
` \`priority:${labelsForPhase(issueDefaults, "regulatory:scan").priority}\`, and \`status:${labelsForPhase(issueDefaults, "regulatory:scan").status}\`. The body must include the`,
|
|
17775
17899
|
" scope slug, the scope type, and any known regulations to include",
|
|
17776
17900
|
" or exclude.",
|
|
17777
17901
|
"2. Execute Phase 1 (Scan) of the regulatory-research-analyst agent.",
|
|
@@ -17788,7 +17912,7 @@ function buildScanRegulatoryLandscapeSkill(paths) {
|
|
|
17788
17912
|
].join("\n")
|
|
17789
17913
|
};
|
|
17790
17914
|
}
|
|
17791
|
-
function buildResearchRegulationSkill(paths) {
|
|
17915
|
+
function buildResearchRegulationSkill(paths, issueDefaults) {
|
|
17792
17916
|
return {
|
|
17793
17917
|
name: "research-regulation",
|
|
17794
17918
|
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.",
|
|
@@ -17847,8 +17971,8 @@ function buildResearchRegulationSkill(paths) {
|
|
|
17847
17971
|
"## Steps",
|
|
17848
17972
|
"",
|
|
17849
17973
|
"1. Create a `regulatory:research` issue with",
|
|
17850
|
-
|
|
17851
|
-
|
|
17974
|
+
` \`type:regulatory-research\`, \`priority:${labelsForPhase(issueDefaults, "regulatory:research").priority}\`, and`,
|
|
17975
|
+
` \`status:${labelsForPhase(issueDefaults, "regulatory:research").status}\`. The body must include the scope slug and the`,
|
|
17852
17976
|
" regulation slug.",
|
|
17853
17977
|
"2. Execute Phase 2 (Research) of the regulatory-research-analyst",
|
|
17854
17978
|
" agent. The agent runs 6\u201312 targeted web searches and populates",
|
|
@@ -17866,7 +17990,7 @@ function buildResearchRegulationSkill(paths) {
|
|
|
17866
17990
|
].join("\n")
|
|
17867
17991
|
};
|
|
17868
17992
|
}
|
|
17869
|
-
function buildImpactRegulationSkill(paths) {
|
|
17993
|
+
function buildImpactRegulationSkill(paths, issueDefaults) {
|
|
17870
17994
|
return {
|
|
17871
17995
|
name: "impact-regulation",
|
|
17872
17996
|
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.",
|
|
@@ -17913,8 +18037,8 @@ function buildImpactRegulationSkill(paths) {
|
|
|
17913
18037
|
"## Steps",
|
|
17914
18038
|
"",
|
|
17915
18039
|
"1. Create a `regulatory:impact` issue with",
|
|
17916
|
-
|
|
17917
|
-
|
|
18040
|
+
` \`type:regulatory-research\`, \`priority:${labelsForPhase(issueDefaults, "regulatory:impact").priority}\`, and`,
|
|
18041
|
+
` \`status:${labelsForPhase(issueDefaults, "regulatory:impact").status}\` (or \`status:blocked\` when still dependent on a`,
|
|
17918
18042
|
" Phase 2 research issue). Body must include the regulation page",
|
|
17919
18043
|
" path.",
|
|
17920
18044
|
"2. Execute Phase 3 (Impact) of the regulatory-research-analyst",
|
|
@@ -17935,7 +18059,7 @@ function buildImpactRegulationSkill(paths) {
|
|
|
17935
18059
|
].join("\n")
|
|
17936
18060
|
};
|
|
17937
18061
|
}
|
|
17938
|
-
function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
18062
|
+
function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
17939
18063
|
return {
|
|
17940
18064
|
name: "regulatory-research",
|
|
17941
18065
|
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.",
|
|
@@ -18002,11 +18126,11 @@ function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
18002
18126
|
}
|
|
18003
18127
|
],
|
|
18004
18128
|
skills: [
|
|
18005
|
-
buildScanRegulatoryLandscapeSkill(paths),
|
|
18006
|
-
buildResearchRegulationSkill(paths),
|
|
18007
|
-
buildImpactRegulationSkill(paths)
|
|
18129
|
+
buildScanRegulatoryLandscapeSkill(paths, issueDefaults),
|
|
18130
|
+
buildResearchRegulationSkill(paths, issueDefaults),
|
|
18131
|
+
buildImpactRegulationSkill(paths, issueDefaults)
|
|
18008
18132
|
],
|
|
18009
|
-
subAgents: [buildRegulatoryResearchAnalystSubAgent(paths)],
|
|
18133
|
+
subAgents: [buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults)],
|
|
18010
18134
|
labels: [
|
|
18011
18135
|
{
|
|
18012
18136
|
name: "type:regulatory-research",
|
|
@@ -23308,7 +23432,7 @@ var slackBundle = {
|
|
|
23308
23432
|
};
|
|
23309
23433
|
|
|
23310
23434
|
// src/agent/bundles/software-profile.ts
|
|
23311
|
-
function buildSoftwareProfileAnalystSubAgent(paths) {
|
|
23435
|
+
function buildSoftwareProfileAnalystSubAgent(paths, issueDefaults) {
|
|
23312
23436
|
return {
|
|
23313
23437
|
name: "software-profile-analyst",
|
|
23314
23438
|
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.",
|
|
@@ -23847,8 +23971,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
|
|
|
23847
23971
|
"",
|
|
23848
23972
|
" - `type:bcm-document`",
|
|
23849
23973
|
" - `bcm:outline`",
|
|
23850
|
-
|
|
23851
|
-
|
|
23974
|
+
` - \`priority:${labelsForPhase(issueDefaults, "bcm:outline").priority}\``,
|
|
23975
|
+
` - \`status:${labelsForPhase(issueDefaults, "bcm:outline").status}\``,
|
|
23852
23976
|
"",
|
|
23853
23977
|
" The issue body must include:",
|
|
23854
23978
|
" - A **discovery source** line naming this software profile",
|
|
@@ -23916,7 +24040,7 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
|
|
|
23916
24040
|
" `Follow-up Candidates > Adjacent products to evaluate`. Each new",
|
|
23917
24041
|
" issue follows the same 4-phase pipeline \u2014 start it in the",
|
|
23918
24042
|
" `software:research` phase with `type:software-profile`,",
|
|
23919
|
-
|
|
24043
|
+
` \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:research").status}\`.`,
|
|
23920
24044
|
"",
|
|
23921
24045
|
"3. **Enqueue a `company:research` issue for the vendor company** if",
|
|
23922
24046
|
" no matching profile already exists under `<COMPANY_PROFILES_DIR>/`.",
|
|
@@ -23927,8 +24051,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
|
|
|
23927
24051
|
"",
|
|
23928
24052
|
" - `type:company-profile`",
|
|
23929
24053
|
" - `company:research`",
|
|
23930
|
-
|
|
23931
|
-
|
|
24054
|
+
` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
|
|
24055
|
+
` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
|
|
23932
24056
|
"",
|
|
23933
24057
|
" The issue body must include:",
|
|
23934
24058
|
" - A **discovery source** line naming this software profile",
|
|
@@ -23946,8 +24070,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
|
|
|
23946
24070
|
"",
|
|
23947
24071
|
" - `type:people-profile`",
|
|
23948
24072
|
" - `people:research`",
|
|
23949
|
-
|
|
23950
|
-
|
|
24073
|
+
` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
|
|
24074
|
+
` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
|
|
23951
24075
|
"",
|
|
23952
24076
|
" The issue body must include:",
|
|
23953
24077
|
" - A **discovery source** line naming this software profile",
|
|
@@ -24090,7 +24214,7 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
|
|
|
24090
24214
|
].join("\n")
|
|
24091
24215
|
};
|
|
24092
24216
|
}
|
|
24093
|
-
function buildProfileSoftwareSkill(paths) {
|
|
24217
|
+
function buildProfileSoftwareSkill(paths, issueDefaults) {
|
|
24094
24218
|
return {
|
|
24095
24219
|
name: "profile-software",
|
|
24096
24220
|
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.",
|
|
@@ -24137,7 +24261,7 @@ function buildProfileSoftwareSkill(paths) {
|
|
|
24137
24261
|
"## Steps",
|
|
24138
24262
|
"",
|
|
24139
24263
|
"1. Create a `software:research` issue with `type:software-profile`,",
|
|
24140
|
-
|
|
24264
|
+
` \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:research").status}\`. Body must include the`,
|
|
24141
24265
|
" product name, selected type, framing, and any overrides.",
|
|
24142
24266
|
"2. Execute Phase 1 (Research) of the software-profile-analyst",
|
|
24143
24267
|
" agent.",
|
|
@@ -24170,7 +24294,7 @@ function buildProfileSoftwareSkill(paths) {
|
|
|
24170
24294
|
].join("\n")
|
|
24171
24295
|
};
|
|
24172
24296
|
}
|
|
24173
|
-
function buildMapSoftwareSkill(paths) {
|
|
24297
|
+
function buildMapSoftwareSkill(paths, issueDefaults) {
|
|
24174
24298
|
return {
|
|
24175
24299
|
name: "map-software",
|
|
24176
24300
|
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.",
|
|
@@ -24225,7 +24349,7 @@ function buildMapSoftwareSkill(paths) {
|
|
|
24225
24349
|
"## Steps",
|
|
24226
24350
|
"",
|
|
24227
24351
|
"1. Create a `software:map` issue with `type:software-profile`,",
|
|
24228
|
-
|
|
24352
|
+
` \`priority:${labelsForPhase(issueDefaults, "software:map").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:map").status}\`. Body must include the`,
|
|
24229
24353
|
" profile path and any overrides.",
|
|
24230
24354
|
"2. Execute Phase 4 (Map) of the software-profile-analyst agent.",
|
|
24231
24355
|
"3. Phase 4 writes the `## Capability Mapping` section, enqueues",
|
|
@@ -24247,7 +24371,7 @@ function buildMapSoftwareSkill(paths) {
|
|
|
24247
24371
|
].join("\n")
|
|
24248
24372
|
};
|
|
24249
24373
|
}
|
|
24250
|
-
function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
24374
|
+
function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
24251
24375
|
return {
|
|
24252
24376
|
name: "software-profile",
|
|
24253
24377
|
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.",
|
|
@@ -24300,8 +24424,11 @@ function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
24300
24424
|
tags: ["workflow"]
|
|
24301
24425
|
}
|
|
24302
24426
|
],
|
|
24303
|
-
skills: [
|
|
24304
|
-
|
|
24427
|
+
skills: [
|
|
24428
|
+
buildProfileSoftwareSkill(paths, issueDefaults),
|
|
24429
|
+
buildMapSoftwareSkill(paths, issueDefaults)
|
|
24430
|
+
],
|
|
24431
|
+
subAgents: [buildSoftwareProfileAnalystSubAgent(paths, issueDefaults)],
|
|
24305
24432
|
labels: [
|
|
24306
24433
|
{
|
|
24307
24434
|
name: "type:software-profile",
|
|
@@ -24459,7 +24586,8 @@ var STANDARDS_COMPARE_REFERENCE_FILES = [
|
|
|
24459
24586
|
content: TEMPLATE_COMPARISON_GRID
|
|
24460
24587
|
}
|
|
24461
24588
|
];
|
|
24462
|
-
function buildStandardsResearchAnalystSubAgent(paths) {
|
|
24589
|
+
function buildStandardsResearchAnalystSubAgent(paths, issueDefaults) {
|
|
24590
|
+
void issueDefaults;
|
|
24463
24591
|
return {
|
|
24464
24592
|
name: "standards-research-analyst",
|
|
24465
24593
|
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.",
|
|
@@ -25246,7 +25374,7 @@ function buildStandardsResearchAnalystSubAgent(paths) {
|
|
|
25246
25374
|
].join("\n")
|
|
25247
25375
|
};
|
|
25248
25376
|
}
|
|
25249
|
-
function buildScopeStandardsResearchSkill(paths) {
|
|
25377
|
+
function buildScopeStandardsResearchSkill(paths, issueDefaults) {
|
|
25250
25378
|
return {
|
|
25251
25379
|
name: "scope-standards-research",
|
|
25252
25380
|
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.",
|
|
@@ -25293,7 +25421,7 @@ function buildScopeStandardsResearchSkill(paths) {
|
|
|
25293
25421
|
"## Steps",
|
|
25294
25422
|
"",
|
|
25295
25423
|
"1. Create a `standards:scope` issue with `type:standards-research`,",
|
|
25296
|
-
|
|
25424
|
+
` \`priority:${labelsForPhase(issueDefaults, "standards:scope").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:scope").status}\`. The body must include the`,
|
|
25297
25425
|
" standard slug, the list of target versions (or a request to",
|
|
25298
25426
|
" enumerate), and any known governance bodies.",
|
|
25299
25427
|
"2. Execute Phase 1 (Scope) of the standards-research-analyst agent.",
|
|
@@ -25312,7 +25440,7 @@ function buildScopeStandardsResearchSkill(paths) {
|
|
|
25312
25440
|
].join("\n")
|
|
25313
25441
|
};
|
|
25314
25442
|
}
|
|
25315
|
-
function buildResearchStandardSkill(paths) {
|
|
25443
|
+
function buildResearchStandardSkill(paths, issueDefaults) {
|
|
25316
25444
|
return {
|
|
25317
25445
|
name: "research-standard",
|
|
25318
25446
|
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.",
|
|
@@ -25358,7 +25486,7 @@ function buildResearchStandardSkill(paths) {
|
|
|
25358
25486
|
"## Steps",
|
|
25359
25487
|
"",
|
|
25360
25488
|
"1. Create a `standards:research` issue with",
|
|
25361
|
-
|
|
25489
|
+
` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:research").status}\`.`,
|
|
25362
25490
|
" The body must include the standard slug and the version slug.",
|
|
25363
25491
|
"2. Execute Phase 2 (Research) of the standards-research-analyst",
|
|
25364
25492
|
" agent. The agent runs 6\u201310 targeted web searches and populates",
|
|
@@ -25377,7 +25505,7 @@ function buildResearchStandardSkill(paths) {
|
|
|
25377
25505
|
].join("\n")
|
|
25378
25506
|
};
|
|
25379
25507
|
}
|
|
25380
|
-
function buildCompareStandardsSkill(paths) {
|
|
25508
|
+
function buildCompareStandardsSkill(paths, issueDefaults) {
|
|
25381
25509
|
return {
|
|
25382
25510
|
name: "compare-standards",
|
|
25383
25511
|
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.",
|
|
@@ -25430,7 +25558,7 @@ function buildCompareStandardsSkill(paths) {
|
|
|
25430
25558
|
"## Steps",
|
|
25431
25559
|
"",
|
|
25432
25560
|
"1. Create a `standards:compare` issue with",
|
|
25433
|
-
|
|
25561
|
+
` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:compare").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:compare").status}\`.`,
|
|
25434
25562
|
" Body must include the standard slug and the list of version",
|
|
25435
25563
|
" pages under comparison.",
|
|
25436
25564
|
"2. Execute Phase 3 (Compare) of the standards-research-analyst",
|
|
@@ -25447,7 +25575,7 @@ function buildCompareStandardsSkill(paths) {
|
|
|
25447
25575
|
].join("\n")
|
|
25448
25576
|
};
|
|
25449
25577
|
}
|
|
25450
|
-
function buildExtensionStandardSkill(paths) {
|
|
25578
|
+
function buildExtensionStandardSkill(paths, issueDefaults) {
|
|
25451
25579
|
return {
|
|
25452
25580
|
name: "extension-standard",
|
|
25453
25581
|
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.",
|
|
@@ -25497,7 +25625,7 @@ function buildExtensionStandardSkill(paths) {
|
|
|
25497
25625
|
"## Steps",
|
|
25498
25626
|
"",
|
|
25499
25627
|
"1. Create a `standards:extension` issue with",
|
|
25500
|
-
|
|
25628
|
+
` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:extension").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:extension").status}\`.`,
|
|
25501
25629
|
" The body must include the standard slug, the entity slug, the",
|
|
25502
25630
|
" closest resource, and a link to the source BCM or canvas",
|
|
25503
25631
|
" document.",
|
|
@@ -25517,7 +25645,7 @@ function buildExtensionStandardSkill(paths) {
|
|
|
25517
25645
|
].join("\n")
|
|
25518
25646
|
};
|
|
25519
25647
|
}
|
|
25520
|
-
function buildOrganizationsStandardSkill(paths) {
|
|
25648
|
+
function buildOrganizationsStandardSkill(paths, issueDefaults) {
|
|
25521
25649
|
return {
|
|
25522
25650
|
name: "organizations-standard",
|
|
25523
25651
|
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.",
|
|
@@ -25563,7 +25691,7 @@ function buildOrganizationsStandardSkill(paths) {
|
|
|
25563
25691
|
"## Steps",
|
|
25564
25692
|
"",
|
|
25565
25693
|
"1. Create a `standards:organizations` issue with",
|
|
25566
|
-
|
|
25694
|
+
` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:organizations").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:organizations").status}\`.`,
|
|
25567
25695
|
" Body must include the standard slug, the organization slug, and",
|
|
25568
25696
|
" the organization's governance role.",
|
|
25569
25697
|
"2. Execute Phase 5 (Organizations) of the",
|
|
@@ -25584,7 +25712,7 @@ function buildOrganizationsStandardSkill(paths) {
|
|
|
25584
25712
|
].join("\n")
|
|
25585
25713
|
};
|
|
25586
25714
|
}
|
|
25587
|
-
function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
25715
|
+
function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
25588
25716
|
return {
|
|
25589
25717
|
name: "standards-research",
|
|
25590
25718
|
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.",
|
|
@@ -25650,13 +25778,13 @@ function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
25650
25778
|
}
|
|
25651
25779
|
],
|
|
25652
25780
|
skills: [
|
|
25653
|
-
buildScopeStandardsResearchSkill(paths),
|
|
25654
|
-
buildResearchStandardSkill(paths),
|
|
25655
|
-
buildCompareStandardsSkill(paths),
|
|
25656
|
-
buildExtensionStandardSkill(paths),
|
|
25657
|
-
buildOrganizationsStandardSkill(paths)
|
|
25781
|
+
buildScopeStandardsResearchSkill(paths, issueDefaults),
|
|
25782
|
+
buildResearchStandardSkill(paths, issueDefaults),
|
|
25783
|
+
buildCompareStandardsSkill(paths, issueDefaults),
|
|
25784
|
+
buildExtensionStandardSkill(paths, issueDefaults),
|
|
25785
|
+
buildOrganizationsStandardSkill(paths, issueDefaults)
|
|
25658
25786
|
],
|
|
25659
|
-
subAgents: [buildStandardsResearchAnalystSubAgent(paths)],
|
|
25787
|
+
subAgents: [buildStandardsResearchAnalystSubAgent(paths, issueDefaults)],
|
|
25660
25788
|
labels: [
|
|
25661
25789
|
{
|
|
25662
25790
|
name: "type:standards-research",
|
|
@@ -26880,7 +27008,7 @@ function renderPriorityRulesSection(rules) {
|
|
|
26880
27008
|
}
|
|
26881
27009
|
|
|
26882
27010
|
// src/agent/bundles/index.ts
|
|
26883
|
-
function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS) {
|
|
27011
|
+
function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
26884
27012
|
return [
|
|
26885
27013
|
buildBaseBundle(paths),
|
|
26886
27014
|
upstreamConfigulatorDocsBundle,
|
|
@@ -26901,15 +27029,15 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS) {
|
|
|
26901
27029
|
buildRequirementsWriterBundle(paths),
|
|
26902
27030
|
buildRequirementsReviewerBundle(paths),
|
|
26903
27031
|
buildResearchPipelineBundle(paths),
|
|
26904
|
-
buildCompanyProfileBundle(paths),
|
|
26905
|
-
buildCustomerProfileBundle(paths),
|
|
26906
|
-
buildPeopleProfileBundle(paths),
|
|
26907
|
-
buildSoftwareProfileBundle(paths),
|
|
26908
|
-
buildIndustryDiscoveryBundle(paths),
|
|
27032
|
+
buildCompanyProfileBundle(paths, issueDefaults),
|
|
27033
|
+
buildCustomerProfileBundle(paths, issueDefaults),
|
|
27034
|
+
buildPeopleProfileBundle(paths, issueDefaults),
|
|
27035
|
+
buildSoftwareProfileBundle(paths, issueDefaults),
|
|
27036
|
+
buildIndustryDiscoveryBundle(paths, issueDefaults),
|
|
26909
27037
|
buildBusinessModelsBundle(paths),
|
|
26910
27038
|
buildBcmWriterBundle(paths),
|
|
26911
|
-
buildStandardsResearchBundle(paths),
|
|
26912
|
-
buildRegulatoryResearchBundle(paths),
|
|
27039
|
+
buildStandardsResearchBundle(paths, issueDefaults),
|
|
27040
|
+
buildRegulatoryResearchBundle(paths, issueDefaults),
|
|
26913
27041
|
buildMaintenanceAuditBundle(paths),
|
|
26914
27042
|
buildDocsSyncBundle(paths)
|
|
26915
27043
|
];
|
|
@@ -26948,6 +27076,152 @@ function prefix(rel, entry) {
|
|
|
26948
27076
|
return path.posix.join(rel, entry);
|
|
26949
27077
|
}
|
|
26950
27078
|
|
|
27079
|
+
// src/agent/renderers/cursor-renderer.ts
|
|
27080
|
+
import { JsonFile as JsonFile2 } from "projen";
|
|
27081
|
+
import { TextFile as TextFile2 } from "projen/lib/textfile";
|
|
27082
|
+
var GENERATED_MARKER = "# ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~";
|
|
27083
|
+
var CursorRenderer = class _CursorRenderer {
|
|
27084
|
+
/**
|
|
27085
|
+
* Render all Cursor configuration files.
|
|
27086
|
+
*/
|
|
27087
|
+
static render(component, rules, skills, subAgents, mcpServers, settings) {
|
|
27088
|
+
_CursorRenderer.renderRules(component, rules);
|
|
27089
|
+
_CursorRenderer.renderSkills(component, skills);
|
|
27090
|
+
_CursorRenderer.renderSubAgents(component, subAgents);
|
|
27091
|
+
_CursorRenderer.renderMcpServers(component, mcpServers);
|
|
27092
|
+
_CursorRenderer.renderHooks(component, settings);
|
|
27093
|
+
_CursorRenderer.renderIgnoreFiles(component, settings);
|
|
27094
|
+
}
|
|
27095
|
+
static renderRules(component, rules) {
|
|
27096
|
+
for (const rule of rules) {
|
|
27097
|
+
if (rule.platforms?.cursor?.exclude) continue;
|
|
27098
|
+
const lines = [];
|
|
27099
|
+
const description = rule.platforms?.cursor?.description ?? rule.description;
|
|
27100
|
+
const isAlways = rule.scope === AGENT_RULE_SCOPE.ALWAYS;
|
|
27101
|
+
lines.push("---");
|
|
27102
|
+
lines.push(`description: "${description}"`);
|
|
27103
|
+
lines.push(`alwaysApply: ${isAlways}`);
|
|
27104
|
+
if (!isAlways && rule.filePatterns && rule.filePatterns.length > 0) {
|
|
27105
|
+
lines.push(`path: ${JSON.stringify([...rule.filePatterns])}`);
|
|
27106
|
+
}
|
|
27107
|
+
lines.push("---");
|
|
27108
|
+
lines.push("");
|
|
27109
|
+
lines.push(...rule.content.split("\n"));
|
|
27110
|
+
new TextFile2(component, `.cursor/rules/${rule.name}.mdc`, { lines });
|
|
27111
|
+
}
|
|
27112
|
+
}
|
|
27113
|
+
static renderSkills(component, skills) {
|
|
27114
|
+
for (const skill of skills) {
|
|
27115
|
+
if (skill.platforms?.cursor?.exclude) continue;
|
|
27116
|
+
const lines = [];
|
|
27117
|
+
lines.push("---");
|
|
27118
|
+
lines.push(`name: "${skill.name}"`);
|
|
27119
|
+
lines.push(`description: "${skill.description}"`);
|
|
27120
|
+
if (skill.disableModelInvocation) {
|
|
27121
|
+
lines.push(`disable-model-invocation: true`);
|
|
27122
|
+
}
|
|
27123
|
+
if (skill.userInvocable === false) {
|
|
27124
|
+
lines.push(`user-invocable: false`);
|
|
27125
|
+
}
|
|
27126
|
+
if (skill.context) {
|
|
27127
|
+
lines.push(`context: "${skill.context}"`);
|
|
27128
|
+
}
|
|
27129
|
+
if (skill.agent) {
|
|
27130
|
+
lines.push(`agent: "${skill.agent}"`);
|
|
27131
|
+
}
|
|
27132
|
+
if (skill.shell) {
|
|
27133
|
+
lines.push(`shell: "${skill.shell}"`);
|
|
27134
|
+
}
|
|
27135
|
+
if (skill.allowedTools && skill.allowedTools.length > 0) {
|
|
27136
|
+
lines.push(`allowed-tools:`);
|
|
27137
|
+
for (const tool of skill.allowedTools) {
|
|
27138
|
+
lines.push(` - "${tool}"`);
|
|
27139
|
+
}
|
|
27140
|
+
}
|
|
27141
|
+
lines.push("---");
|
|
27142
|
+
lines.push("");
|
|
27143
|
+
lines.push(...skill.instructions.split("\n"));
|
|
27144
|
+
new TextFile2(component, `.cursor/skills/${skill.name}/SKILL.md`, {
|
|
27145
|
+
lines
|
|
27146
|
+
});
|
|
27147
|
+
if (skill.referenceFiles && skill.referenceFiles.length > 0) {
|
|
27148
|
+
for (const file of skill.referenceFiles) {
|
|
27149
|
+
new TextFile2(component, `.cursor/skills/${skill.name}/${file.path}`, {
|
|
27150
|
+
lines: file.content.split("\n")
|
|
27151
|
+
});
|
|
27152
|
+
}
|
|
27153
|
+
}
|
|
27154
|
+
}
|
|
27155
|
+
}
|
|
27156
|
+
static renderSubAgents(component, subAgents) {
|
|
27157
|
+
for (const agent of subAgents) {
|
|
27158
|
+
if (agent.platforms?.cursor?.exclude) continue;
|
|
27159
|
+
const lines = [];
|
|
27160
|
+
lines.push("---");
|
|
27161
|
+
lines.push(`name: ${agent.name}`);
|
|
27162
|
+
lines.push(`description: >-`);
|
|
27163
|
+
lines.push(` ${agent.description}`);
|
|
27164
|
+
if (agent.platforms?.cursor?.readonly) {
|
|
27165
|
+
lines.push(`readonly: true`);
|
|
27166
|
+
}
|
|
27167
|
+
if (agent.platforms?.cursor?.isBackground) {
|
|
27168
|
+
lines.push(`is_background: true`);
|
|
27169
|
+
}
|
|
27170
|
+
lines.push("---");
|
|
27171
|
+
lines.push("");
|
|
27172
|
+
lines.push(...agent.prompt.split("\n"));
|
|
27173
|
+
new TextFile2(component, `.cursor/agents/${agent.name}.md`, { lines });
|
|
27174
|
+
}
|
|
27175
|
+
}
|
|
27176
|
+
static renderMcpServers(component, mcpServers) {
|
|
27177
|
+
const serverNames = Object.keys(mcpServers);
|
|
27178
|
+
if (serverNames.length === 0) return;
|
|
27179
|
+
const obj = { mcpServers: {} };
|
|
27180
|
+
const servers = obj.mcpServers;
|
|
27181
|
+
for (const [name, config] of Object.entries(mcpServers)) {
|
|
27182
|
+
const server = {};
|
|
27183
|
+
if (config.transport) server.transport = config.transport;
|
|
27184
|
+
if (config.command) server.command = config.command;
|
|
27185
|
+
if (config.args) server.args = [...config.args];
|
|
27186
|
+
if (config.url) server.url = config.url;
|
|
27187
|
+
if (config.headers && Object.keys(config.headers).length > 0) {
|
|
27188
|
+
server.headers = { ...config.headers };
|
|
27189
|
+
}
|
|
27190
|
+
if (config.env) server.env = { ...config.env };
|
|
27191
|
+
servers[name] = server;
|
|
27192
|
+
}
|
|
27193
|
+
new JsonFile2(component, ".cursor/mcp.json", { obj });
|
|
27194
|
+
}
|
|
27195
|
+
static renderHooks(component, settings) {
|
|
27196
|
+
if (!settings?.hooks) return;
|
|
27197
|
+
const hooks = {};
|
|
27198
|
+
const hookEntries = settings.hooks;
|
|
27199
|
+
for (const [event, actions] of Object.entries(hookEntries)) {
|
|
27200
|
+
if (actions && actions.length > 0) {
|
|
27201
|
+
hooks[event] = actions.map((h) => ({
|
|
27202
|
+
command: h.command
|
|
27203
|
+
}));
|
|
27204
|
+
}
|
|
27205
|
+
}
|
|
27206
|
+
if (Object.keys(hooks).length === 0) return;
|
|
27207
|
+
new JsonFile2(component, ".cursor/hooks.json", {
|
|
27208
|
+
obj: { version: 1, hooks }
|
|
27209
|
+
});
|
|
27210
|
+
}
|
|
27211
|
+
static renderIgnoreFiles(component, settings) {
|
|
27212
|
+
if (settings?.ignorePatterns && settings.ignorePatterns.length > 0) {
|
|
27213
|
+
new TextFile2(component, ".cursorignore", {
|
|
27214
|
+
lines: [GENERATED_MARKER, "", ...settings.ignorePatterns]
|
|
27215
|
+
});
|
|
27216
|
+
}
|
|
27217
|
+
if (settings?.indexingIgnorePatterns && settings.indexingIgnorePatterns.length > 0) {
|
|
27218
|
+
new TextFile2(component, ".cursorindexingignore", {
|
|
27219
|
+
lines: [GENERATED_MARKER, "", ...settings.indexingIgnorePatterns]
|
|
27220
|
+
});
|
|
27221
|
+
}
|
|
27222
|
+
}
|
|
27223
|
+
};
|
|
27224
|
+
|
|
26951
27225
|
// src/agent/template-resolver.ts
|
|
26952
27226
|
var FALLBACKS = {
|
|
26953
27227
|
"repository.owner": "<owner>",
|
|
@@ -27003,9 +27277,9 @@ function resolveTemplateVariables(template, metadata) {
|
|
|
27003
27277
|
}
|
|
27004
27278
|
|
|
27005
27279
|
// src/agent/renderers/claude-renderer.ts
|
|
27006
|
-
import { JsonFile as
|
|
27007
|
-
import { TextFile as
|
|
27008
|
-
var
|
|
27280
|
+
import { JsonFile as JsonFile3 } from "projen";
|
|
27281
|
+
import { TextFile as TextFile3 } from "projen/lib/textfile";
|
|
27282
|
+
var GENERATED_MARKER2 = "<!-- ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~ -->";
|
|
27009
27283
|
var ClaudeRenderer = class _ClaudeRenderer {
|
|
27010
27284
|
/**
|
|
27011
27285
|
* Render all Claude Code configuration files.
|
|
@@ -27027,12 +27301,12 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27027
27301
|
return target === CLAUDE_RULE_TARGET.CLAUDE_MD;
|
|
27028
27302
|
});
|
|
27029
27303
|
if (claudeMdRules.length === 0) return;
|
|
27030
|
-
const lines = [
|
|
27304
|
+
const lines = [GENERATED_MARKER2, ""];
|
|
27031
27305
|
for (let i = 0; i < claudeMdRules.length; i++) {
|
|
27032
27306
|
if (i > 0) lines.push("", "---", "");
|
|
27033
27307
|
lines.push(...claudeMdRules[i].content.split("\n"));
|
|
27034
27308
|
}
|
|
27035
|
-
new
|
|
27309
|
+
new TextFile3(component, "CLAUDE.md", { lines });
|
|
27036
27310
|
}
|
|
27037
27311
|
static renderScopedRules(component, rules) {
|
|
27038
27312
|
const scopedRules = rules.filter((r) => {
|
|
@@ -27052,7 +27326,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27052
27326
|
lines.push("");
|
|
27053
27327
|
}
|
|
27054
27328
|
lines.push(...rule.content.split("\n"));
|
|
27055
|
-
new
|
|
27329
|
+
new TextFile3(component, `.claude/rules/${rule.name}.md`, { lines });
|
|
27056
27330
|
}
|
|
27057
27331
|
}
|
|
27058
27332
|
static renderSettings(component, mcpServers, settings) {
|
|
@@ -27177,7 +27451,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27177
27451
|
hasContent = true;
|
|
27178
27452
|
}
|
|
27179
27453
|
if (!hasContent) return;
|
|
27180
|
-
new
|
|
27454
|
+
new JsonFile3(component, ".claude/settings.json", { obj });
|
|
27181
27455
|
}
|
|
27182
27456
|
static buildSandboxObj(sandbox) {
|
|
27183
27457
|
const obj = {};
|
|
@@ -27264,12 +27538,12 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27264
27538
|
lines.push("---");
|
|
27265
27539
|
lines.push("");
|
|
27266
27540
|
lines.push(...skill.instructions.split("\n"));
|
|
27267
|
-
new
|
|
27541
|
+
new TextFile3(component, `.claude/skills/${skill.name}/SKILL.md`, {
|
|
27268
27542
|
lines
|
|
27269
27543
|
});
|
|
27270
27544
|
if (skill.referenceFiles && skill.referenceFiles.length > 0) {
|
|
27271
27545
|
for (const file of skill.referenceFiles) {
|
|
27272
|
-
new
|
|
27546
|
+
new TextFile3(component, `.claude/skills/${skill.name}/${file.path}`, {
|
|
27273
27547
|
lines: file.content.split("\n")
|
|
27274
27548
|
});
|
|
27275
27549
|
}
|
|
@@ -27327,7 +27601,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27327
27601
|
lines.push("---");
|
|
27328
27602
|
lines.push("");
|
|
27329
27603
|
lines.push(...agent.prompt.split("\n"));
|
|
27330
|
-
new
|
|
27604
|
+
new TextFile3(component, `.claude/agents/${agent.name}.md`, { lines });
|
|
27331
27605
|
}
|
|
27332
27606
|
}
|
|
27333
27607
|
static buildMcpServerObj(config) {
|
|
@@ -27344,7 +27618,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27344
27618
|
}
|
|
27345
27619
|
static renderProcedures(component, procedures) {
|
|
27346
27620
|
for (const proc of procedures) {
|
|
27347
|
-
new
|
|
27621
|
+
new TextFile3(component, `.claude/procedures/${proc.name}`, {
|
|
27348
27622
|
lines: proc.content.split("\n"),
|
|
27349
27623
|
executable: true
|
|
27350
27624
|
});
|
|
@@ -27371,152 +27645,6 @@ var CopilotRenderer = class {
|
|
|
27371
27645
|
}
|
|
27372
27646
|
};
|
|
27373
27647
|
|
|
27374
|
-
// src/agent/renderers/cursor-renderer.ts
|
|
27375
|
-
import { JsonFile as JsonFile3 } from "projen";
|
|
27376
|
-
import { TextFile as TextFile3 } from "projen/lib/textfile";
|
|
27377
|
-
var GENERATED_MARKER2 = "# ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~";
|
|
27378
|
-
var CursorRenderer = class _CursorRenderer {
|
|
27379
|
-
/**
|
|
27380
|
-
* Render all Cursor configuration files.
|
|
27381
|
-
*/
|
|
27382
|
-
static render(component, rules, skills, subAgents, mcpServers, settings) {
|
|
27383
|
-
_CursorRenderer.renderRules(component, rules);
|
|
27384
|
-
_CursorRenderer.renderSkills(component, skills);
|
|
27385
|
-
_CursorRenderer.renderSubAgents(component, subAgents);
|
|
27386
|
-
_CursorRenderer.renderMcpServers(component, mcpServers);
|
|
27387
|
-
_CursorRenderer.renderHooks(component, settings);
|
|
27388
|
-
_CursorRenderer.renderIgnoreFiles(component, settings);
|
|
27389
|
-
}
|
|
27390
|
-
static renderRules(component, rules) {
|
|
27391
|
-
for (const rule of rules) {
|
|
27392
|
-
if (rule.platforms?.cursor?.exclude) continue;
|
|
27393
|
-
const lines = [];
|
|
27394
|
-
const description = rule.platforms?.cursor?.description ?? rule.description;
|
|
27395
|
-
const isAlways = rule.scope === AGENT_RULE_SCOPE.ALWAYS;
|
|
27396
|
-
lines.push("---");
|
|
27397
|
-
lines.push(`description: "${description}"`);
|
|
27398
|
-
lines.push(`alwaysApply: ${isAlways}`);
|
|
27399
|
-
if (!isAlways && rule.filePatterns && rule.filePatterns.length > 0) {
|
|
27400
|
-
lines.push(`path: ${JSON.stringify([...rule.filePatterns])}`);
|
|
27401
|
-
}
|
|
27402
|
-
lines.push("---");
|
|
27403
|
-
lines.push("");
|
|
27404
|
-
lines.push(...rule.content.split("\n"));
|
|
27405
|
-
new TextFile3(component, `.cursor/rules/${rule.name}.mdc`, { lines });
|
|
27406
|
-
}
|
|
27407
|
-
}
|
|
27408
|
-
static renderSkills(component, skills) {
|
|
27409
|
-
for (const skill of skills) {
|
|
27410
|
-
if (skill.platforms?.cursor?.exclude) continue;
|
|
27411
|
-
const lines = [];
|
|
27412
|
-
lines.push("---");
|
|
27413
|
-
lines.push(`name: "${skill.name}"`);
|
|
27414
|
-
lines.push(`description: "${skill.description}"`);
|
|
27415
|
-
if (skill.disableModelInvocation) {
|
|
27416
|
-
lines.push(`disable-model-invocation: true`);
|
|
27417
|
-
}
|
|
27418
|
-
if (skill.userInvocable === false) {
|
|
27419
|
-
lines.push(`user-invocable: false`);
|
|
27420
|
-
}
|
|
27421
|
-
if (skill.context) {
|
|
27422
|
-
lines.push(`context: "${skill.context}"`);
|
|
27423
|
-
}
|
|
27424
|
-
if (skill.agent) {
|
|
27425
|
-
lines.push(`agent: "${skill.agent}"`);
|
|
27426
|
-
}
|
|
27427
|
-
if (skill.shell) {
|
|
27428
|
-
lines.push(`shell: "${skill.shell}"`);
|
|
27429
|
-
}
|
|
27430
|
-
if (skill.allowedTools && skill.allowedTools.length > 0) {
|
|
27431
|
-
lines.push(`allowed-tools:`);
|
|
27432
|
-
for (const tool of skill.allowedTools) {
|
|
27433
|
-
lines.push(` - "${tool}"`);
|
|
27434
|
-
}
|
|
27435
|
-
}
|
|
27436
|
-
lines.push("---");
|
|
27437
|
-
lines.push("");
|
|
27438
|
-
lines.push(...skill.instructions.split("\n"));
|
|
27439
|
-
new TextFile3(component, `.cursor/skills/${skill.name}/SKILL.md`, {
|
|
27440
|
-
lines
|
|
27441
|
-
});
|
|
27442
|
-
if (skill.referenceFiles && skill.referenceFiles.length > 0) {
|
|
27443
|
-
for (const file of skill.referenceFiles) {
|
|
27444
|
-
new TextFile3(component, `.cursor/skills/${skill.name}/${file.path}`, {
|
|
27445
|
-
lines: file.content.split("\n")
|
|
27446
|
-
});
|
|
27447
|
-
}
|
|
27448
|
-
}
|
|
27449
|
-
}
|
|
27450
|
-
}
|
|
27451
|
-
static renderSubAgents(component, subAgents) {
|
|
27452
|
-
for (const agent of subAgents) {
|
|
27453
|
-
if (agent.platforms?.cursor?.exclude) continue;
|
|
27454
|
-
const lines = [];
|
|
27455
|
-
lines.push("---");
|
|
27456
|
-
lines.push(`name: ${agent.name}`);
|
|
27457
|
-
lines.push(`description: >-`);
|
|
27458
|
-
lines.push(` ${agent.description}`);
|
|
27459
|
-
if (agent.platforms?.cursor?.readonly) {
|
|
27460
|
-
lines.push(`readonly: true`);
|
|
27461
|
-
}
|
|
27462
|
-
if (agent.platforms?.cursor?.isBackground) {
|
|
27463
|
-
lines.push(`is_background: true`);
|
|
27464
|
-
}
|
|
27465
|
-
lines.push("---");
|
|
27466
|
-
lines.push("");
|
|
27467
|
-
lines.push(...agent.prompt.split("\n"));
|
|
27468
|
-
new TextFile3(component, `.cursor/agents/${agent.name}.md`, { lines });
|
|
27469
|
-
}
|
|
27470
|
-
}
|
|
27471
|
-
static renderMcpServers(component, mcpServers) {
|
|
27472
|
-
const serverNames = Object.keys(mcpServers);
|
|
27473
|
-
if (serverNames.length === 0) return;
|
|
27474
|
-
const obj = { mcpServers: {} };
|
|
27475
|
-
const servers = obj.mcpServers;
|
|
27476
|
-
for (const [name, config] of Object.entries(mcpServers)) {
|
|
27477
|
-
const server = {};
|
|
27478
|
-
if (config.transport) server.transport = config.transport;
|
|
27479
|
-
if (config.command) server.command = config.command;
|
|
27480
|
-
if (config.args) server.args = [...config.args];
|
|
27481
|
-
if (config.url) server.url = config.url;
|
|
27482
|
-
if (config.headers && Object.keys(config.headers).length > 0) {
|
|
27483
|
-
server.headers = { ...config.headers };
|
|
27484
|
-
}
|
|
27485
|
-
if (config.env) server.env = { ...config.env };
|
|
27486
|
-
servers[name] = server;
|
|
27487
|
-
}
|
|
27488
|
-
new JsonFile3(component, ".cursor/mcp.json", { obj });
|
|
27489
|
-
}
|
|
27490
|
-
static renderHooks(component, settings) {
|
|
27491
|
-
if (!settings?.hooks) return;
|
|
27492
|
-
const hooks = {};
|
|
27493
|
-
const hookEntries = settings.hooks;
|
|
27494
|
-
for (const [event, actions] of Object.entries(hookEntries)) {
|
|
27495
|
-
if (actions && actions.length > 0) {
|
|
27496
|
-
hooks[event] = actions.map((h) => ({
|
|
27497
|
-
command: h.command
|
|
27498
|
-
}));
|
|
27499
|
-
}
|
|
27500
|
-
}
|
|
27501
|
-
if (Object.keys(hooks).length === 0) return;
|
|
27502
|
-
new JsonFile3(component, ".cursor/hooks.json", {
|
|
27503
|
-
obj: { version: 1, hooks }
|
|
27504
|
-
});
|
|
27505
|
-
}
|
|
27506
|
-
static renderIgnoreFiles(component, settings) {
|
|
27507
|
-
if (settings?.ignorePatterns && settings.ignorePatterns.length > 0) {
|
|
27508
|
-
new TextFile3(component, ".cursorignore", {
|
|
27509
|
-
lines: [GENERATED_MARKER2, "", ...settings.ignorePatterns]
|
|
27510
|
-
});
|
|
27511
|
-
}
|
|
27512
|
-
if (settings?.indexingIgnorePatterns && settings.indexingIgnorePatterns.length > 0) {
|
|
27513
|
-
new TextFile3(component, ".cursorindexingignore", {
|
|
27514
|
-
lines: [GENERATED_MARKER2, "", ...settings.indexingIgnorePatterns]
|
|
27515
|
-
});
|
|
27516
|
-
}
|
|
27517
|
-
}
|
|
27518
|
-
};
|
|
27519
|
-
|
|
27520
27648
|
// src/agent/agent-config.ts
|
|
27521
27649
|
var DEFAULT_CLAUDE_ALLOW = [
|
|
27522
27650
|
// ── Git ──────────────────────────────────────────────────────────────
|
|
@@ -27742,7 +27870,10 @@ var AgentConfig = class _AgentConfig extends Component8 {
|
|
|
27742
27870
|
*/
|
|
27743
27871
|
get pathAwareBundles() {
|
|
27744
27872
|
if (!this.cachedBundles) {
|
|
27745
|
-
this.cachedBundles = buildBuiltInBundles(
|
|
27873
|
+
this.cachedBundles = buildBuiltInBundles(
|
|
27874
|
+
this.resolvedPaths,
|
|
27875
|
+
resolveIssueDefaults(this.options.issueDefaults)
|
|
27876
|
+
);
|
|
27746
27877
|
}
|
|
27747
27878
|
return this.cachedBundles;
|
|
27748
27879
|
}
|
|
@@ -27788,6 +27919,7 @@ var AgentConfig = class _AgentConfig extends Component8 {
|
|
|
27788
27919
|
this.project.gitignore.addPatterns(`/${resolvedRunRatio.stateFilePath}`);
|
|
27789
27920
|
}
|
|
27790
27921
|
validateUnblockDependentsConfig(this.options.unblockDependents);
|
|
27922
|
+
validateIssueDefaultsConfig(this.options.issueDefaults);
|
|
27791
27923
|
const resolvedProgressFiles = validateProgressFilesConfig(
|
|
27792
27924
|
this.options.progressFiles
|
|
27793
27925
|
);
|
|
@@ -32675,6 +32807,8 @@ export {
|
|
|
32675
32807
|
DEFAULT_DISPATCH_MODEL,
|
|
32676
32808
|
DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
|
|
32677
32809
|
DEFAULT_HOUSEKEEPING_MODEL,
|
|
32810
|
+
DEFAULT_ISSUE_PRIORITY,
|
|
32811
|
+
DEFAULT_ISSUE_STATUS,
|
|
32678
32812
|
DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS,
|
|
32679
32813
|
DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER,
|
|
32680
32814
|
DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER,
|
|
@@ -32691,6 +32825,7 @@ export {
|
|
|
32691
32825
|
DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
|
|
32692
32826
|
DEFAULT_PROGRESS_FILES_STATE_DIR,
|
|
32693
32827
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
32828
|
+
DEFAULT_RESOLVED_ISSUE_DEFAULTS,
|
|
32694
32829
|
DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
32695
32830
|
DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
32696
32831
|
DEFAULT_SCHEDULED_TASK_ENTRIES,
|
|
@@ -32742,6 +32877,8 @@ export {
|
|
|
32742
32877
|
TypeScriptConfig,
|
|
32743
32878
|
TypeScriptProject,
|
|
32744
32879
|
UNKNOWN_TYPE_FALLBACK_TIER,
|
|
32880
|
+
VALID_PRIORITY_VALUES,
|
|
32881
|
+
VALID_STATUS_VALUES,
|
|
32745
32882
|
VERSION,
|
|
32746
32883
|
VERSION_KEYS_SKIP,
|
|
32747
32884
|
VERSION_NPM_PACKAGES,
|
|
@@ -32800,6 +32937,7 @@ export {
|
|
|
32800
32937
|
githubWorkflowBundle,
|
|
32801
32938
|
industryDiscoveryBundle,
|
|
32802
32939
|
jestBundle,
|
|
32940
|
+
labelsForPhase,
|
|
32803
32941
|
maintenanceAuditBundle,
|
|
32804
32942
|
meetingAnalysisBundle,
|
|
32805
32943
|
orchestratorBundle,
|
|
@@ -32853,6 +32991,7 @@ export {
|
|
|
32853
32991
|
resolveAgentTiers,
|
|
32854
32992
|
resolveAstroProjectOutdir,
|
|
32855
32993
|
resolveAwsCdkProjectOutdir,
|
|
32994
|
+
resolveIssueDefaults,
|
|
32856
32995
|
resolveIssueTemplates,
|
|
32857
32996
|
resolveModelAlias,
|
|
32858
32997
|
resolveOrchestratorAssets,
|
|
@@ -32876,6 +33015,7 @@ export {
|
|
|
32876
33015
|
typescriptBundle,
|
|
32877
33016
|
upstreamConfigulatorDocsBundle,
|
|
32878
33017
|
validateAgentTierConfig,
|
|
33018
|
+
validateIssueDefaultsConfig,
|
|
32879
33019
|
validateIssueTemplatesConfig,
|
|
32880
33020
|
validateMonorepoLayout,
|
|
32881
33021
|
validateProgressFilesConfig,
|