@higrowth/cli 0.3.2 → 0.3.3
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 +193 -25
- 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 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, or plan.
|
|
707
707
|
allowed-tools: mcp__higrowth__execute_typescript
|
|
708
708
|
---
|
|
709
709
|
|
|
@@ -725,7 +725,20 @@ Plans are not giant backlogs. A good plan is a scoped intervention:
|
|
|
725
725
|
one topic area, page cluster, gap type, or conversion slice with enough
|
|
726
726
|
evidence to act and narrow enough boundaries to avoid conflicting work.
|
|
727
727
|
|
|
728
|
-
|
|
728
|
+
The planning stack has four layers:
|
|
729
|
+
|
|
730
|
+
1. **Answer map** \u2014 what questions the site answers for which persona
|
|
731
|
+
and decision stage.
|
|
732
|
+
2. **Decision candidates** \u2014 executable moves grounded in answer cells,
|
|
733
|
+
gaps, GSC, GA, strategy, and conflict checks.
|
|
734
|
+
3. **Imagination candidates** \u2014 adjacent hypotheses HG can infer from
|
|
735
|
+
weak or missing answers. They are ideas only.
|
|
736
|
+
4. **Scoped plans** \u2014 a small selected scope that generates execution
|
|
737
|
+
items from decision candidates.
|
|
738
|
+
|
|
739
|
+
Rank by **leverage, evidence, and executability**, not raw opportunity count.
|
|
740
|
+
Never create work orders directly from imagination candidates. Promote
|
|
741
|
+
good imagination candidates into decision candidates first, then plan.
|
|
729
742
|
|
|
730
743
|
## The conversation
|
|
731
744
|
|
|
@@ -745,41 +758,142 @@ Anything missing or recently changed?"*
|
|
|
745
758
|
Use the answer to steer scope selection. Recent launches, product
|
|
746
759
|
changes, seasonality, and sales priorities should shape what you plan.
|
|
747
760
|
|
|
748
|
-
### Step 2 \u2014
|
|
761
|
+
### Step 2 \u2014 Resolve the topic or area
|
|
749
762
|
|
|
750
763
|
If the user named an area, use it as the scope query. If not, help them
|
|
751
764
|
pick one from the diagnostic: a pillar, subtopic, page cluster, gap type,
|
|
752
765
|
or conversion issue.
|
|
753
766
|
|
|
767
|
+
Find the most likely topic/pillar id before generating plans. Use the
|
|
768
|
+
current API surface available in the MCP harness; if the harness exposes
|
|
769
|
+
topic search, use it. If not, use scoped candidates with the user's query
|
|
770
|
+
and read the returned \`topicId\`.
|
|
771
|
+
|
|
754
772
|
\`\`\`ts
|
|
755
773
|
const q = userIntent || 'highest leverage scoped fixes';
|
|
774
|
+
const firstPass = await api.get(
|
|
775
|
+
\`/api/entities/\${entityId}/plan-scopes/candidates?q=\${encodeURIComponent(q)}&limit=8&maxItems=8\`
|
|
776
|
+
);
|
|
777
|
+
const topicId = firstPass.candidates.find(c => c.topicId)?.topicId;
|
|
778
|
+
\`\`\`
|
|
779
|
+
|
|
780
|
+
### Step 3 \u2014 Check source signal before planning
|
|
781
|
+
|
|
782
|
+
Do not jump straight to a plan if the answer map and decision registry
|
|
783
|
+
are empty. HG should reason from the rich signal it already gathered.
|
|
784
|
+
|
|
785
|
+
\`\`\`ts
|
|
786
|
+
const answerSummary = topicId
|
|
787
|
+
? await api.get(\`/api/entities/\${entityId}/answer-map/summary?topicId=\${topicId}\`)
|
|
788
|
+
: null;
|
|
789
|
+
console.log(answerSummary?.summary);
|
|
790
|
+
\`\`\`
|
|
791
|
+
|
|
792
|
+
If the summary has no cells, compute it:
|
|
793
|
+
|
|
794
|
+
\`\`\`ts
|
|
795
|
+
if (topicId && (!answerSummary || answerSummary.summary.totalCells === 0)) {
|
|
796
|
+
await api.post(\`/api/entities/\${entityId}/answer-map/compute\`, {
|
|
797
|
+
topicId,
|
|
798
|
+
limit: 500,
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
\`\`\`
|
|
802
|
+
|
|
803
|
+
Then refresh decision candidates for the topic or page slice:
|
|
804
|
+
|
|
805
|
+
\`\`\`ts
|
|
806
|
+
await api.post(\`/api/entities/\${entityId}/decision-candidates/refresh\`, {
|
|
807
|
+
topicId,
|
|
808
|
+
limit: 500,
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
const decisions = await api.get(
|
|
812
|
+
\`/api/entities/\${entityId}/decision-candidates?topicId=\${topicId}&status=candidate&limit=50\`
|
|
813
|
+
);
|
|
814
|
+
console.log(decisions.candidates.slice(0, 10));
|
|
815
|
+
\`\`\`
|
|
816
|
+
|
|
817
|
+
If answer-map compute still returns little or no signal, say so. The
|
|
818
|
+
right prerequisite may be a scan, GSC/GA connection, KB population, or
|
|
819
|
+
pillar analysis. Do not fabricate a strategic plan from thin data.
|
|
820
|
+
|
|
821
|
+
### Step 4 \u2014 Use imagination only when useful
|
|
822
|
+
|
|
823
|
+
When the user asks "what else could we do here?", "what are we missing?",
|
|
824
|
+
or the decision registry feels too narrow, generate imagination
|
|
825
|
+
candidates. This is HG's ideation layer: adjacent questions and content
|
|
826
|
+
angles extrapolated from answer-map gaps.
|
|
827
|
+
|
|
828
|
+
\`\`\`ts
|
|
829
|
+
const imagination = await api.post(
|
|
830
|
+
\`/api/entities/\${entityId}/imagination-candidates/generate\`,
|
|
831
|
+
{ topicId, limit: 20 }
|
|
832
|
+
);
|
|
833
|
+
console.log(imagination.candidates);
|
|
834
|
+
\`\`\`
|
|
835
|
+
|
|
836
|
+
Review these critically with the user. Reject weak, duplicate, or noisy
|
|
837
|
+
hypotheses:
|
|
838
|
+
|
|
839
|
+
\`\`\`ts
|
|
840
|
+
await api.post(\`/api/entities/\${entityId}/imagination-candidates/\${id}/reject\`, {
|
|
841
|
+
reason: 'Duplicate of an existing page angle',
|
|
842
|
+
});
|
|
843
|
+
\`\`\`
|
|
844
|
+
|
|
845
|
+
Promote only the best 1-3 ideas. Promotion creates decision candidates;
|
|
846
|
+
it still does not create work orders or plan items.
|
|
847
|
+
|
|
848
|
+
\`\`\`ts
|
|
849
|
+
const promoted = await api.post(
|
|
850
|
+
\`/api/entities/\${entityId}/imagination-candidates/\${id}/promote\`
|
|
851
|
+
);
|
|
852
|
+
console.log(promoted.candidate);
|
|
853
|
+
\`\`\`
|
|
854
|
+
|
|
855
|
+
After promotion, re-run scoped candidates so promoted ideas can compete
|
|
856
|
+
with observed-gap candidates.
|
|
857
|
+
|
|
858
|
+
### Step 5 \u2014 Choose a bounded scope
|
|
859
|
+
|
|
860
|
+
\`\`\`ts
|
|
756
861
|
const candidates = await api.get(
|
|
757
|
-
\`/api/entities/\${entityId}/plan-scopes/candidates?q=\${encodeURIComponent(q)}&limit=
|
|
862
|
+
\`/api/entities/\${entityId}/plan-scopes/candidates?q=\${encodeURIComponent(q)}&limit=8&maxItems=8\`
|
|
758
863
|
);
|
|
759
864
|
\`\`\`
|
|
760
865
|
|
|
761
866
|
Show the top 3 candidates with:
|
|
762
867
|
- label
|
|
763
868
|
- scope type
|
|
764
|
-
- pages and
|
|
869
|
+
- pages, gaps, answer cells, and decision candidates included
|
|
870
|
+
- personas and decision stages if present
|
|
765
871
|
- expected outcome
|
|
766
872
|
- conflict state and warnings
|
|
767
873
|
- why you prefer one
|
|
768
874
|
|
|
875
|
+
Prefer scopes that are:
|
|
876
|
+
- decision-backed
|
|
877
|
+
- page-bounded or small topic-bounded
|
|
878
|
+
- clear about persona x decision stage x question
|
|
879
|
+
- conflict-clear
|
|
880
|
+
- commercially or strategically meaningful
|
|
881
|
+
|
|
769
882
|
If every candidate is weak, broaden the query once. If candidates are
|
|
770
883
|
still thin, say the source data is missing and suggest the prerequisite
|
|
771
|
-
connection or
|
|
884
|
+
connection, scan, or KB work.
|
|
772
885
|
|
|
773
|
-
### Step
|
|
886
|
+
### Step 6 \u2014 Inspect conflicts before committing
|
|
774
887
|
|
|
775
888
|
Never stage a scope blindly. Use preview when the user is leaning toward
|
|
776
889
|
a candidate or asks why it is safe.
|
|
777
890
|
|
|
891
|
+
Convert the candidate to a full scope without dropping the evidence
|
|
892
|
+
bindings:
|
|
893
|
+
|
|
778
894
|
\`\`\`ts
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
selectedBy: 'agent',
|
|
782
|
-
scope: {
|
|
895
|
+
function toScope(selected) {
|
|
896
|
+
return {
|
|
783
897
|
version: 1,
|
|
784
898
|
selectedAt: new Date().toISOString(),
|
|
785
899
|
selectedBy: 'agent',
|
|
@@ -791,12 +905,29 @@ const preview = await api.post(\`/api/entities/\${entityId}/plan-scopes/preview\
|
|
|
791
905
|
subtopicIds: selected.subtopicIds,
|
|
792
906
|
pageIds: selected.pageIds,
|
|
793
907
|
gapIds: selected.gapIds,
|
|
908
|
+
answerCellIds: selected.answerCellIds ?? [],
|
|
909
|
+
decisionCandidateIds: selected.decisionCandidateIds ?? [],
|
|
910
|
+
primaryPersonaIds: selected.primaryPersonaIds ?? [],
|
|
911
|
+
decisionStages: selected.decisionStages ?? [],
|
|
912
|
+
scopeThesis: selected.scopeThesis ?? null,
|
|
794
913
|
analysisTypes: selected.analysisTypes,
|
|
795
|
-
includedSignals: [
|
|
914
|
+
includedSignals: [
|
|
915
|
+
'gap_inventory',
|
|
916
|
+
'answer_map',
|
|
917
|
+
'decision_candidates',
|
|
918
|
+
...selected.analysisTypes,
|
|
919
|
+
],
|
|
796
920
|
excludedAdjacentScopes: [],
|
|
797
921
|
reasonForScope: selected.whyThisScope,
|
|
798
922
|
expectedOutcome: selected.expectedOutcome,
|
|
799
|
-
}
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
const selected = candidates.candidates[0];
|
|
927
|
+
const preview = await api.post(\`/api/entities/\${entityId}/plan-scopes/preview\`, {
|
|
928
|
+
selectedBy: 'agent',
|
|
929
|
+
userIntent: q,
|
|
930
|
+
scope: toScope(selected),
|
|
800
931
|
});
|
|
801
932
|
\`\`\`
|
|
802
933
|
|
|
@@ -806,7 +937,20 @@ the overlap and pick another scope.
|
|
|
806
937
|
If preview returns warnings, ask for explicit user acceptance before
|
|
807
938
|
creating. Warnings are allowed only when the user understands the overlap.
|
|
808
939
|
|
|
809
|
-
### Step
|
|
940
|
+
### Step 7 \u2014 Clean old plans only with approval
|
|
941
|
+
|
|
942
|
+
If the user says old plans are conflicting, list them first and ask
|
|
943
|
+
before deleting. Do not silently remove plans.
|
|
944
|
+
|
|
945
|
+
\`\`\`ts
|
|
946
|
+
const existing = await api.get(\`/api/plans?entityId=\${entityId}\`);
|
|
947
|
+
console.log(existing.plans.map(p => ({ id: p.id, name: p.name, status: p.status })));
|
|
948
|
+
|
|
949
|
+
// After explicit user approval:
|
|
950
|
+
await Promise.all(existing.plans.map(p => api.delete(\`/api/plans/\${p.id}\`)));
|
|
951
|
+
\`\`\`
|
|
952
|
+
|
|
953
|
+
### Step 8 \u2014 Create the scoped plan
|
|
810
954
|
|
|
811
955
|
Create from the selected scope. Do not use legacy topic-plan or
|
|
812
956
|
opportunity-basket endpoints.
|
|
@@ -823,7 +967,7 @@ const plan = await api.post(\`/api/entities/\${entityId}/plans/from-scope\`, {
|
|
|
823
967
|
});
|
|
824
968
|
\`\`\`
|
|
825
969
|
|
|
826
|
-
### Step
|
|
970
|
+
### Step 9 \u2014 Generate scoped items
|
|
827
971
|
|
|
828
972
|
\`\`\`ts
|
|
829
973
|
const generation = await api.post(\`/api/plans/\${plan.plan.id}/generate-scoped\`);
|
|
@@ -831,14 +975,24 @@ console.log(generation);
|
|
|
831
975
|
\`\`\`
|
|
832
976
|
|
|
833
977
|
Generation must stay inside the selected scope. It should claim only
|
|
834
|
-
the gaps and pages in the scope,
|
|
835
|
-
and return deferred or not-recommended
|
|
836
|
-
scope to look productive.
|
|
978
|
+
the gaps and pages in the scope, cite \`decisionCandidateIds\`, carry
|
|
979
|
+
conflict warnings into the audit, and return deferred or not-recommended
|
|
980
|
+
items instead of stretching the scope to look productive.
|
|
981
|
+
|
|
982
|
+
After generation, read the plan and verify it stayed grounded:
|
|
983
|
+
|
|
984
|
+
\`\`\`ts
|
|
985
|
+
const detail = await api.get(\`/api/plans/\${plan.plan.id}\`);
|
|
986
|
+
console.log(detail.items.map(i => ({
|
|
987
|
+
title: i.title,
|
|
988
|
+
bundle: i.bundleJson,
|
|
989
|
+
})));
|
|
990
|
+
\`\`\`
|
|
837
991
|
|
|
838
|
-
|
|
839
|
-
|
|
992
|
+
Explain what to review and which first 1-3 items are safest to move into
|
|
993
|
+
execution.
|
|
840
994
|
|
|
841
|
-
### Step
|
|
995
|
+
### Step 10 \u2014 Set expectations
|
|
842
996
|
|
|
843
997
|
End with reality:
|
|
844
998
|
|
|
@@ -849,20 +1003,29 @@ End with reality:
|
|
|
849
1003
|
## Strong opinions to bring
|
|
850
1004
|
|
|
851
1005
|
- **One bounded scope per plan.** Always.
|
|
1006
|
+
- **Decision candidates are the execution menu.** If a plan ignores them,
|
|
1007
|
+
stop and investigate.
|
|
1008
|
+
- **Imagination is hypothesis generation.** Promote it before planning;
|
|
1009
|
+
never execute it directly.
|
|
852
1010
|
- **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.
|
|
1011
|
+
- **Use the signal, not the URL.** Match on topic, page summaries, answer
|
|
1012
|
+
cells, gap evidence, GSC, GA, AEO, conversion, and strategy context.
|
|
855
1013
|
- **Small is fine.** A plan with 3 high-confidence page items can beat a giant backlog.
|
|
856
1014
|
- **Don't promise CTR lift in week 1.** The data takes 14 days.
|
|
857
1015
|
- **Inconclusive is not failed.** Many outcomes need another window.
|
|
858
|
-
- **Archive old/conflicting plans.** Open-ended plans
|
|
1016
|
+
- **Archive old/conflicting plans only with approval.** Open-ended plans
|
|
1017
|
+
become graveyards, but deleting them is still destructive.
|
|
859
1018
|
|
|
860
1019
|
## What success looks like
|
|
861
1020
|
|
|
1021
|
+
- Source signal checked
|
|
1022
|
+
- Decision candidates refreshed
|
|
1023
|
+
- Imagination candidates reviewed when useful
|
|
862
1024
|
- One bounded scope picked
|
|
863
1025
|
- Conflicts reviewed
|
|
864
1026
|
- One scoped plan created
|
|
865
1027
|
- Scoped generation run
|
|
1028
|
+
- Generated items cite decision candidates
|
|
866
1029
|
- First execution items are obvious
|
|
867
1030
|
- User knows when to come back: 14 days for outcomes, sooner for approvals
|
|
868
1031
|
|
|
@@ -874,7 +1037,12 @@ End with reality:
|
|
|
874
1037
|
or \`POST /api/plans/:id/generate-topic\`.
|
|
875
1038
|
- Don't sort opportunities by score and list the top 10. That's not strategy.
|
|
876
1039
|
- Don't let URLs alone classify scope. Use the evidence Higrowth gathered.
|
|
1040
|
+
- Don't drop \`answerCellIds\`, \`decisionCandidateIds\`, \`primaryPersonaIds\`,
|
|
1041
|
+
\`decisionStages\`, or \`scopeThesis\` when previewing or creating a scope.
|
|
877
1042
|
- Don't create a plan that overlaps blocked active work.
|
|
1043
|
+
- Don't create work orders from imagination candidates.
|
|
1044
|
+
- Don't run a new scan by default. Check answer map, decision candidates,
|
|
1045
|
+
GSC, GA, and KB first; scan only when source signal is missing or stale.
|
|
878
1046
|
- Don't gloss over the KB. If the KB is empty, stop and run the
|
|
879
1047
|
populate-kb playbook first. Strategy without KB context is generic.
|
|
880
1048
|
`;
|
|
@@ -1305,7 +1473,7 @@ function beginUpdateCheck(currentVersion) {
|
|
|
1305
1473
|
// package.json
|
|
1306
1474
|
var package_default = {
|
|
1307
1475
|
name: "@higrowth/cli",
|
|
1308
|
-
version: "0.3.
|
|
1476
|
+
version: "0.3.3",
|
|
1309
1477
|
description: "Higrowth CLI \u2014 log in via browser, install Claude Code / Codex skills, manage the MCP connection.",
|
|
1310
1478
|
type: "module",
|
|
1311
1479
|
license: "Apache-2.0",
|