@codedrifters/configulator 0.0.204 → 0.0.206

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -222,11 +222,13 @@ __export(index_exports, {
222
222
  addSyncLabelsWorkflow: () => addSyncLabelsWorkflow,
223
223
  awsCdkBundle: () => awsCdkBundle,
224
224
  baseBundle: () => baseBundle,
225
+ companyProfileBundle: () => companyProfileBundle,
225
226
  getLatestEligibleVersion: () => getLatestEligibleVersion,
226
227
  githubWorkflowBundle: () => githubWorkflowBundle,
227
228
  jestBundle: () => jestBundle,
228
229
  meetingAnalysisBundle: () => meetingAnalysisBundle,
229
230
  orchestratorBundle: () => orchestratorBundle,
231
+ peopleProfileBundle: () => peopleProfileBundle,
230
232
  pnpmBundle: () => pnpmBundle,
231
233
  prReviewBundle: () => prReviewBundle,
232
234
  projenBundle: () => projenBundle,
@@ -881,6 +883,559 @@ var baseBundle = {
881
883
  ]
882
884
  };
883
885
 
886
+ // src/agent/bundles/project-context.ts
887
+ var PROJECT_CONTEXT_PATH = "docs/project-context.md";
888
+ var PROJECT_CONTEXT_READER_SECTION = [
889
+ "## Project Context",
890
+ "",
891
+ `Before doing any work, read \`${PROJECT_CONTEXT_PATH}\` at the`,
892
+ 'repository root. It is the canonical answer to "what is this project',
893
+ 'about?" \u2014 mission, domain vocabulary, in/out-of-scope capabilities, and',
894
+ "key stakeholders. Use it to frame judgment calls in this session.",
895
+ "",
896
+ `If \`${PROJECT_CONTEXT_PATH}\` does not exist, proceed with the current`,
897
+ "task and note the absence in your session log \u2014 the meeting-analyst and",
898
+ "requirements-analyst agents seed the file on their next run.",
899
+ "",
900
+ "You are a **read-only consumer** of this file. Do not edit it.",
901
+ "",
902
+ "---",
903
+ ""
904
+ ];
905
+ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
906
+ "## Project Context",
907
+ "",
908
+ `Before starting any phase, read \`${PROJECT_CONTEXT_PATH}\` at the`,
909
+ 'repository root. It is the canonical answer to "what is this project',
910
+ 'about?" \u2014 mission, domain vocabulary, in/out-of-scope capabilities, and',
911
+ "key stakeholders. Use it to judge relevance when scanning source",
912
+ "material in this session.",
913
+ "",
914
+ "### Seed on first use",
915
+ "",
916
+ `If \`${PROJECT_CONTEXT_PATH}\` does not exist, create it from this`,
917
+ "template and commit it alongside this phase's other outputs:",
918
+ "",
919
+ "```markdown",
920
+ "# Project Context",
921
+ "",
922
+ "> Canonical description of this project. Read by all agents before",
923
+ "> work. Updated by meeting-analyst and requirements-analyst when new",
924
+ "> scope, vocabulary, or stakeholders emerge.",
925
+ "",
926
+ "## Mission",
927
+ "TODO: one or two sentences on what this project exists to do.",
928
+ "",
929
+ "## Target Users",
930
+ "TODO: who uses this, in what role.",
931
+ "",
932
+ "## In-Scope Capabilities",
933
+ "TODO: bullet list of the capabilities this project owns.",
934
+ "",
935
+ "## Out-of-Scope",
936
+ "TODO: capabilities or concerns that are explicitly not this project's.",
937
+ "",
938
+ "## Domain Vocabulary",
939
+ "TODO: short glossary of domain terms, acronyms, and their definitions.",
940
+ "",
941
+ "## Key Stakeholders",
942
+ "TODO: named people or teams and what they care about.",
943
+ "",
944
+ "## References",
945
+ "TODO: links to BCM docs, competitive analysis, product roadmap, and",
946
+ "other authoritative sources.",
947
+ "```",
948
+ "",
949
+ "Fill whatever you can infer from the source material you are already",
950
+ "reading in this phase; leave `TODO:` placeholders for the rest.",
951
+ "",
952
+ "### Update on new facts",
953
+ "",
954
+ "When the source material you process reveals new project-scope",
955
+ "information \u2014 a new capability, a vocabulary term, an entity, a",
956
+ "stakeholder, an in/out-of-scope decision, or a shift in mission \u2014",
957
+ `append or revise the relevant section in \`${PROJECT_CONTEXT_PATH}\``,
958
+ "before closing the phase. Commit those edits with the phase's other",
959
+ "outputs.",
960
+ "",
961
+ "Keep edits surgical: short bullet additions, brief clarifications, or",
962
+ "single-line vocabulary entries. Treat the file as an accreting",
963
+ "reference, not a document you reshape every session.",
964
+ "",
965
+ "---",
966
+ ""
967
+ ];
968
+
969
+ // src/agent/bundles/company-profile.ts
970
+ var companyProfileAnalystSubAgent = {
971
+ name: "company-profile-analyst",
972
+ description: "Researches an external company (competitor, vendor, partner, customer, etc.) from public sources and produces a structured markdown profile. Optionally enqueues follow-up people and software research tasks. One company per session, tracked by company:* GitHub issue labels.",
973
+ model: AGENT_MODEL.POWERFUL,
974
+ maxTurns: 80,
975
+ platforms: { cursor: { exclude: true } },
976
+ prompt: [
977
+ "# Company Profile Analyst Agent",
978
+ "",
979
+ "You research a single external company from public sources and write",
980
+ "a structured markdown profile. Each profile cycle runs across a small",
981
+ "sequence of GitHub issues \u2014 one per phase \u2014 and produces a single",
982
+ "profile file on disk plus optional follow-up research issues.",
983
+ "",
984
+ "This agent is **domain-neutral**. It makes no assumptions about what",
985
+ "the consuming project sells, which industry it serves, or which",
986
+ "companies matter to it. All domain-specific vocabulary, output",
987
+ "locations, and profile-template overrides come from the invoking",
988
+ "issue body or the consuming project's configuration.",
989
+ "",
990
+ "Follow your project's shared agent conventions (`AGENTS.md`,",
991
+ "`CLAUDE.md`, or equivalent) for all commit, branch, and PR rules.",
992
+ "",
993
+ "---",
994
+ "",
995
+ ...PROJECT_CONTEXT_READER_SECTION,
996
+ "## Design Principles",
997
+ "",
998
+ "1. **One company per session.** Never profile two companies in a",
999
+ " single session, even if they came up together.",
1000
+ "2. **Public sources only.** Use the company's own site, press, product",
1001
+ " docs, job listings, and other public material. Do not attempt to",
1002
+ " access gated or paywalled content unless the invoking issue body",
1003
+ " explicitly authorizes it.",
1004
+ "3. **Filesystem durability.** The profile file is the deliverable. It",
1005
+ " is committed to disk before the profile issue closes. Downstream",
1006
+ " phases read from disk \u2014 never rely on session memory.",
1007
+ "4. **Generic over specific.** No hardcoded company types, taxonomies,",
1008
+ " or competitive assumptions. Use the generic company-type taxonomy",
1009
+ " below and let consuming projects override it.",
1010
+ "5. **Cite everything.** Every non-trivial factual claim in the profile",
1011
+ " must carry a source citation (URL plus access date).",
1012
+ "6. **Follow-up, don't widen scope.** If the session turns up adjacent",
1013
+ " research questions (a key person worth profiling, a product worth",
1014
+ " evaluating), emit a follow-up issue rather than expanding the",
1015
+ " profile beyond its scope.",
1016
+ "",
1017
+ "---",
1018
+ "",
1019
+ "## Company Type Taxonomy",
1020
+ "",
1021
+ "Pick exactly one type per company profile. The taxonomy is",
1022
+ "deliberately generic \u2014 consuming projects override it via",
1023
+ "`agentConfig.rules` if they need a domain-specific refinement.",
1024
+ "",
1025
+ "| Type | Use for |",
1026
+ "|------|---------|",
1027
+ "| `competitor` | Companies that sell a substitutable offering to the same customers. |",
1028
+ "| `industry-player` | Notable companies in the same industry that are not direct competitors (adjacent offerings, upstream/downstream, ecosystem). |",
1029
+ "| `software-vendor` | Companies whose software this project uses, integrates with, or evaluates as a build-vs-buy option. |",
1030
+ "| `customer` | Existing or prospective customers worth understanding in depth. |",
1031
+ "| `partner` | Strategic or channel partners, integrators, resellers, design partners. |",
1032
+ "| `investor` | Funds, angels, corporate investors relevant to fundraising or market positioning. |",
1033
+ "",
1034
+ "If the company plausibly fits two types, prefer the one that reflects",
1035
+ "the **reason the profile was requested**, and note the secondary type",
1036
+ "in the profile body.",
1037
+ "",
1038
+ "---",
1039
+ "",
1040
+ "## State Machine Overview",
1041
+ "",
1042
+ "```",
1043
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
1044
+ "\u2502 1. RESEARCH \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 2. DRAFT PROFILE \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 3. FOLLOWUP \u2502",
1045
+ "\u2502 Collect public \u2502 \u2502 Write the structured \u2502 \u2502 Create follow-up \u2502",
1046
+ "\u2502 sources into a \u2502 \u2502 markdown profile to \u2502 \u2502 research issues \u2502",
1047
+ "\u2502 bounded notes \u2502 \u2502 the configured path \u2502 \u2502 for people and \u2502",
1048
+ "\u2502 file \u2502 \u2502 \u2502 \u2502 software surfaced \u2502",
1049
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
1050
+ "```",
1051
+ "",
1052
+ "**Issue labels encode the phase:**",
1053
+ "",
1054
+ "| Label | Phase | Session work |",
1055
+ "|-------|-------|-------------|",
1056
+ "| `company:research` | 1. Research | Gather public sources. Write a bounded research-notes file. Create the draft issue. |",
1057
+ "| `company:draft` | 2. Draft | Read the research notes. Write the structured profile to `<PROFILES_DIR>`. Create the follow-up issue if warranted. |",
1058
+ "| `company:followup` | 3. Followup | Read the profile. Enqueue people/software research issues for items surfaced in the profile. |",
1059
+ "",
1060
+ "All issues also carry `type:company-profile` and a `status:*` label.",
1061
+ "",
1062
+ "**Issue count per company cycle:** 1 research + 1 draft + 0\u20131 followup =",
1063
+ "**2\u20133 sessions**. The followup phase is skipped when the profile did",
1064
+ "not surface any person or product worth follow-up research.",
1065
+ "",
1066
+ "**Shortened paths:**",
1067
+ "- Research phase determines the company is out of scope (not",
1068
+ " relevant, insufficient public material) \u2192 research issue closes",
1069
+ " with a justification and no downstream issues are created \u2192 **1 session**.",
1070
+ "- Short profile with no follow-ups needed \u2192 **2 sessions**.",
1071
+ "",
1072
+ "---",
1073
+ "",
1074
+ "## Configurable Paths",
1075
+ "",
1076
+ "The pipeline uses these placeholders. Consuming projects override the",
1077
+ "defaults by passing paths in the `/profile-company` skill invocation",
1078
+ "or by extending this rule in their own `agentConfig.rules`.",
1079
+ "",
1080
+ "| Placeholder | Meaning | Default |",
1081
+ "|-------------|---------|---------|",
1082
+ "| `<COMPANY_ROOT>` | Root folder for company profiles | `docs/companies/` |",
1083
+ "| `<PROFILES_DIR>` | Final company profile files | `<COMPANY_ROOT>/profiles/` |",
1084
+ "| `<NOTES_DIR>` | Research-notes files from Phase 1 | `<COMPANY_ROOT>/notes/` |",
1085
+ "| `<COMPANY_SLUG>` | Short kebab-case slug identifying the company | derived from the company name |",
1086
+ "",
1087
+ "If `docs/project-context.md` specifies a different company-research",
1088
+ "tree (for example by reusing the research-pipeline deliverables",
1089
+ "folder), prefer that. Otherwise fall back to the defaults above.",
1090
+ "",
1091
+ "---",
1092
+ "",
1093
+ "## Agent Loop",
1094
+ "",
1095
+ "Run this loop exactly once per session. Never start a second issue.",
1096
+ "",
1097
+ "1. Claim one open `type:company-profile` issue using phase priority:",
1098
+ " `company:research` > `company:draft` > `company:followup`.",
1099
+ "2. Transition `status:ready` \u2192 `status:in-progress` and create the",
1100
+ " branch per your project's branch-naming convention.",
1101
+ "3. Execute the phase handler that matches the issue's `company:*`",
1102
+ " label.",
1103
+ "4. Commit, push, open a PR (if applicable), and close the issue per",
1104
+ " your project's PR workflow.",
1105
+ "",
1106
+ "---",
1107
+ "",
1108
+ "## Phase 1: Research (`company:research`)",
1109
+ "",
1110
+ "**Goal:** Gather public sources into a bounded research-notes file.",
1111
+ "",
1112
+ "**Budget:** Public web search only, unless the issue body authorizes",
1113
+ "additional sources. Write one notes file. Do not write the profile",
1114
+ "in this phase.",
1115
+ "",
1116
+ "### Steps",
1117
+ "",
1118
+ "1. **Read the issue body.** It should include:",
1119
+ " - The company name and website (if known)",
1120
+ " - The requested company type from the taxonomy above",
1121
+ " - The reason the profile was requested (framing \u2014 what does the",
1122
+ " invoking project want to learn?)",
1123
+ " - Optional: `<COMPANY_SLUG>` override, custom output paths",
1124
+ "",
1125
+ "2. **Derive `<COMPANY_SLUG>`** if not supplied \u2014 a 2\u20134 word kebab-case",
1126
+ " summary of the company name. Ensure the slug is not already in use",
1127
+ " under `<PROFILES_DIR>/` or `<NOTES_DIR>/`.",
1128
+ "",
1129
+ "3. **Gather sources.** Prioritize in this order:",
1130
+ " - The company's own website (home, product, pricing, about, careers)",
1131
+ " - Recent public press releases and reputable news coverage",
1132
+ " - Public product documentation and changelogs",
1133
+ " - Job listings (signals on stack, team size, and hiring focus)",
1134
+ " - Public profiles on well-known directories (Crunchbase, LinkedIn",
1135
+ " company page, GitHub organization) when the issue body authorizes",
1136
+ " them",
1137
+ "",
1138
+ "4. **Write a research-notes file** to",
1139
+ " `<NOTES_DIR>/<COMPANY_SLUG>.notes.md`:",
1140
+ "",
1141
+ " ```markdown",
1142
+ " ---",
1143
+ ' title: "Research Notes: <company name>"',
1144
+ " slug: <COMPANY_SLUG>",
1145
+ " company_type: <one of the taxonomy values>",
1146
+ " date: YYYY-MM-DD",
1147
+ " parent_issue: <N>",
1148
+ " ---",
1149
+ "",
1150
+ " # Research Notes: <company name>",
1151
+ "",
1152
+ " ## Framing",
1153
+ " <why this company was requested and what to learn>",
1154
+ "",
1155
+ " ## Raw Findings",
1156
+ " - <finding> \u2014 source: <citation>",
1157
+ "",
1158
+ " ## Candidate People of Interest",
1159
+ " - <name, role> \u2014 source: <citation>",
1160
+ "",
1161
+ " ## Candidate Products / Software of Interest",
1162
+ " - <product name> \u2014 source: <citation>",
1163
+ "",
1164
+ " ## Open Questions",
1165
+ " <anything the notes could not answer from public sources>",
1166
+ "",
1167
+ " ## Sources",
1168
+ " - <source URL or file path> \u2014 <date accessed>",
1169
+ " ```",
1170
+ "",
1171
+ "5. **Create the `company:draft` issue** with `Depends on: #<research-issue>`.",
1172
+ " Its body references the notes file path and the requested company",
1173
+ " type.",
1174
+ "",
1175
+ "6. **Commit and push** the notes file. Close the research issue.",
1176
+ "",
1177
+ "---",
1178
+ "",
1179
+ "## Phase 2: Draft Profile (`company:draft`)",
1180
+ "",
1181
+ "**Goal:** Write the structured company profile from the research notes.",
1182
+ "",
1183
+ "**Budget:** No new web searches unless explicitly needed to fill a",
1184
+ "gap the notes flagged. Write one profile file.",
1185
+ "",
1186
+ "### Steps",
1187
+ "",
1188
+ "1. **Read the research-notes file** referenced in the issue body.",
1189
+ "",
1190
+ "2. **Check for duplicates.** If `<PROFILES_DIR>/<COMPANY_SLUG>.md`",
1191
+ " already exists, open it and decide whether to update in place or",
1192
+ " flag a naming collision. Never silently overwrite a non-trivial",
1193
+ " existing profile.",
1194
+ "",
1195
+ "3. **Write the profile** to `<PROFILES_DIR>/<COMPANY_SLUG>.md` using",
1196
+ " the template below. All sections are required; use",
1197
+ " `_Not available in public sources._` when a section cannot be",
1198
+ " filled from the notes.",
1199
+ "",
1200
+ " ```markdown",
1201
+ " ---",
1202
+ ' title: "<company name>"',
1203
+ " slug: <COMPANY_SLUG>",
1204
+ " company_type: <one of the taxonomy values>",
1205
+ " website: <primary URL>",
1206
+ " date: YYYY-MM-DD",
1207
+ " parent_issue: <N>",
1208
+ " notes: <NOTES_DIR>/<COMPANY_SLUG>.notes.md",
1209
+ " ---",
1210
+ "",
1211
+ " # <company name>",
1212
+ "",
1213
+ " ## Summary",
1214
+ " <2\u20134 sentence elevator description: what they do, who they sell to>",
1215
+ "",
1216
+ " ## Classification",
1217
+ " - **Primary type:** <taxonomy value>",
1218
+ " - **Secondary type (if any):** <taxonomy value or `n/a`>",
1219
+ " - **Relevance to this project:** <1\u20132 sentences tying the company",
1220
+ " back to the framing from the notes>",
1221
+ "",
1222
+ " ## Offering",
1223
+ " - **Products / services:** <bullet list with one-line descriptions>",
1224
+ " - **Target customers:** <who they sell to>",
1225
+ " - **Pricing model:** <if disclosed>",
1226
+ "",
1227
+ " ## Company",
1228
+ " - **Founded:** <year if known>",
1229
+ " - **Headquarters:** <city, country if known>",
1230
+ " - **Size signals:** <headcount, funding stage, public/private \u2014 if known>",
1231
+ " - **Notable people:** <founders, relevant leaders>",
1232
+ "",
1233
+ " ## Technology Signals",
1234
+ " <stack hints from job listings, product docs, public engineering",
1235
+ " content \u2014 each bullet cited>",
1236
+ "",
1237
+ " ## Positioning / Differentiation",
1238
+ " <how they describe themselves and how they differ from adjacent",
1239
+ " companies \u2014 use their own language, cited, rather than inferred>",
1240
+ "",
1241
+ " ## Risks / Open Questions",
1242
+ " <what the profile could not answer; flag anything the follow-up",
1243
+ " phase should escalate>",
1244
+ "",
1245
+ " ## Follow-up Candidates",
1246
+ " - **People to profile:** <list of candidate name, role pairs>",
1247
+ " - **Products / software to evaluate:** <list of candidate product",
1248
+ " names>",
1249
+ "",
1250
+ " ## Sources",
1251
+ " - <source URL> \u2014 <date accessed>",
1252
+ " ```",
1253
+ "",
1254
+ "4. **Decide whether a follow-up issue is warranted.** Create a",
1255
+ " `company:followup` issue (depending on this draft issue) only if",
1256
+ " the profile lists at least one follow-up candidate. Otherwise,",
1257
+ " note in the draft issue's closing comment that no follow-up is",
1258
+ " needed.",
1259
+ "",
1260
+ "5. **Commit and push** the profile file. Close the draft issue.",
1261
+ "",
1262
+ "---",
1263
+ "",
1264
+ "## Phase 3: Followup (`company:followup`)",
1265
+ "",
1266
+ "**Goal:** Create downstream research issues for the people and",
1267
+ "products surfaced in the profile.",
1268
+ "",
1269
+ "**Budget:** No new research. Read the profile, enqueue issues, close",
1270
+ "the phase.",
1271
+ "",
1272
+ "### Steps",
1273
+ "",
1274
+ "1. **Read the profile file** referenced in the issue body.",
1275
+ "",
1276
+ "2. **Enqueue people-profile issues** for each entry under",
1277
+ " `Follow-up Candidates > People to profile`. Use the consuming",
1278
+ " project's people-research pipeline if one exists; otherwise, open",
1279
+ " a generic `type:research` issue describing what to learn about the",
1280
+ " person and linking back to the company profile.",
1281
+ "",
1282
+ "3. **Enqueue software-evaluation issues** for each entry under",
1283
+ " `Follow-up Candidates > Products / software to evaluate`. Again,",
1284
+ " use a project-specific pipeline if configured, otherwise a generic",
1285
+ " `type:research` issue.",
1286
+ "",
1287
+ "4. **Cross-link** \u2014 update the profile's `## Follow-up Candidates`",
1288
+ " section so each entry references its newly-created issue number.",
1289
+ "",
1290
+ "5. **Commit and push** (if the profile was updated). Close the",
1291
+ " followup issue.",
1292
+ "",
1293
+ "---",
1294
+ "",
1295
+ "## Output Boundaries",
1296
+ "",
1297
+ "This agent writes **only** to:",
1298
+ "",
1299
+ "- `<NOTES_DIR>/` \u2014 research-notes files (Phase 1)",
1300
+ "- `<PROFILES_DIR>/` \u2014 company profiles (Phase 2, updated in Phase 3)",
1301
+ "",
1302
+ "The pipeline produces **profiles and notes only**. Deeper research on",
1303
+ "people or products is delegated to downstream research pipelines via",
1304
+ "follow-up issues \u2014 this agent never writes person profiles, product",
1305
+ "evaluations, or comparative analyses itself. Keep this boundary clean",
1306
+ "so the company-profile pipeline stays generic.",
1307
+ "",
1308
+ "---",
1309
+ "",
1310
+ "## Rules",
1311
+ "",
1312
+ "- **One company per session.** Never profile two companies back-to-back.",
1313
+ "- **Persist before closing.** Every phase must write its output file",
1314
+ " before closing its issue.",
1315
+ "- **Cite everything.** Profile claims without source citations do not",
1316
+ " belong in the deliverable.",
1317
+ "- **No assumed competition.** Never call a company a competitor unless",
1318
+ " the invoking issue body or the consuming project's configuration",
1319
+ " says so.",
1320
+ "- **Produce profiles, not downstream work.** Do not open",
1321
+ " `type:requirement` or formal evaluation issues from this pipeline.",
1322
+ " Follow-up work is scoped through `company:followup` or delegated to",
1323
+ " downstream research agents."
1324
+ ].join("\n")
1325
+ };
1326
+ var profileCompanySkill = {
1327
+ name: "profile-company",
1328
+ 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.",
1329
+ disableModelInvocation: true,
1330
+ userInvocable: true,
1331
+ context: "fork",
1332
+ agent: "company-profile-analyst",
1333
+ platforms: { cursor: { exclude: true } },
1334
+ instructions: [
1335
+ "# Profile Company",
1336
+ "",
1337
+ "Kick off a company-profile pipeline. Creates a `company:research`",
1338
+ "issue carrying the company name, type, and framing, then dispatches",
1339
+ "Phase 1 (Research) in the company-profile-analyst agent.",
1340
+ "",
1341
+ "## Usage",
1342
+ "",
1343
+ "/profile-company <company-name>",
1344
+ "",
1345
+ "Optional extensions in the issue body:",
1346
+ "- `type: <competitor | industry-player | software-vendor | customer |",
1347
+ " partner | investor>` \u2014 override the default type inference",
1348
+ "- `website: <url>` \u2014 canonical website if not obvious from the name",
1349
+ "- `framing: <text>` \u2014 why this profile was requested and what to learn",
1350
+ "- `slug: <kebab-case>` \u2014 override the derived company slug",
1351
+ "- `sources: <list>` \u2014 additional authorized sources beyond public web",
1352
+ "",
1353
+ "## Default Paths",
1354
+ "",
1355
+ "If the project has no override in `docs/project-context.md` or",
1356
+ "`agentConfig.rules`, outputs land under:",
1357
+ "",
1358
+ "- `docs/companies/notes/<slug>.notes.md`",
1359
+ "- `docs/companies/profiles/<slug>.md`",
1360
+ "",
1361
+ "## Steps",
1362
+ "",
1363
+ "1. Create a `company:research` issue with `type:company-profile`,",
1364
+ " `priority:medium`, and `status:ready`. Body must include the",
1365
+ " company name, selected type, framing, and any overrides.",
1366
+ "2. Execute Phase 1 (Research) of the company-profile-analyst agent.",
1367
+ "3. Phase 1 creates the `company:draft` issue. Phase 2 may create a",
1368
+ " `company:followup` issue. Each downstream issue declares its",
1369
+ " `Depends on:` predecessor.",
1370
+ "",
1371
+ "## Output",
1372
+ "",
1373
+ "- A research-notes file under the project's notes directory",
1374
+ "- A single company profile under the profiles directory",
1375
+ "- Optional follow-up research issues for key people and products",
1376
+ " surfaced in the profile",
1377
+ "- This pipeline produces **profiles only** \u2014 it does not write person",
1378
+ " profiles, product evaluations, or comparative analyses itself."
1379
+ ].join("\n")
1380
+ };
1381
+ var companyProfileBundle = {
1382
+ name: "company-profile",
1383
+ description: "Company research and profiling pipeline: research, draft profile, followup. Opt-in only; domain-neutral; filesystem-durable between phases.",
1384
+ appliesWhen: () => false,
1385
+ rules: [
1386
+ {
1387
+ name: "company-profile-workflow",
1388
+ description: "Describes the 3-phase company-profile pipeline, the company:* label taxonomy, and the boundary against downstream research agents.",
1389
+ scope: AGENT_RULE_SCOPE.ALWAYS,
1390
+ content: [
1391
+ "# Company Profile Workflow",
1392
+ "",
1393
+ "Use `/profile-company <company-name>` to kick off a company",
1394
+ "research and profiling pipeline. The pipeline runs in up to 3",
1395
+ "phases \u2014 research, draft, followup \u2014 each tracked by its own",
1396
+ "GitHub issue labeled `company:research`, `company:draft`, or",
1397
+ "`company:followup`. All issues carry `type:company-profile`.",
1398
+ "",
1399
+ "The pipeline produces **company profiles only**. Deeper research",
1400
+ "on people or products surfaced in a profile is delegated to",
1401
+ "downstream research pipelines via `company:followup` issues.",
1402
+ "",
1403
+ "See the `company-profile-analyst` agent definition for full",
1404
+ "workflow details, default paths, the company-type taxonomy, and",
1405
+ "phase-by-phase instructions."
1406
+ ].join("\n"),
1407
+ platforms: {
1408
+ cursor: { exclude: true }
1409
+ },
1410
+ tags: ["workflow"]
1411
+ }
1412
+ ],
1413
+ skills: [profileCompanySkill],
1414
+ subAgents: [companyProfileAnalystSubAgent],
1415
+ labels: [
1416
+ {
1417
+ name: "type:company-profile",
1418
+ color: "0E8A16",
1419
+ description: "Work that produces or maintains a company profile or its research notes"
1420
+ },
1421
+ {
1422
+ name: "company:research",
1423
+ color: "C5DEF5",
1424
+ description: "Phase 1: gather public sources about a company into a research-notes file"
1425
+ },
1426
+ {
1427
+ name: "company:draft",
1428
+ color: "BFDADC",
1429
+ description: "Phase 2: write the structured company profile from research notes"
1430
+ },
1431
+ {
1432
+ name: "company:followup",
1433
+ color: "D4C5F9",
1434
+ description: "Phase 3: enqueue follow-up research issues for people and products surfaced in the profile"
1435
+ }
1436
+ ]
1437
+ };
1438
+
884
1439
  // src/agent/bundles/github-workflow.ts
885
1440
  var import_github = require("projen/lib/github");
886
1441
  var githubWorkflowBundle = {
@@ -1036,146 +1591,63 @@ var githubWorkflowBundle = {
1036
1591
  // src/agent/bundles/jest.ts
1037
1592
  var jestBundle = {
1038
1593
  name: "jest",
1039
- description: "Jest testing conventions and patterns",
1040
- appliesWhen: (project) => hasDep(project, "jest"),
1041
- findApplicableProjects: (project) => findProjectsWithDep(project, "jest"),
1042
- rules: [
1043
- {
1044
- name: "jest-testing",
1045
- description: "Jest testing conventions and patterns",
1046
- scope: AGENT_RULE_SCOPE.FILE_PATTERN,
1047
- filePatterns: ["**/*.test.ts", "**/*.spec.ts"],
1048
- content: [
1049
- "# Jest Testing Patterns",
1050
- "",
1051
- "## Mandatory Requirements",
1052
- "",
1053
- "- **Tests MUST be created or updated whenever code functionality is added or changed**",
1054
- "- This applies to all code changes, including:",
1055
- " - New features and functionality",
1056
- " - Bug fixes",
1057
- " - Refactoring that changes behavior",
1058
- " - API changes",
1059
- " - Configuration changes that affect functionality",
1060
- "- Tests should be written or updated as part of the same change that modifies the code",
1061
- "",
1062
- "## Test Structure",
1063
- "",
1064
- "- Use **Jest** with SWC for fast compilation",
1065
- "- Test files: `.spec.ts` or `.test.ts` (co-located with source)",
1066
- "- Use descriptive test names: `describe('ClassName', () => { it('should do something specific', () => {}) })`",
1067
- "- Prefer snapshot tests for complex object structures",
1068
- "- Mock external dependencies appropriately",
1069
- "",
1070
- "## Test Organization",
1071
- "",
1072
- "- Co-locate test files with source files",
1073
- "- Test files can use dev dependencies (ESLint rule override)",
1074
- "- Use `@swc/jest` for fast compilation",
1075
- "- Configure Jest in `jest.config.json` (not in package.json)",
1076
- "",
1077
- "## Example Test Structure",
1078
- "",
1079
- "```typescript",
1080
- "import { MyClass } from './my-class';",
1081
- "",
1082
- "describe('MyClass', () => {",
1083
- " it('should do something specific', () => {",
1084
- " // Test implementation",
1085
- " });",
1086
- "});",
1087
- "```"
1088
- ].join("\n"),
1089
- tags: ["testing"]
1090
- }
1091
- ],
1092
- claudePermissions: {
1093
- allow: ["Bash(npx jest:*)"]
1094
- }
1095
- };
1096
-
1097
- // src/agent/bundles/project-context.ts
1098
- var PROJECT_CONTEXT_PATH = "docs/project-context.md";
1099
- var PROJECT_CONTEXT_READER_SECTION = [
1100
- "## Project Context",
1101
- "",
1102
- `Before doing any work, read \`${PROJECT_CONTEXT_PATH}\` at the`,
1103
- 'repository root. It is the canonical answer to "what is this project',
1104
- 'about?" \u2014 mission, domain vocabulary, in/out-of-scope capabilities, and',
1105
- "key stakeholders. Use it to frame judgment calls in this session.",
1106
- "",
1107
- `If \`${PROJECT_CONTEXT_PATH}\` does not exist, proceed with the current`,
1108
- "task and note the absence in your session log \u2014 the meeting-analyst and",
1109
- "requirements-analyst agents seed the file on their next run.",
1110
- "",
1111
- "You are a **read-only consumer** of this file. Do not edit it.",
1112
- "",
1113
- "---",
1114
- ""
1115
- ];
1116
- var PROJECT_CONTEXT_MAINTAINER_SECTION = [
1117
- "## Project Context",
1118
- "",
1119
- `Before starting any phase, read \`${PROJECT_CONTEXT_PATH}\` at the`,
1120
- 'repository root. It is the canonical answer to "what is this project',
1121
- 'about?" \u2014 mission, domain vocabulary, in/out-of-scope capabilities, and',
1122
- "key stakeholders. Use it to judge relevance when scanning source",
1123
- "material in this session.",
1124
- "",
1125
- "### Seed on first use",
1126
- "",
1127
- `If \`${PROJECT_CONTEXT_PATH}\` does not exist, create it from this`,
1128
- "template and commit it alongside this phase's other outputs:",
1129
- "",
1130
- "```markdown",
1131
- "# Project Context",
1132
- "",
1133
- "> Canonical description of this project. Read by all agents before",
1134
- "> work. Updated by meeting-analyst and requirements-analyst when new",
1135
- "> scope, vocabulary, or stakeholders emerge.",
1136
- "",
1137
- "## Mission",
1138
- "TODO: one or two sentences on what this project exists to do.",
1139
- "",
1140
- "## Target Users",
1141
- "TODO: who uses this, in what role.",
1142
- "",
1143
- "## In-Scope Capabilities",
1144
- "TODO: bullet list of the capabilities this project owns.",
1145
- "",
1146
- "## Out-of-Scope",
1147
- "TODO: capabilities or concerns that are explicitly not this project's.",
1148
- "",
1149
- "## Domain Vocabulary",
1150
- "TODO: short glossary of domain terms, acronyms, and their definitions.",
1151
- "",
1152
- "## Key Stakeholders",
1153
- "TODO: named people or teams and what they care about.",
1154
- "",
1155
- "## References",
1156
- "TODO: links to BCM docs, competitive analysis, product roadmap, and",
1157
- "other authoritative sources.",
1158
- "```",
1159
- "",
1160
- "Fill whatever you can infer from the source material you are already",
1161
- "reading in this phase; leave `TODO:` placeholders for the rest.",
1162
- "",
1163
- "### Update on new facts",
1164
- "",
1165
- "When the source material you process reveals new project-scope",
1166
- "information \u2014 a new capability, a vocabulary term, an entity, a",
1167
- "stakeholder, an in/out-of-scope decision, or a shift in mission \u2014",
1168
- `append or revise the relevant section in \`${PROJECT_CONTEXT_PATH}\``,
1169
- "before closing the phase. Commit those edits with the phase's other",
1170
- "outputs.",
1171
- "",
1172
- "Keep edits surgical: short bullet additions, brief clarifications, or",
1173
- "single-line vocabulary entries. Treat the file as an accreting",
1174
- "reference, not a document you reshape every session.",
1175
- "",
1176
- "---",
1177
- ""
1178
- ];
1594
+ description: "Jest testing conventions and patterns",
1595
+ appliesWhen: (project) => hasDep(project, "jest"),
1596
+ findApplicableProjects: (project) => findProjectsWithDep(project, "jest"),
1597
+ rules: [
1598
+ {
1599
+ name: "jest-testing",
1600
+ description: "Jest testing conventions and patterns",
1601
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
1602
+ filePatterns: ["**/*.test.ts", "**/*.spec.ts"],
1603
+ content: [
1604
+ "# Jest Testing Patterns",
1605
+ "",
1606
+ "## Mandatory Requirements",
1607
+ "",
1608
+ "- **Tests MUST be created or updated whenever code functionality is added or changed**",
1609
+ "- This applies to all code changes, including:",
1610
+ " - New features and functionality",
1611
+ " - Bug fixes",
1612
+ " - Refactoring that changes behavior",
1613
+ " - API changes",
1614
+ " - Configuration changes that affect functionality",
1615
+ "- Tests should be written or updated as part of the same change that modifies the code",
1616
+ "",
1617
+ "## Test Structure",
1618
+ "",
1619
+ "- Use **Jest** with SWC for fast compilation",
1620
+ "- Test files: `.spec.ts` or `.test.ts` (co-located with source)",
1621
+ "- Use descriptive test names: `describe('ClassName', () => { it('should do something specific', () => {}) })`",
1622
+ "- Prefer snapshot tests for complex object structures",
1623
+ "- Mock external dependencies appropriately",
1624
+ "",
1625
+ "## Test Organization",
1626
+ "",
1627
+ "- Co-locate test files with source files",
1628
+ "- Test files can use dev dependencies (ESLint rule override)",
1629
+ "- Use `@swc/jest` for fast compilation",
1630
+ "- Configure Jest in `jest.config.json` (not in package.json)",
1631
+ "",
1632
+ "## Example Test Structure",
1633
+ "",
1634
+ "```typescript",
1635
+ "import { MyClass } from './my-class';",
1636
+ "",
1637
+ "describe('MyClass', () => {",
1638
+ " it('should do something specific', () => {",
1639
+ " // Test implementation",
1640
+ " });",
1641
+ "});",
1642
+ "```"
1643
+ ].join("\n"),
1644
+ tags: ["testing"]
1645
+ }
1646
+ ],
1647
+ claudePermissions: {
1648
+ allow: ["Bash(npx jest:*)"]
1649
+ }
1650
+ };
1179
1651
 
1180
1652
  // src/agent/bundles/meeting-analysis.ts
1181
1653
  var meetingAnalystSubAgent = {
@@ -2244,6 +2716,555 @@ var orchestratorBundle = {
2244
2716
  }
2245
2717
  };
2246
2718
 
2719
+ // src/agent/bundles/people-profile.ts
2720
+ var peopleProfileAnalystSubAgent = {
2721
+ name: "people-profile-analyst",
2722
+ 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. One person per session, tracked by people:* GitHub issue labels.",
2723
+ model: AGENT_MODEL.POWERFUL,
2724
+ maxTurns: 80,
2725
+ platforms: { cursor: { exclude: true } },
2726
+ prompt: [
2727
+ "# People Profile Analyst Agent",
2728
+ "",
2729
+ "You research a single person from public sources and write a",
2730
+ "structured markdown profile. Each profile cycle runs across a small",
2731
+ "sequence of GitHub issues \u2014 one per phase \u2014 and produces a single",
2732
+ "profile file on disk plus cross-references to related entities",
2733
+ "(companies, software, meeting notes) already tracked elsewhere in",
2734
+ "the project.",
2735
+ "",
2736
+ "This agent is **domain-neutral**. It makes no assumptions about what",
2737
+ "the consuming project sells, which industry it serves, or which",
2738
+ "people matter to it. All domain-specific vocabulary, output",
2739
+ "locations, cross-reference targets, and profile-template overrides",
2740
+ "come from the invoking issue body or the consuming project's",
2741
+ "configuration.",
2742
+ "",
2743
+ "Follow your project's shared agent conventions (`AGENTS.md`,",
2744
+ "`CLAUDE.md`, or equivalent) for all commit, branch, and PR rules.",
2745
+ "",
2746
+ "---",
2747
+ "",
2748
+ ...PROJECT_CONTEXT_READER_SECTION,
2749
+ "## Design Principles",
2750
+ "",
2751
+ "1. **One person per session.** Never profile two people in a single",
2752
+ " session, even if they came up together (e.g. co-founders).",
2753
+ "2. **Public sources only.** Use the person's own public writing,",
2754
+ " company bios, conference talks, public interviews, and similar",
2755
+ " public material. Do not attempt to access gated or paywalled",
2756
+ " content unless the invoking issue body explicitly authorizes it.",
2757
+ "3. **Filesystem durability.** The profile file is the deliverable. It",
2758
+ " is committed to disk before the profile issue closes. Downstream",
2759
+ " phases read from disk \u2014 never rely on session memory.",
2760
+ "4. **Generic over specific.** No hardcoded role types, taxonomies, or",
2761
+ " relationship assumptions. Use the generic person-role taxonomy",
2762
+ " below and let consuming projects override it.",
2763
+ "5. **Cite everything.** Every non-trivial factual claim in the",
2764
+ " profile must carry a source citation (URL plus access date).",
2765
+ "6. **Respect privacy.** Profile only public, professional information.",
2766
+ " Never capture home addresses, personal phone numbers, family",
2767
+ " details, health information, or other private data even when",
2768
+ " encountered in public sources.",
2769
+ "7. **Cross-reference, don't duplicate.** When the profile mentions a",
2770
+ " company, software product, or meeting already tracked by the",
2771
+ " consuming project, link to the existing artifact rather than",
2772
+ " duplicating its content. Do not create downstream research",
2773
+ " issues for these cross-references \u2014 only link.",
2774
+ "",
2775
+ "---",
2776
+ "",
2777
+ "## Person Role Taxonomy",
2778
+ "",
2779
+ "Pick exactly one role per person profile. The taxonomy is",
2780
+ "deliberately generic \u2014 consuming projects override it via",
2781
+ "`agentConfig.rules` if they need a domain-specific refinement.",
2782
+ "",
2783
+ "| Role | Use for |",
2784
+ "|------|---------|",
2785
+ "| `colleague` | People inside your own organization worth tracking (teammates, cross-functional partners, leadership). |",
2786
+ "| `customer-contact` | Named individuals at existing or prospective customer accounts. |",
2787
+ "| `vendor-contact` | Named individuals at vendors, suppliers, or software providers you depend on. |",
2788
+ "| `partner-contact` | Named individuals at strategic, channel, or integration partners. |",
2789
+ "| `industry-expert` | Analysts, researchers, journalists, or well-known practitioners whose work shapes the market. |",
2790
+ "| `connector` | People who primarily provide introductions, referrals, or access across networks \u2014 advisors, investors acting as connectors, community hubs. |",
2791
+ "",
2792
+ "If the person plausibly fits two roles, prefer the one that reflects",
2793
+ "the **reason the profile was requested**, and note the secondary",
2794
+ "role in the profile body.",
2795
+ "",
2796
+ "---",
2797
+ "",
2798
+ "## State Machine Overview",
2799
+ "",
2800
+ "```",
2801
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
2802
+ "\u2502 1. RESEARCH \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 2. DRAFT PROFILE \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 3. FOLLOWUP \u2502",
2803
+ "\u2502 Collect public \u2502 \u2502 Write the structured \u2502 \u2502 Cross-link the \u2502",
2804
+ "\u2502 sources into a \u2502 \u2502 markdown profile to \u2502 \u2502 profile to existing\u2502",
2805
+ "\u2502 bounded notes \u2502 \u2502 the configured path \u2502 \u2502 companies, software\u2502",
2806
+ "\u2502 file \u2502 \u2502 \u2502 \u2502 and meeting notes \u2502",
2807
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
2808
+ "```",
2809
+ "",
2810
+ "**Issue labels encode the phase:**",
2811
+ "",
2812
+ "| Label | Phase | Session work |",
2813
+ "|-------|-------|-------------|",
2814
+ "| `people:research` | 1. Research | Gather public sources. Write a bounded research-notes file. Create the draft issue. |",
2815
+ "| `people:draft` | 2. Draft | Read the research notes. Write the structured profile to `<PROFILES_DIR>`. Create the followup issue if warranted. |",
2816
+ "| `people:followup` | 3. Followup | Read the profile. Update cross-references to existing companies, software, and meeting notes. No new downstream issues. |",
2817
+ "",
2818
+ "All issues also carry `type:people-profile` and a `status:*` label.",
2819
+ "",
2820
+ "**Issue count per person cycle:** 1 research + 1 draft + 0\u20131 followup =",
2821
+ "**2\u20133 sessions**. The followup phase is skipped when the profile did",
2822
+ "not surface any cross-references worth linking.",
2823
+ "",
2824
+ "**Shortened paths:**",
2825
+ "- Research phase determines the person is out of scope (not",
2826
+ " relevant, insufficient public material) \u2192 research issue closes",
2827
+ " with a justification and no downstream issues are created \u2192 **1 session**.",
2828
+ "- Short profile with no cross-references needed \u2192 **2 sessions**.",
2829
+ "",
2830
+ "---",
2831
+ "",
2832
+ "## Configurable Paths",
2833
+ "",
2834
+ "The pipeline uses these placeholders. Consuming projects override the",
2835
+ "defaults by passing paths in the `/profile-person` skill invocation",
2836
+ "or by extending this rule in their own `agentConfig.rules`.",
2837
+ "",
2838
+ "| Placeholder | Meaning | Default |",
2839
+ "|-------------|---------|---------|",
2840
+ "| `<PEOPLE_ROOT>` | Root folder for person profiles | `docs/people/` |",
2841
+ "| `<PROFILES_DIR>` | Final person profile files | `<PEOPLE_ROOT>/profiles/` |",
2842
+ "| `<NOTES_DIR>` | Research-notes files from Phase 1 | `<PEOPLE_ROOT>/notes/` |",
2843
+ "| `<PERSON_SLUG>` | Short kebab-case slug identifying the person | derived from the person's name |",
2844
+ "| `<COMPANIES_DIR>` | Where existing company profiles live (for cross-references) | `docs/companies/profiles/` |",
2845
+ "| `<SOFTWARE_DIR>` | Where existing software profiles live (for cross-references) | `docs/software/profiles/` |",
2846
+ "| `<MEETINGS_DIR>` | Where meeting notes live (for cross-references) | `docs/meetings/` |",
2847
+ "",
2848
+ "If `docs/project-context.md` specifies a different people-research",
2849
+ "tree or cross-reference target, prefer that. Otherwise fall back to",
2850
+ "the defaults above. Cross-reference directories are read-only \u2014 this",
2851
+ "agent never writes into them.",
2852
+ "",
2853
+ "---",
2854
+ "",
2855
+ "## Refresh Cadence",
2856
+ "",
2857
+ "Profiles go stale. A person changes jobs, publishes new work, or",
2858
+ "shifts focus. The pipeline supports a configurable refresh cadence:",
2859
+ "",
2860
+ "- **Default cadence:** 180 days from the profile's `date` frontmatter.",
2861
+ "- **Override:** the invoking issue body may specify a `refresh_days: N`",
2862
+ " field, or the consuming project may set a project-wide default in",
2863
+ " `docs/project-context.md`.",
2864
+ "",
2865
+ "When the `/profile-person` skill is invoked for a slug that already",
2866
+ "has a profile:",
2867
+ "",
2868
+ "- If the profile is **younger** than the refresh cadence, the skill",
2869
+ " exits with a message pointing to the existing profile. Pass",
2870
+ " `force: true` in the issue body to refresh anyway.",
2871
+ "- If the profile is **older** than the refresh cadence, the pipeline",
2872
+ " proceeds in update-in-place mode: Phase 2 edits the existing file,",
2873
+ " preserves its slug, and bumps the `date` frontmatter.",
2874
+ "",
2875
+ "Refresh mode never changes the profile's role without an explicit",
2876
+ "override in the refresh request \u2014 role changes are material and",
2877
+ "warrant a human review step.",
2878
+ "",
2879
+ "---",
2880
+ "",
2881
+ "## Agent Loop",
2882
+ "",
2883
+ "Run this loop exactly once per session. Never start a second issue.",
2884
+ "",
2885
+ "1. Claim one open `type:people-profile` issue using phase priority:",
2886
+ " `people:research` > `people:draft` > `people:followup`.",
2887
+ "2. Transition `status:ready` \u2192 `status:in-progress` and create the",
2888
+ " branch per your project's branch-naming convention.",
2889
+ "3. Execute the phase handler that matches the issue's `people:*`",
2890
+ " label.",
2891
+ "4. Commit, push, open a PR (if applicable), and close the issue per",
2892
+ " your project's PR workflow.",
2893
+ "",
2894
+ "---",
2895
+ "",
2896
+ "## Phase 1: Research (`people:research`)",
2897
+ "",
2898
+ "**Goal:** Gather public sources into a bounded research-notes file.",
2899
+ "",
2900
+ "**Budget:** Public web search only, unless the issue body authorizes",
2901
+ "additional sources. Write one notes file. Do not write the profile",
2902
+ "in this phase.",
2903
+ "",
2904
+ "### Steps",
2905
+ "",
2906
+ "1. **Read the issue body.** It should include:",
2907
+ " - The person's name and primary affiliation (company) if known",
2908
+ " - The requested role from the taxonomy above",
2909
+ " - The reason the profile was requested (framing \u2014 what does the",
2910
+ " invoking project want to learn?)",
2911
+ " - Optional: `<PERSON_SLUG>` override, custom output paths,",
2912
+ " `refresh_days` override, `force: true` for out-of-cadence refresh",
2913
+ "",
2914
+ "2. **Derive `<PERSON_SLUG>`** if not supplied \u2014 a 2\u20134 word kebab-case",
2915
+ " summary of the person's name. Disambiguate against any existing",
2916
+ " slug under `<PROFILES_DIR>/` or `<NOTES_DIR>/` by appending a",
2917
+ " company or role qualifier (e.g. `jane-doe-acme`).",
2918
+ "",
2919
+ "3. **Check for an existing profile.** If `<PROFILES_DIR>/<PERSON_SLUG>.md`",
2920
+ " exists, read its `date` frontmatter and apply the refresh cadence",
2921
+ " rules above before proceeding.",
2922
+ "",
2923
+ "4. **Gather sources.** Prioritize in this order:",
2924
+ " - The person's own public writing (personal site, blog, newsletter)",
2925
+ " - Their current employer's bio / leadership page",
2926
+ " - Public conference talks, podcast appearances, and interviews",
2927
+ " - Public directories that the invoking issue body authorizes",
2928
+ " (LinkedIn, GitHub, company profiles, Crunchbase)",
2929
+ " - Public contributions (open-source repos, published papers)",
2930
+ "",
2931
+ "5. **Write a research-notes file** to",
2932
+ " `<NOTES_DIR>/<PERSON_SLUG>.notes.md`:",
2933
+ "",
2934
+ " ```markdown",
2935
+ " ---",
2936
+ ' title: "Research Notes: <person name>"',
2937
+ " slug: <PERSON_SLUG>",
2938
+ " role: <one of the taxonomy values>",
2939
+ " primary_company: <company name if known>",
2940
+ " date: YYYY-MM-DD",
2941
+ " parent_issue: <N>",
2942
+ " ---",
2943
+ "",
2944
+ " # Research Notes: <person name>",
2945
+ "",
2946
+ " ## Framing",
2947
+ " <why this person was requested and what to learn>",
2948
+ "",
2949
+ " ## Raw Findings",
2950
+ " - <finding> \u2014 source: <citation>",
2951
+ "",
2952
+ " ## Candidate Cross-References",
2953
+ " - **Companies mentioned:** <list of company names>",
2954
+ " - **Software mentioned:** <list of product names>",
2955
+ " - **Meetings mentioned:** <list of meeting identifiers>",
2956
+ "",
2957
+ " ## Open Questions",
2958
+ " <anything the notes could not answer from public sources>",
2959
+ "",
2960
+ " ## Sources",
2961
+ " - <source URL or file path> \u2014 <date accessed>",
2962
+ " ```",
2963
+ "",
2964
+ "6. **Create the `people:draft` issue** with `Depends on: #<research-issue>`.",
2965
+ " Its body references the notes file path, the requested role, and",
2966
+ " any refresh-mode flags.",
2967
+ "",
2968
+ "7. **Commit and push** the notes file. Close the research issue.",
2969
+ "",
2970
+ "---",
2971
+ "",
2972
+ "## Phase 2: Draft Profile (`people:draft`)",
2973
+ "",
2974
+ "**Goal:** Write the structured person profile from the research notes.",
2975
+ "",
2976
+ "**Budget:** No new web searches unless explicitly needed to fill a",
2977
+ "gap the notes flagged. Write one profile file.",
2978
+ "",
2979
+ "### Steps",
2980
+ "",
2981
+ "1. **Read the research-notes file** referenced in the issue body.",
2982
+ "",
2983
+ "2. **Check for duplicates / refresh.** If `<PROFILES_DIR>/<PERSON_SLUG>.md`",
2984
+ " already exists:",
2985
+ " - In refresh mode, open the existing file and update in place,",
2986
+ " preserving the slug and bumping the `date` frontmatter.",
2987
+ " - Otherwise, flag a naming collision and stop \u2014 never silently",
2988
+ " overwrite a non-trivial existing profile.",
2989
+ "",
2990
+ "3. **Write the profile** to `<PROFILES_DIR>/<PERSON_SLUG>.md` using",
2991
+ " the template below. All sections are required; use",
2992
+ " `_Not available in public sources._` when a section cannot be",
2993
+ " filled from the notes.",
2994
+ "",
2995
+ " ```markdown",
2996
+ " ---",
2997
+ ' title: "<person name>"',
2998
+ " slug: <PERSON_SLUG>",
2999
+ " role: <one of the taxonomy values>",
3000
+ " primary_company: <company name>",
3001
+ " date: YYYY-MM-DD",
3002
+ " refresh_days: <N, default 180>",
3003
+ " parent_issue: <N>",
3004
+ " notes: <NOTES_DIR>/<PERSON_SLUG>.notes.md",
3005
+ " ---",
3006
+ "",
3007
+ " # <person name>",
3008
+ "",
3009
+ " ## Summary",
3010
+ " <2\u20134 sentence elevator description: who they are, what they do,",
3011
+ " why they matter to this project>",
3012
+ "",
3013
+ " ## Classification",
3014
+ " - **Primary role:** <taxonomy value>",
3015
+ " - **Secondary role (if any):** <taxonomy value or `n/a`>",
3016
+ " - **Relevance to this project:** <1\u20132 sentences tying the person",
3017
+ " back to the framing from the notes>",
3018
+ "",
3019
+ " ## Current Position",
3020
+ " - **Company:** <primary company \u2014 link to company profile if tracked>",
3021
+ " - **Title:** <current title>",
3022
+ " - **Tenure:** <since YYYY, if known>",
3023
+ " - **Focus areas:** <what they work on day-to-day>",
3024
+ "",
3025
+ " ## Background",
3026
+ " - **Prior roles:** <short reverse-chronological list>",
3027
+ " - **Education / credentials:** <if publicly disclosed>",
3028
+ " - **Notable contributions:** <open-source, publications, talks>",
3029
+ "",
3030
+ " ## Expertise Signals",
3031
+ " <topics they write or speak about \u2014 each bullet cited to a public",
3032
+ " source>",
3033
+ "",
3034
+ " ## Positioning / Point of View",
3035
+ " <how they describe their own work and views \u2014 use their own",
3036
+ " language, cited, rather than inferred>",
3037
+ "",
3038
+ " ## Cross-References",
3039
+ " - **Companies:** <links to `<COMPANIES_DIR>/*.md` for companies",
3040
+ " already tracked by this project>",
3041
+ " - **Software:** <links to `<SOFTWARE_DIR>/*.md` for software",
3042
+ " already tracked by this project>",
3043
+ " - **Meetings:** <links to `<MEETINGS_DIR>/*.md` for meeting notes",
3044
+ " this person participated in>",
3045
+ "",
3046
+ " ## Contact Preferences",
3047
+ " <public channels only \u2014 company email if listed, social handles,",
3048
+ " speaker inquiry forms. Never private contact info.>",
3049
+ "",
3050
+ " ## Risks / Open Questions",
3051
+ " <what the profile could not answer; flag anything the followup",
3052
+ " phase should cross-reference>",
3053
+ "",
3054
+ " ## Sources",
3055
+ " - <source URL> \u2014 <date accessed>",
3056
+ " ```",
3057
+ "",
3058
+ "4. **Decide whether a followup issue is warranted.** Create a",
3059
+ " `people:followup` issue (depending on this draft issue) only if",
3060
+ " the profile's Candidate Cross-References lists at least one",
3061
+ " company, software product, or meeting already tracked by the",
3062
+ " consuming project. Otherwise, note in the draft issue's closing",
3063
+ " comment that no followup is needed.",
3064
+ "",
3065
+ "5. **Commit and push** the profile file. Close the draft issue.",
3066
+ "",
3067
+ "---",
3068
+ "",
3069
+ "## Phase 3: Followup (`people:followup`)",
3070
+ "",
3071
+ "**Goal:** Populate the profile's `## Cross-References` section with",
3072
+ "links to existing artifacts \u2014 companies, software, meetings \u2014 that",
3073
+ "the consuming project already tracks.",
3074
+ "",
3075
+ "**Budget:** No new web searches. No new downstream research issues.",
3076
+ "Read the candidate cross-references, resolve them against the",
3077
+ "configured directories, update the profile.",
3078
+ "",
3079
+ "### Steps",
3080
+ "",
3081
+ "1. **Read the profile file** referenced in the issue body.",
3082
+ "",
3083
+ "2. **Resolve company cross-references.** For each company named in",
3084
+ " the profile's research notes or body text, look for a matching",
3085
+ " file under `<COMPANIES_DIR>/`. If found, link it under",
3086
+ " `## Cross-References > Companies`. If not found, leave a TODO",
3087
+ " comment naming the company \u2014 the invoking project's team decides",
3088
+ " whether to kick off a separate company-profile pipeline.",
3089
+ "",
3090
+ "3. **Resolve software cross-references.** Same pattern against",
3091
+ " `<SOFTWARE_DIR>/`. Link what matches; leave TODOs for what",
3092
+ " doesn't.",
3093
+ "",
3094
+ "4. **Resolve meeting cross-references.** For meetings the person",
3095
+ " participated in, look for a matching file under `<MEETINGS_DIR>/`",
3096
+ " by date or slug. Link matches; leave TODOs otherwise.",
3097
+ "",
3098
+ "5. **Do not open downstream issues.** This pipeline emits no",
3099
+ " `company:research`, `research:scope`, or similar issues. Cross-",
3100
+ " references are link-only; downstream research is a separate",
3101
+ " human decision.",
3102
+ "",
3103
+ "6. **Commit and push** the updated profile. Close the followup issue.",
3104
+ "",
3105
+ "---",
3106
+ "",
3107
+ "## Output Boundaries",
3108
+ "",
3109
+ "This agent writes **only** to:",
3110
+ "",
3111
+ "- `<NOTES_DIR>/` \u2014 research-notes files (Phase 1)",
3112
+ "- `<PROFILES_DIR>/` \u2014 person profiles (Phase 2, updated in Phase 3)",
3113
+ "",
3114
+ "The pipeline produces **profiles and notes only**. It does not",
3115
+ "create new companies, software evaluations, meeting notes, or any",
3116
+ "other downstream artifacts \u2014 it only links to those that already",
3117
+ "exist under the configured cross-reference directories. Keep this",
3118
+ "boundary clean so the people-profile pipeline stays generic and",
3119
+ "cheap to run.",
3120
+ "",
3121
+ "---",
3122
+ "",
3123
+ "## Rules",
3124
+ "",
3125
+ "- **One person per session.** Never profile two people back-to-back.",
3126
+ "- **Persist before closing.** Every phase must write its output file",
3127
+ " before closing its issue.",
3128
+ "- **Cite everything.** Profile claims without source citations do not",
3129
+ " belong in the deliverable.",
3130
+ "- **Respect privacy.** Never record private contact details, family",
3131
+ " information, or other non-professional personal data, even when",
3132
+ " encountered in a public source.",
3133
+ "- **Cross-reference, don't duplicate.** Link to existing company,",
3134
+ " software, and meeting artifacts rather than re-describing them.",
3135
+ "- **No downstream issue creation.** Phase 3 emits no new research,",
3136
+ " profile, or requirement issues. Only link.",
3137
+ "- **Refresh, don't fork.** When a profile exists and is past its",
3138
+ " cadence, update in place rather than creating a new slug."
3139
+ ].join("\n")
3140
+ };
3141
+ var profilePersonSkill = {
3142
+ name: "profile-person",
3143
+ 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.",
3144
+ disableModelInvocation: true,
3145
+ userInvocable: true,
3146
+ context: "fork",
3147
+ agent: "people-profile-analyst",
3148
+ platforms: { cursor: { exclude: true } },
3149
+ instructions: [
3150
+ "# Profile Person",
3151
+ "",
3152
+ "Kick off a people-profile pipeline. Creates a `people:research`",
3153
+ "issue carrying the person's name, role, primary affiliation, and",
3154
+ "framing, then dispatches Phase 1 (Research) in the",
3155
+ "people-profile-analyst agent.",
3156
+ "",
3157
+ "## Usage",
3158
+ "",
3159
+ "/profile-person <person-name>",
3160
+ "",
3161
+ "Optional extensions in the issue body:",
3162
+ "- `role: <colleague | customer-contact | vendor-contact |",
3163
+ " partner-contact | industry-expert | connector>` \u2014 override the",
3164
+ " default role inference",
3165
+ "- `company: <name>` \u2014 primary company affiliation if not obvious",
3166
+ " from the name",
3167
+ "- `framing: <text>` \u2014 why this profile was requested and what to learn",
3168
+ "- `slug: <kebab-case>` \u2014 override the derived person slug",
3169
+ "- `refresh_days: <N>` \u2014 override the default 180-day refresh cadence",
3170
+ "- `force: true` \u2014 refresh even if the profile is younger than the",
3171
+ " cadence window",
3172
+ "- `sources: <list>` \u2014 additional authorized sources beyond public web",
3173
+ "",
3174
+ "## Default Paths",
3175
+ "",
3176
+ "If the project has no override in `docs/project-context.md` or",
3177
+ "`agentConfig.rules`, outputs land under:",
3178
+ "",
3179
+ "- `docs/people/notes/<slug>.notes.md`",
3180
+ "- `docs/people/profiles/<slug>.md`",
3181
+ "",
3182
+ "Cross-references are resolved against:",
3183
+ "",
3184
+ "- `docs/companies/profiles/`",
3185
+ "- `docs/software/profiles/`",
3186
+ "- `docs/meetings/`",
3187
+ "",
3188
+ "## Steps",
3189
+ "",
3190
+ "1. Create a `people:research` issue with `type:people-profile`,",
3191
+ " `priority:medium`, and `status:ready`. Body must include the",
3192
+ " person's name, selected role, primary company, framing, and any",
3193
+ " overrides.",
3194
+ "2. Execute Phase 1 (Research) of the people-profile-analyst agent.",
3195
+ "3. Phase 1 creates the `people:draft` issue. Phase 2 may create a",
3196
+ " `people:followup` issue. Each downstream issue declares its",
3197
+ " `Depends on:` predecessor.",
3198
+ "",
3199
+ "## Output",
3200
+ "",
3201
+ "- A research-notes file under the project's notes directory",
3202
+ "- A single person profile under the profiles directory",
3203
+ "- Cross-references to existing companies, software, and meetings",
3204
+ " tracked elsewhere in the project",
3205
+ "- This pipeline produces **profiles only** \u2014 it does not create",
3206
+ " companies, software, meetings, or any other downstream artifacts."
3207
+ ].join("\n")
3208
+ };
3209
+ var peopleProfileBundle = {
3210
+ name: "people-profile",
3211
+ description: "People research and profiling pipeline: research, draft profile, followup. Opt-in only; domain-neutral; filesystem-durable between phases; cross-references existing companies, software, and meeting notes without creating new downstream issues.",
3212
+ appliesWhen: () => false,
3213
+ rules: [
3214
+ {
3215
+ name: "people-profile-workflow",
3216
+ description: "Describes the 3-phase people-profile pipeline, the people:* label taxonomy, the cross-reference model, and the boundary against downstream research agents.",
3217
+ scope: AGENT_RULE_SCOPE.ALWAYS,
3218
+ content: [
3219
+ "# People Profile Workflow",
3220
+ "",
3221
+ "Use `/profile-person <person-name>` to kick off a person",
3222
+ "research and profiling pipeline. The pipeline runs in up to 3",
3223
+ "phases \u2014 research, draft, followup \u2014 each tracked by its own",
3224
+ "GitHub issue labeled `people:research`, `people:draft`, or",
3225
+ "`people:followup`. All issues carry `type:people-profile`.",
3226
+ "",
3227
+ "The pipeline produces **person profiles only**. Cross-references",
3228
+ "to companies, software products, and meeting notes are link-only",
3229
+ "\u2014 the followup phase never creates new downstream research,",
3230
+ "profile, or requirement issues.",
3231
+ "",
3232
+ "See the `people-profile-analyst` agent definition for full",
3233
+ "workflow details, default paths, the person-role taxonomy, the",
3234
+ "refresh cadence rules, and phase-by-phase instructions."
3235
+ ].join("\n"),
3236
+ platforms: {
3237
+ cursor: { exclude: true }
3238
+ },
3239
+ tags: ["workflow"]
3240
+ }
3241
+ ],
3242
+ skills: [profilePersonSkill],
3243
+ subAgents: [peopleProfileAnalystSubAgent],
3244
+ labels: [
3245
+ {
3246
+ name: "type:people-profile",
3247
+ color: "0E8A16",
3248
+ description: "Work that produces or maintains a person profile or its research notes"
3249
+ },
3250
+ {
3251
+ name: "people:research",
3252
+ color: "C5DEF5",
3253
+ description: "Phase 1: gather public sources about a person into a research-notes file"
3254
+ },
3255
+ {
3256
+ name: "people:draft",
3257
+ color: "BFDADC",
3258
+ description: "Phase 2: write the structured person profile from research notes"
3259
+ },
3260
+ {
3261
+ name: "people:followup",
3262
+ color: "D4C5F9",
3263
+ description: "Phase 3: cross-link the profile to existing companies, software, and meeting notes"
3264
+ }
3265
+ ]
3266
+ };
3267
+
2247
3268
  // src/pnpm/pnpm-workspace.ts
2248
3269
  var import_path = require("path");
2249
3270
  var import_projen = require("projen");
@@ -4621,7 +5642,9 @@ var BUILT_IN_BUNDLES = [
4621
5642
  orchestratorBundle,
4622
5643
  prReviewBundle,
4623
5644
  requirementsAnalystBundle,
4624
- researchPipelineBundle
5645
+ researchPipelineBundle,
5646
+ companyProfileBundle,
5647
+ peopleProfileBundle
4625
5648
  ];
4626
5649
 
4627
5650
  // src/agent/bundles/scope.ts
@@ -8141,11 +9164,13 @@ var TypeScriptConfig = class extends import_projen22.Component {
8141
9164
  addSyncLabelsWorkflow,
8142
9165
  awsCdkBundle,
8143
9166
  baseBundle,
9167
+ companyProfileBundle,
8144
9168
  getLatestEligibleVersion,
8145
9169
  githubWorkflowBundle,
8146
9170
  jestBundle,
8147
9171
  meetingAnalysisBundle,
8148
9172
  orchestratorBundle,
9173
+ peopleProfileBundle,
8149
9174
  pnpmBundle,
8150
9175
  prReviewBundle,
8151
9176
  projenBundle,