@higrowth/cli 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +372 -30
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -703,7 +703,7 @@ just say which one \u2014 you don't have to redo the whole interview."*
|
|
|
703
703
|
// src/skills/marketing-strategy.ts
|
|
704
704
|
var MARKETING_STRATEGY = `---
|
|
705
705
|
name: higrowth-marketing-strategy
|
|
706
|
-
description: Helps the user interpret a Higrowth diagnostic, choose a bounded scoped-plan area, and shape the next 2-4 week sprint. Use when the user wants to talk through their report, decide what to ship, ask what can be fixed in an area, or plan.
|
|
706
|
+
description: Helps the user interpret a Higrowth diagnostic, choose a bounded scoped-plan or topic-roadmap area, review imagination hypotheses, and shape the next 2-4 week sprint. Use when the user wants to talk through their report, decide what to ship, ask what can be fixed in an area, create/update content from roadmap gaps, or plan.
|
|
707
707
|
allowed-tools: mcp__higrowth__execute_typescript
|
|
708
708
|
---
|
|
709
709
|
|
|
@@ -717,7 +717,8 @@ measurable scoped plan that can move the needle.
|
|
|
717
717
|
|
|
718
718
|
Trigger on: "what should I focus on", "walk me through my report",
|
|
719
719
|
"prioritize this", "what's the move", "plan my sprint", "what can we
|
|
720
|
-
fix in [area/topic/page]"
|
|
720
|
+
fix in [area/topic/page]", "what are the gaps in this topic", "plan this
|
|
721
|
+
roadmap", "what new pages or updates should we create".
|
|
721
722
|
|
|
722
723
|
## Mental model
|
|
723
724
|
|
|
@@ -725,7 +726,27 @@ Plans are not giant backlogs. A good plan is a scoped intervention:
|
|
|
725
726
|
one topic area, page cluster, gap type, or conversion slice with enough
|
|
726
727
|
evidence to act and narrow enough boundaries to avoid conflicting work.
|
|
727
728
|
|
|
728
|
-
|
|
729
|
+
The planning stack has five layers:
|
|
730
|
+
|
|
731
|
+
1. **Answer map** \u2014 what questions the site answers for which persona
|
|
732
|
+
and decision stage.
|
|
733
|
+
2. **Decision candidates** \u2014 executable moves grounded in answer cells,
|
|
734
|
+
gaps, GSC, GA, strategy, and conflict checks.
|
|
735
|
+
3. **Topic roadmap** \u2014 the topic-area execution ledger: new pages to
|
|
736
|
+
create, pages to refresh, consolidation/removal, internal links, and
|
|
737
|
+
measurement/setup rows. When the user asks about a topic's gaps or
|
|
738
|
+
roadmap, these rows are a first-class planning source.
|
|
739
|
+
4. **Imagination candidates** \u2014 adjacent hypotheses HG can infer from
|
|
740
|
+
weak or missing answers. They are ideas only.
|
|
741
|
+
5. **Scoped plans** \u2014 a small selected scope that generates execution
|
|
742
|
+
items from roadmap rows, scoped gaps, pages, answer cells, or decision
|
|
743
|
+
candidates.
|
|
744
|
+
|
|
745
|
+
Rank by **leverage, evidence, and executability**, not raw opportunity count.
|
|
746
|
+
Never create work orders directly from imagination candidates. Promote
|
|
747
|
+
good imagination candidates into decision candidates first, then plan.
|
|
748
|
+
Roadmap rows do not need promotion: use them directly when the user's
|
|
749
|
+
intent is to execute a topic roadmap.
|
|
729
750
|
|
|
730
751
|
## The conversation
|
|
731
752
|
|
|
@@ -745,41 +766,259 @@ Anything missing or recently changed?"*
|
|
|
745
766
|
Use the answer to steer scope selection. Recent launches, product
|
|
746
767
|
changes, seasonality, and sales priorities should shape what you plan.
|
|
747
768
|
|
|
748
|
-
### Step 2 \u2014
|
|
769
|
+
### Step 2 \u2014 Resolve the topic or area
|
|
749
770
|
|
|
750
771
|
If the user named an area, use it as the scope query. If not, help them
|
|
751
772
|
pick one from the diagnostic: a pillar, subtopic, page cluster, gap type,
|
|
752
773
|
or conversion issue.
|
|
753
774
|
|
|
775
|
+
Find the most likely topic/pillar id before generating plans. Use the
|
|
776
|
+
current API surface available in the MCP harness; if the harness exposes
|
|
777
|
+
topic search, use it. If not, use scoped candidates with the user's query
|
|
778
|
+
and read the returned \`topicId\`.
|
|
779
|
+
|
|
754
780
|
\`\`\`ts
|
|
755
781
|
const q = userIntent || 'highest leverage scoped fixes';
|
|
782
|
+
const firstPass = await api.get(
|
|
783
|
+
\`/api/entities/\${entityId}/plan-scopes/candidates?q=\${encodeURIComponent(q)}&limit=8&maxItems=8\`
|
|
784
|
+
);
|
|
785
|
+
const topicId = firstPass.candidates.find(c => c.topicId)?.topicId;
|
|
786
|
+
\`\`\`
|
|
787
|
+
|
|
788
|
+
### Step 3 \u2014 Check source signal before planning
|
|
789
|
+
|
|
790
|
+
Do not jump straight to a plan if the answer map and decision registry
|
|
791
|
+
are empty. HG should reason from the rich signal it already gathered.
|
|
792
|
+
|
|
793
|
+
\`\`\`ts
|
|
794
|
+
const answerSummary = topicId
|
|
795
|
+
? await api.get(\`/api/entities/\${entityId}/answer-map/summary?topicId=\${topicId}\`)
|
|
796
|
+
: null;
|
|
797
|
+
console.log(answerSummary?.summary);
|
|
798
|
+
\`\`\`
|
|
799
|
+
|
|
800
|
+
If the summary has no cells, compute it:
|
|
801
|
+
|
|
802
|
+
\`\`\`ts
|
|
803
|
+
if (topicId && (!answerSummary || answerSummary.summary.totalCells === 0)) {
|
|
804
|
+
await api.post(\`/api/entities/\${entityId}/answer-map/compute\`, {
|
|
805
|
+
topicId,
|
|
806
|
+
limit: 500,
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
\`\`\`
|
|
810
|
+
|
|
811
|
+
Then refresh decision candidates for the topic or page slice:
|
|
812
|
+
|
|
813
|
+
\`\`\`ts
|
|
814
|
+
await api.post(\`/api/entities/\${entityId}/decision-candidates/refresh\`, {
|
|
815
|
+
topicId,
|
|
816
|
+
limit: 500,
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
const decisions = await api.get(
|
|
820
|
+
\`/api/entities/\${entityId}/decision-candidates?topicId=\${topicId}&status=candidate&limit=50\`
|
|
821
|
+
);
|
|
822
|
+
console.log(decisions.candidates.slice(0, 10));
|
|
823
|
+
\`\`\`
|
|
824
|
+
|
|
825
|
+
If answer-map compute still returns little or no signal, say so. The
|
|
826
|
+
right prerequisite may be a scan, GSC/GA connection, KB population, or
|
|
827
|
+
pillar analysis. Do not fabricate a strategic plan from thin data.
|
|
828
|
+
|
|
829
|
+
Also check the topic roadmap when the user asks about a topic, gaps,
|
|
830
|
+
new content, content updates, or comprehensiveness:
|
|
831
|
+
|
|
832
|
+
\`\`\`ts
|
|
833
|
+
const roadmap = topicId
|
|
834
|
+
? await api.get(\`/api/topics/\${topicId}/roadmap\`)
|
|
835
|
+
: null;
|
|
836
|
+
const openRoadmapItems =
|
|
837
|
+
roadmap?.items?.filter(item => item.status === 'open') ?? [];
|
|
838
|
+
|
|
839
|
+
console.log(openRoadmapItems.map(item => ({
|
|
840
|
+
id: item.id,
|
|
841
|
+
actionType: item.actionType,
|
|
842
|
+
title: item.title,
|
|
843
|
+
targetPageUrl: item.targetPageUrl,
|
|
844
|
+
queries: item.queries?.slice(0, 5) ?? [],
|
|
845
|
+
existingCoverage: item.coverage?.length ?? 0,
|
|
846
|
+
})));
|
|
847
|
+
\`\`\`
|
|
848
|
+
|
|
849
|
+
Roadmap rows answer: what new pages to create, which pages to update,
|
|
850
|
+
what to consolidate or remove, where internal links are missing, and
|
|
851
|
+
what measurement/setup work blocks confidence. Treat open roadmap rows
|
|
852
|
+
as source evidence, not as loose suggestions.
|
|
853
|
+
|
|
854
|
+
### Step 4 \u2014 Use imagination only when useful
|
|
855
|
+
|
|
856
|
+
When the user asks "what else could we do here?", "what are we missing?",
|
|
857
|
+
or the decision registry feels too narrow, generate imagination
|
|
858
|
+
candidates. This is HG's ideation layer: adjacent questions and content
|
|
859
|
+
angles extrapolated from answer-map gaps.
|
|
860
|
+
|
|
861
|
+
\`\`\`ts
|
|
862
|
+
const imagination = await api.post(
|
|
863
|
+
\`/api/entities/\${entityId}/imagination-candidates/generate\`,
|
|
864
|
+
{ topicId, limit: 20 }
|
|
865
|
+
);
|
|
866
|
+
console.log(imagination.candidates);
|
|
867
|
+
\`\`\`
|
|
868
|
+
|
|
869
|
+
Review these critically with the user. Reject weak, duplicate, or noisy
|
|
870
|
+
hypotheses:
|
|
871
|
+
|
|
872
|
+
\`\`\`ts
|
|
873
|
+
await api.post(\`/api/entities/\${entityId}/imagination-candidates/\${id}/reject\`, {
|
|
874
|
+
reason: 'Duplicate of an existing page angle',
|
|
875
|
+
});
|
|
876
|
+
\`\`\`
|
|
877
|
+
|
|
878
|
+
Promote only the best 1-3 ideas. Promotion creates decision candidates;
|
|
879
|
+
it still does not create work orders or plan items.
|
|
880
|
+
|
|
881
|
+
\`\`\`ts
|
|
882
|
+
const promoted = await api.post(
|
|
883
|
+
\`/api/entities/\${entityId}/imagination-candidates/\${id}/promote\`
|
|
884
|
+
);
|
|
885
|
+
console.log(promoted.candidate);
|
|
886
|
+
\`\`\`
|
|
887
|
+
|
|
888
|
+
After promotion, re-run scoped candidates so promoted ideas can compete
|
|
889
|
+
with observed-gap candidates.
|
|
890
|
+
|
|
891
|
+
### Step 5 \u2014 Choose a bounded scope
|
|
892
|
+
|
|
893
|
+
If the user explicitly asked to execute a topic roadmap, prefer a
|
|
894
|
+
roadmap-derived scope over a generic candidate. The open roadmap rows
|
|
895
|
+
are the scope thesis.
|
|
896
|
+
|
|
897
|
+
\`\`\`ts
|
|
898
|
+
function compactRoadmapSourceId(topicId, items) {
|
|
899
|
+
const key = (items ?? [])
|
|
900
|
+
.map(item => item.id)
|
|
901
|
+
.sort()
|
|
902
|
+
.join('_')
|
|
903
|
+
.replace(/[^a-zA-Z0-9_-]/g, '')
|
|
904
|
+
.slice(0, 96) || 'open';
|
|
905
|
+
return \`roadmap_topic_v6_\${topicId}_\${key}\`;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function analysisTypesFromRoadmap(items) {
|
|
909
|
+
const types = new Set(['supply_tactical']);
|
|
910
|
+
for (const item of items ?? []) {
|
|
911
|
+
if (item.actionType === 'new_content') types.add('demand_pull');
|
|
912
|
+
if (item.actionType === 'internal_linking') types.add('structural');
|
|
913
|
+
if (item.actionType === 'page_refresh') types.add('positioning');
|
|
914
|
+
if (item.actionType === 'measurement') types.add('conversion');
|
|
915
|
+
}
|
|
916
|
+
return [...types];
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function roadmapScope(topicId, topicName, entityId, openItems) {
|
|
920
|
+
const analysisTypes = analysisTypesFromRoadmap(openItems);
|
|
921
|
+
return {
|
|
922
|
+
version: 1,
|
|
923
|
+
selectedAt: new Date().toISOString(),
|
|
924
|
+
selectedBy: 'agent',
|
|
925
|
+
sourceCandidateId: compactRoadmapSourceId(topicId, openItems),
|
|
926
|
+
entityId,
|
|
927
|
+
label: \`\${topicName ?? 'Topic'} roadmap execution scope\`,
|
|
928
|
+
scopeType: 'subtopic',
|
|
929
|
+
topicId,
|
|
930
|
+
subtopicIds: [],
|
|
931
|
+
pageIds: [],
|
|
932
|
+
gapIds: [],
|
|
933
|
+
answerCellIds: [],
|
|
934
|
+
decisionCandidateIds: [],
|
|
935
|
+
primaryPersonaIds: [],
|
|
936
|
+
decisionStages: [],
|
|
937
|
+
scopeThesis: [
|
|
938
|
+
\`Use the \${topicName ?? 'selected topic'} roadmap as the execution source of truth.\`,
|
|
939
|
+
...openItems.slice(0, 8).map((item, index) =>
|
|
940
|
+
[
|
|
941
|
+
\`\${index + 1}. \${item.title}\`,
|
|
942
|
+
\`Action: \${item.actionType} (\${item.priority} priority).\`,
|
|
943
|
+
item.recommendedAction ? \`Recommended move: \${item.recommendedAction}\` : null,
|
|
944
|
+
item.targetPageUrl ? \`Target page: \${item.targetPageUrl}\` : null,
|
|
945
|
+
item.queries?.length ? \`Queries/questions: \${item.queries.join('; ')}\` : null,
|
|
946
|
+
item.why ? \`Why: \${item.why}\` : null,
|
|
947
|
+
].filter(Boolean).join(' ')
|
|
948
|
+
),
|
|
949
|
+
].join('\\n'),
|
|
950
|
+
analysisTypes,
|
|
951
|
+
includedSignals: [
|
|
952
|
+
'topic_roadmap',
|
|
953
|
+
'gap_inventory',
|
|
954
|
+
'question_pool',
|
|
955
|
+
'page_summaries',
|
|
956
|
+
'serp_opportunities',
|
|
957
|
+
...analysisTypes,
|
|
958
|
+
],
|
|
959
|
+
excludedAdjacentScopes: [],
|
|
960
|
+
reasonForScope:
|
|
961
|
+
'The user requested a plan that executes the currently open roadmap gaps for this topic.',
|
|
962
|
+
expectedOutcome:
|
|
963
|
+
'Generate concrete plan items to create, refresh, consolidate, remove, link, or measure the pages called out by the open roadmap rows without cannibalizing existing topic coverage.',
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const useRoadmapScope = topicId && openRoadmapItems.length > 0 &&
|
|
968
|
+
/roadmap|gaps|gap|new pages|new content|updates|refresh|comprehensive/i.test(userIntent ?? '');
|
|
969
|
+
|
|
970
|
+
let selected = null;
|
|
971
|
+
let preview = null;
|
|
972
|
+
if (useRoadmapScope) {
|
|
973
|
+
const scope = roadmapScope(topicId, topicName, entityId, openRoadmapItems);
|
|
974
|
+
preview = await api.post(\`/api/entities/\${entityId}/plan-scopes/preview\`, {
|
|
975
|
+
selectedBy: 'agent',
|
|
976
|
+
userIntent: q,
|
|
977
|
+
scope,
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
\`\`\`
|
|
981
|
+
|
|
982
|
+
If you are not in roadmap mode, use ranked scoped candidates:
|
|
983
|
+
|
|
984
|
+
\`\`\`ts
|
|
756
985
|
const candidates = await api.get(
|
|
757
|
-
\`/api/entities/\${entityId}/plan-scopes/candidates?q=\${encodeURIComponent(q)}&limit=
|
|
986
|
+
\`/api/entities/\${entityId}/plan-scopes/candidates?q=\${encodeURIComponent(q)}&limit=8&maxItems=8\`
|
|
758
987
|
);
|
|
759
988
|
\`\`\`
|
|
760
989
|
|
|
761
990
|
Show the top 3 candidates with:
|
|
762
991
|
- label
|
|
763
992
|
- scope type
|
|
764
|
-
- pages and
|
|
993
|
+
- pages, gaps, answer cells, roadmap rows, and decision candidates included
|
|
994
|
+
- personas and decision stages if present
|
|
765
995
|
- expected outcome
|
|
766
996
|
- conflict state and warnings
|
|
767
997
|
- why you prefer one
|
|
768
998
|
|
|
999
|
+
Prefer scopes that are:
|
|
1000
|
+
- roadmap-backed or decision-backed
|
|
1001
|
+
- page-bounded or small topic-bounded
|
|
1002
|
+
- clear about persona x decision stage x question
|
|
1003
|
+
- conflict-clear
|
|
1004
|
+
- commercially or strategically meaningful
|
|
1005
|
+
|
|
769
1006
|
If every candidate is weak, broaden the query once. If candidates are
|
|
770
1007
|
still thin, say the source data is missing and suggest the prerequisite
|
|
771
|
-
connection or
|
|
1008
|
+
connection, scan, KB work, or roadmap generation.
|
|
772
1009
|
|
|
773
|
-
### Step
|
|
1010
|
+
### Step 6 \u2014 Inspect conflicts before committing
|
|
774
1011
|
|
|
775
1012
|
Never stage a scope blindly. Use preview when the user is leaning toward
|
|
776
1013
|
a candidate or asks why it is safe.
|
|
777
1014
|
|
|
1015
|
+
For non-roadmap scopes, convert the candidate to a full scope without
|
|
1016
|
+
dropping the evidence bindings:
|
|
1017
|
+
|
|
778
1018
|
\`\`\`ts
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
scope: {
|
|
1019
|
+
selected = candidates.candidates[0];
|
|
1020
|
+
function toScope(selected) {
|
|
1021
|
+
return {
|
|
783
1022
|
version: 1,
|
|
784
1023
|
selectedAt: new Date().toISOString(),
|
|
785
1024
|
selectedBy: 'agent',
|
|
@@ -791,13 +1030,31 @@ const preview = await api.post(\`/api/entities/\${entityId}/plan-scopes/preview\
|
|
|
791
1030
|
subtopicIds: selected.subtopicIds,
|
|
792
1031
|
pageIds: selected.pageIds,
|
|
793
1032
|
gapIds: selected.gapIds,
|
|
1033
|
+
answerCellIds: selected.answerCellIds ?? [],
|
|
1034
|
+
decisionCandidateIds: selected.decisionCandidateIds ?? [],
|
|
1035
|
+
primaryPersonaIds: selected.primaryPersonaIds ?? [],
|
|
1036
|
+
decisionStages: selected.decisionStages ?? [],
|
|
1037
|
+
scopeThesis: selected.scopeThesis ?? null,
|
|
794
1038
|
analysisTypes: selected.analysisTypes,
|
|
795
|
-
includedSignals: [
|
|
1039
|
+
includedSignals: [
|
|
1040
|
+
'gap_inventory',
|
|
1041
|
+
'answer_map',
|
|
1042
|
+
'decision_candidates',
|
|
1043
|
+
...selected.analysisTypes,
|
|
1044
|
+
],
|
|
796
1045
|
excludedAdjacentScopes: [],
|
|
797
1046
|
reasonForScope: selected.whyThisScope,
|
|
798
1047
|
expectedOutcome: selected.expectedOutcome,
|
|
799
|
-
}
|
|
800
|
-
}
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
if (!preview) {
|
|
1052
|
+
preview = await api.post(\`/api/entities/\${entityId}/plan-scopes/preview\`, {
|
|
1053
|
+
selectedBy: 'agent',
|
|
1054
|
+
userIntent: q,
|
|
1055
|
+
scope: toScope(selected),
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
801
1058
|
\`\`\`
|
|
802
1059
|
|
|
803
1060
|
If preview returns blocked conflicts, do not create the plan. Explain
|
|
@@ -806,15 +1063,30 @@ the overlap and pick another scope.
|
|
|
806
1063
|
If preview returns warnings, ask for explicit user acceptance before
|
|
807
1064
|
creating. Warnings are allowed only when the user understands the overlap.
|
|
808
1065
|
|
|
809
|
-
### Step
|
|
1066
|
+
### Step 7 \u2014 Clean old plans only with approval
|
|
1067
|
+
|
|
1068
|
+
If the user says old plans are conflicting, list them first and ask
|
|
1069
|
+
before deleting. Do not silently remove plans.
|
|
1070
|
+
|
|
1071
|
+
\`\`\`ts
|
|
1072
|
+
const existing = await api.get(\`/api/plans?entityId=\${entityId}\`);
|
|
1073
|
+
console.log(existing.plans.map(p => ({ id: p.id, name: p.name, status: p.status })));
|
|
1074
|
+
|
|
1075
|
+
// After explicit user approval:
|
|
1076
|
+
await Promise.all(existing.plans.map(p => api.delete(\`/api/plans/\${p.id}\`)));
|
|
1077
|
+
\`\`\`
|
|
1078
|
+
|
|
1079
|
+
### Step 8 \u2014 Create the scoped plan
|
|
810
1080
|
|
|
811
1081
|
Create from the selected scope. Do not use legacy topic-plan or
|
|
812
1082
|
opportunity-basket endpoints.
|
|
813
1083
|
|
|
814
1084
|
\`\`\`ts
|
|
1085
|
+
const planLabel = selected?.label ?? preview.scope.label;
|
|
1086
|
+
const planDescription = selected?.expectedOutcome ?? preview.scope.expectedOutcome;
|
|
815
1087
|
const plan = await api.post(\`/api/entities/\${entityId}/plans/from-scope\`, {
|
|
816
|
-
name:
|
|
817
|
-
description:
|
|
1088
|
+
name: planLabel,
|
|
1089
|
+
description: planDescription,
|
|
818
1090
|
scope: preview.scope,
|
|
819
1091
|
conflictOverride:
|
|
820
1092
|
preview.conflicts.some(c => c.severity === 'warn')
|
|
@@ -823,7 +1095,7 @@ const plan = await api.post(\`/api/entities/\${entityId}/plans/from-scope\`, {
|
|
|
823
1095
|
});
|
|
824
1096
|
\`\`\`
|
|
825
1097
|
|
|
826
|
-
### Step
|
|
1098
|
+
### Step 9 \u2014 Generate scoped items
|
|
827
1099
|
|
|
828
1100
|
\`\`\`ts
|
|
829
1101
|
const generation = await api.post(\`/api/plans/\${plan.plan.id}/generate-scoped\`);
|
|
@@ -831,14 +1103,55 @@ console.log(generation);
|
|
|
831
1103
|
\`\`\`
|
|
832
1104
|
|
|
833
1105
|
Generation must stay inside the selected scope. It should claim only
|
|
834
|
-
the gaps and pages in the scope,
|
|
835
|
-
|
|
836
|
-
|
|
1106
|
+
the gaps and pages in the scope, cite the selected evidence spine
|
|
1107
|
+
(\`topic_roadmap\` rows, scoped gaps, pages, answer cells, or
|
|
1108
|
+
\`decisionCandidateIds\`), carry conflict warnings into the audit, and
|
|
1109
|
+
return deferred or not-recommended items instead of stretching the scope
|
|
1110
|
+
to look productive.
|
|
1111
|
+
|
|
1112
|
+
After generation, read the plan and verify it stayed grounded:
|
|
1113
|
+
|
|
1114
|
+
\`\`\`ts
|
|
1115
|
+
const detail = await api.get(\`/api/plans/\${plan.plan.id}\`);
|
|
1116
|
+
console.log(detail.items.map(i => ({
|
|
1117
|
+
title: i.title,
|
|
1118
|
+
bundle: i.bundleJson,
|
|
1119
|
+
})));
|
|
1120
|
+
\`\`\`
|
|
1121
|
+
|
|
1122
|
+
Explain what to review and which first 1-3 items are safest to move into
|
|
1123
|
+
execution.
|
|
1124
|
+
|
|
1125
|
+
### Step 10 \u2014 Generate content briefs when the plan item is ready
|
|
1126
|
+
|
|
1127
|
+
For roadmap new-page rows or plan items that need a writer-ready brief,
|
|
1128
|
+
use the brief generator only when you can resolve a source question id
|
|
1129
|
+
from the roadmap row or its covered opportunity keys. Let the user add a
|
|
1130
|
+
thesis, proof point, competitor angle, product workflow, related product,
|
|
1131
|
+
use case, benefit, or unique take as \`guidance\`.
|
|
1132
|
+
|
|
1133
|
+
\`\`\`ts
|
|
1134
|
+
const brief = await api.post(
|
|
1135
|
+
\`/api/diagnostics/\${diagnosticId}/questions/\${questionId}/generate-brief\`,
|
|
1136
|
+
{
|
|
1137
|
+
targetPlanItemId: planItemId ?? null,
|
|
1138
|
+
guidance: userBriefGuidance ?? null,
|
|
1139
|
+
previousFailure: previousBriefFailure ?? null,
|
|
1140
|
+
}
|
|
1141
|
+
);
|
|
1142
|
+
console.log(brief);
|
|
1143
|
+
\`\`\`
|
|
1144
|
+
|
|
1145
|
+
A useful brief should cover focus keyword, secondary keywords, target
|
|
1146
|
+
questions, competitor/SERP and AEO shape, related products, use cases,
|
|
1147
|
+
benefits to include, the company's unique angle or thesis, outline, and
|
|
1148
|
+
key facts/proof the writer can cite.
|
|
837
1149
|
|
|
838
|
-
|
|
839
|
-
|
|
1150
|
+
If the generator asks for missing inputs, do not invent them. Surface the
|
|
1151
|
+
open questions to the user and use the brief chat/context flow to fill
|
|
1152
|
+
only those blanks. Then regenerate with the user's guidance.
|
|
840
1153
|
|
|
841
|
-
### Step
|
|
1154
|
+
### Step 11 \u2014 Set expectations
|
|
842
1155
|
|
|
843
1156
|
End with reality:
|
|
844
1157
|
|
|
@@ -849,20 +1162,37 @@ End with reality:
|
|
|
849
1162
|
## Strong opinions to bring
|
|
850
1163
|
|
|
851
1164
|
- **One bounded scope per plan.** Always.
|
|
1165
|
+
- **Decision candidates are the execution menu.** If a plan ignores them,
|
|
1166
|
+
stop and investigate, unless this is a roadmap-derived scope whose
|
|
1167
|
+
execution menu is the open roadmap rows.
|
|
1168
|
+
- **Topic roadmap rows are execution evidence.** Use them directly for
|
|
1169
|
+
topic-gap, new-page, page-refresh, consolidation, internal-link, and
|
|
1170
|
+
measurement planning.
|
|
1171
|
+
- **Imagination is hypothesis generation.** Promote it before planning;
|
|
1172
|
+
never execute it directly.
|
|
852
1173
|
- **Prefer conflict-clear scopes.** Warning scopes require explicit user acceptance.
|
|
853
|
-
- **Use the signal, not the URL.** Match on topic, page summaries,
|
|
854
|
-
GSC, GA, AEO, conversion, and strategy context.
|
|
1174
|
+
- **Use the signal, not the URL.** Match on topic, page summaries, answer
|
|
1175
|
+
cells, gap evidence, GSC, GA, AEO, conversion, and strategy context.
|
|
855
1176
|
- **Small is fine.** A plan with 3 high-confidence page items can beat a giant backlog.
|
|
856
1177
|
- **Don't promise CTR lift in week 1.** The data takes 14 days.
|
|
857
1178
|
- **Inconclusive is not failed.** Many outcomes need another window.
|
|
858
|
-
- **Archive old/conflicting plans.** Open-ended plans
|
|
1179
|
+
- **Archive old/conflicting plans only with approval.** Open-ended plans
|
|
1180
|
+
become graveyards, but deleting them is still destructive.
|
|
859
1181
|
|
|
860
1182
|
## What success looks like
|
|
861
1183
|
|
|
1184
|
+
- Source signal checked
|
|
1185
|
+
- Topic roadmap checked when the user asks about topic gaps, new pages,
|
|
1186
|
+
updates, or comprehensiveness
|
|
1187
|
+
- Decision candidates refreshed
|
|
1188
|
+
- Imagination candidates reviewed when useful
|
|
862
1189
|
- One bounded scope picked
|
|
863
1190
|
- Conflicts reviewed
|
|
864
1191
|
- One scoped plan created
|
|
865
1192
|
- Scoped generation run
|
|
1193
|
+
- Generated items cite the selected evidence spine
|
|
1194
|
+
- Content briefs generated only from resolvable roadmap/plan-item source
|
|
1195
|
+
questions, with user guidance captured when needed
|
|
866
1196
|
- First execution items are obvious
|
|
867
1197
|
- User knows when to come back: 14 days for outcomes, sooner for approvals
|
|
868
1198
|
|
|
@@ -874,7 +1204,19 @@ End with reality:
|
|
|
874
1204
|
or \`POST /api/plans/:id/generate-topic\`.
|
|
875
1205
|
- Don't sort opportunities by score and list the top 10. That's not strategy.
|
|
876
1206
|
- Don't let URLs alone classify scope. Use the evidence Higrowth gathered.
|
|
1207
|
+
- Don't ignore open topic roadmap rows when the user asks for topic gaps,
|
|
1208
|
+
comprehensiveness, new pages, or content updates.
|
|
1209
|
+
- Don't drop \`answerCellIds\`, \`decisionCandidateIds\`, \`primaryPersonaIds\`,
|
|
1210
|
+
\`decisionStages\`, or \`scopeThesis\` when previewing or creating a scope.
|
|
1211
|
+
For roadmap scopes, preserve the roadmap rows in \`scopeThesis\` and
|
|
1212
|
+
include \`topic_roadmap\` in \`includedSignals\`.
|
|
877
1213
|
- Don't create a plan that overlaps blocked active work.
|
|
1214
|
+
- Don't create work orders from imagination candidates.
|
|
1215
|
+
- Don't hand-write content briefs when the brief generator has a source
|
|
1216
|
+
question. Generate, inspect open questions, collect guidance, then
|
|
1217
|
+
regenerate.
|
|
1218
|
+
- Don't run a new scan by default. Check answer map, decision candidates,
|
|
1219
|
+
GSC, GA, and KB first; scan only when source signal is missing or stale.
|
|
878
1220
|
- Don't gloss over the KB. If the KB is empty, stop and run the
|
|
879
1221
|
populate-kb playbook first. Strategy without KB context is generic.
|
|
880
1222
|
`;
|
|
@@ -1060,7 +1402,7 @@ var SKILLS = [
|
|
|
1060
1402
|
{
|
|
1061
1403
|
slug: "higrowth-marketing-strategy",
|
|
1062
1404
|
title: "Marketing strategy chat",
|
|
1063
|
-
description: "Walk a diagnostic, pick a
|
|
1405
|
+
description: "Walk a diagnostic, pick a scoped topic or roadmap, build the sprint plan.",
|
|
1064
1406
|
body: MARKETING_STRATEGY
|
|
1065
1407
|
},
|
|
1066
1408
|
{
|
|
@@ -1305,7 +1647,7 @@ function beginUpdateCheck(currentVersion) {
|
|
|
1305
1647
|
// package.json
|
|
1306
1648
|
var package_default = {
|
|
1307
1649
|
name: "@higrowth/cli",
|
|
1308
|
-
version: "0.3.
|
|
1650
|
+
version: "0.3.4",
|
|
1309
1651
|
description: "Higrowth CLI \u2014 log in via browser, install Claude Code / Codex skills, manage the MCP connection.",
|
|
1310
1652
|
type: "module",
|
|
1311
1653
|
license: "Apache-2.0",
|