@botbotgo/kit-builtin 0.0.92 → 0.0.94
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/README.md +16 -0
- package/dist/core-tools-manifest.json +105 -0
- package/dist/src/http/yahooFinance.d.ts.map +1 -1
- package/dist/src/http/yahooFinance.js.map +1 -1
- package/dist/src/http/yahooFinanceNews.d.ts +32 -0
- package/dist/src/http/yahooFinanceNews.d.ts.map +1 -0
- package/dist/src/http/yahooFinanceNews.js +137 -0
- package/dist/src/http/yahooFinanceNews.js.map +1 -0
- package/package.json +5 -3
- package/skills/company-report/SKILL.md +90 -0
- package/skills/company-report/references/company-report.template.html +151 -0
- package/skills/company-report/scripts/merge-report.mjs +41 -0
- package/skills/project-prompt-ops/SKILL.md +92 -0
- package/skills/project-prompt-ops/references/REQUEST_PATTERNS.md +56 -0
- package/skills/project-prompt-ops/scripts/build_prompt.sh +86 -0
- package/skills/project-prompt-ops/scripts/run_prompt_mode.sh +153 -0
package/README.md
CHANGED
|
@@ -80,3 +80,19 @@ Explanation:
|
|
|
80
80
|
- `fs.listDir.maxEntries` and `fs.listDir.maxDepth`: directory traversal limits.
|
|
81
81
|
- `http.fetchJson.timeoutMs`: request timeout for HTTP JSON fetches.
|
|
82
82
|
- `exec.runCommand.allowedCommands`: shell commands allowed by the built-in exec tool.
|
|
83
|
+
|
|
84
|
+
## Configuration
|
|
85
|
+
|
|
86
|
+
`@botbotgo/kit-builtin` publishes two different asset types:
|
|
87
|
+
|
|
88
|
+
- `dist/`: compiled tool implementation and embedded `config/tool.yaml`
|
|
89
|
+
- `skills/`: built-in skills, including `SKILL.md`, `scripts/`, `references/`, and templates
|
|
90
|
+
|
|
91
|
+
Recommended layout when adding new built-ins:
|
|
92
|
+
|
|
93
|
+
- Put TypeScript implementation that should be compiled, tested, and versioned as runtime code under `src/`
|
|
94
|
+
- Put skill instructions and static skill-owned assets under `skills/<skill-name>/`
|
|
95
|
+
- Keep `SKILL.md` focused on workflow and orchestration, not large inline code blocks
|
|
96
|
+
- If a skill needs Node.js code, prefer a checked-in script file and call it from `SKILL.md`
|
|
97
|
+
- Declare Node.js dependencies once in this package's top-level `dependencies`, not inside individual skill folders
|
|
98
|
+
- If a skill grows heavy or needs isolated dependency/version management, promote it into its own package instead of expanding `@botbotgo/kit-builtin`
|
|
@@ -4720,6 +4720,111 @@
|
|
|
4720
4720
|
"exportName": "yahooFinanceQuote",
|
|
4721
4721
|
"sideEffect": "none"
|
|
4722
4722
|
},
|
|
4723
|
+
{
|
|
4724
|
+
"name": "yahooFinanceNews",
|
|
4725
|
+
"description": "Fetch Yahoo Finance news items by symbol or query.",
|
|
4726
|
+
"inputSchema": {
|
|
4727
|
+
"type": "object",
|
|
4728
|
+
"properties": {
|
|
4729
|
+
"query": {
|
|
4730
|
+
"type": "string"
|
|
4731
|
+
},
|
|
4732
|
+
"symbol": {
|
|
4733
|
+
"type": "string"
|
|
4734
|
+
},
|
|
4735
|
+
"newsCount": {
|
|
4736
|
+
"type": "number"
|
|
4737
|
+
},
|
|
4738
|
+
"timeoutMs": {
|
|
4739
|
+
"type": "number"
|
|
4740
|
+
},
|
|
4741
|
+
"maxBytes": {
|
|
4742
|
+
"type": "number"
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
},
|
|
4746
|
+
"outputSchema": {
|
|
4747
|
+
"type": "object",
|
|
4748
|
+
"properties": {
|
|
4749
|
+
"result": {
|
|
4750
|
+
"type": "object",
|
|
4751
|
+
"properties": {
|
|
4752
|
+
"query": {
|
|
4753
|
+
"type": "string"
|
|
4754
|
+
},
|
|
4755
|
+
"count": {
|
|
4756
|
+
"type": "number"
|
|
4757
|
+
},
|
|
4758
|
+
"news": {
|
|
4759
|
+
"type": "array",
|
|
4760
|
+
"items": {
|
|
4761
|
+
"type": "object",
|
|
4762
|
+
"properties": {
|
|
4763
|
+
"title": {
|
|
4764
|
+
"type": "string"
|
|
4765
|
+
},
|
|
4766
|
+
"link": {
|
|
4767
|
+
"type": "string"
|
|
4768
|
+
},
|
|
4769
|
+
"publisher": {
|
|
4770
|
+
"type": "string"
|
|
4771
|
+
},
|
|
4772
|
+
"publishedAt": {
|
|
4773
|
+
"type": "string"
|
|
4774
|
+
},
|
|
4775
|
+
"type": {
|
|
4776
|
+
"type": "string"
|
|
4777
|
+
}
|
|
4778
|
+
},
|
|
4779
|
+
"required": [
|
|
4780
|
+
"title",
|
|
4781
|
+
"link"
|
|
4782
|
+
]
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
},
|
|
4786
|
+
"required": [
|
|
4787
|
+
"query",
|
|
4788
|
+
"count",
|
|
4789
|
+
"news"
|
|
4790
|
+
]
|
|
4791
|
+
},
|
|
4792
|
+
"evidence": {
|
|
4793
|
+
"type": "array",
|
|
4794
|
+
"items": {
|
|
4795
|
+
"type": "object",
|
|
4796
|
+
"properties": {
|
|
4797
|
+
"type": {
|
|
4798
|
+
"type": "string"
|
|
4799
|
+
},
|
|
4800
|
+
"ref": {
|
|
4801
|
+
"type": "string"
|
|
4802
|
+
},
|
|
4803
|
+
"summary": {
|
|
4804
|
+
"type": "string"
|
|
4805
|
+
},
|
|
4806
|
+
"createdAt": {
|
|
4807
|
+
"type": "string"
|
|
4808
|
+
}
|
|
4809
|
+
},
|
|
4810
|
+
"required": [
|
|
4811
|
+
"type",
|
|
4812
|
+
"ref",
|
|
4813
|
+
"summary",
|
|
4814
|
+
"createdAt"
|
|
4815
|
+
]
|
|
4816
|
+
}
|
|
4817
|
+
}
|
|
4818
|
+
},
|
|
4819
|
+
"required": [
|
|
4820
|
+
"result",
|
|
4821
|
+
"evidence"
|
|
4822
|
+
]
|
|
4823
|
+
},
|
|
4824
|
+
"sourcePath": "src/http/yahooFinanceNews",
|
|
4825
|
+
"exportName": "yahooFinanceNews",
|
|
4826
|
+
"sideEffect": "none"
|
|
4827
|
+
},
|
|
4723
4828
|
{
|
|
4724
4829
|
"name": "messagesFindChatsByParticipant",
|
|
4725
4830
|
"description": "Find Messages chats by participant handle or chat name.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yahooFinance.d.ts","sourceRoot":"","sources":["../../../src/http/yahooFinance.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"yahooFinance.d.ts","sourceRoot":"","sources":["../../../src/http/yahooFinance.ts"],"names":[],"mappings":"AAyCA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4ID;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;GAoCA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yahooFinance.js","sourceRoot":"","sources":["../../../src/http/yahooFinance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,MAAM,gBAAgB,GAAG,oDAAoD,CAAC;
|
|
1
|
+
{"version":3,"file":"yahooFinance.js","sourceRoot":"","sources":["../../../src/http/yahooFinance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,MAAM,gBAAgB,GAAG,oDAAoD,CAAC;AAqD9E,SAAS,cAAc;IACrB,MAAM,QAAQ,GAAG;QACf,SAAS,EAAE,kBAAkB;QAC7B,QAAQ,EAAE,sBAAsB;QAChC,SAAS,EAAE,uBAAuB;QAClC,YAAY,EAAE,qBAAqB;QACnC,YAAY,EAAE,EAAc;QAC5B,YAAY,EAAE,EAAc;KAC7B,CAAC;IACF,MAAM,GAAG,GAAG,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAC,MAAM,CAAC,CAAC;IACvE,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS;QAC9C,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ;QAC3C,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS;QAC9C,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY;QACxF,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY;QACxF,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY;KACzF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAA+D;IACvF,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC;SAC5D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAClD,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,MAAM,iBAAiB,CAAC,eAAe,EAAE,iCAAiC,EAAE,EAAE,CAAC,CAAC;IACrG,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IASlC;IACC,MAAM,GAAG,GAAG,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,IAAI,CAAC,KAAK,EAAE,CAAC;IACpG,MAAM,WAAW,CAAC,GAAG,EAAE;QACrB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACnE,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC1B,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACrE,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACtD,MAAM,iBAAiB,CAAC,cAAc,EAAE,6BAA6B,IAAI,CAAC,MAAM,oBAAoB,IAAI,CAAC,SAAS,IAAI,EAAE;gBACtH,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;QACL,CAAC;QACD,MAAM,iBAAiB,CAAC,gBAAgB,EAAE,iCAAiC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;YAC7H,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;IACL,CAAC;IACD,YAAY,CAAC,KAAK,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1B,MAAM,iBAAiB,CAAC,gBAAgB,EAAE,0BAA0B,KAAK,2BAA2B,IAAI,CAAC,QAAQ,QAAQ,EAAE;YACzH,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,QAAQ;SACrB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuB,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,iBAAiB,CAAC,gBAAgB,EAAE,qCAAqC,EAAE;YAC/E,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAGD,SAAS,OAAO,CAAC,MAAc,EAAE,QAA4B;IAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACpC,IAAI,KAAK,EAAE,WAAW,EAAE,CAAC;QACvB,MAAM,iBAAiB,CAAC,aAAa,EAAE,2BAA2B,MAAM,KAAK,KAAK,CAAC,WAAW,EAAE,EAAE;YAChG,MAAM;YACN,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAE/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,aAAa,IAAI,QAAQ,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;IACvG,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,kBAAkB,IAAI,QAAQ,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IAChI,MAAM,MAAM,GAAG,KAAK,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1F,MAAM,aAAa,GAAG,MAAM,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,IAAI,aAAa,KAAK,CAAC;QAClF,CAAC,CAAC,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,GAAG;QAChC,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,MAAM;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,KAAK,IAAI,SAAS;QACzB,aAAa,EAAE,aAAa,IAAI,SAAS;QACzC,MAAM;QACN,aAAa;QACb,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS;QAC5C,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS;QAC5C,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS;QAC1C,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS;QAChD,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC;KACvC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAOvC;IACC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC;IAE/C,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC;YACrC,MAAM;YACN,KAAK;YACL,SAAS;YACT,QAAQ;YACR,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,YAAY,EAAE,GAAG,CAAC,YAAY;SAC/B,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,sBAAsB,KAAK,EAAE,CAAC;IACpG,OAAO;QACL,MAAM,EAAE;YACN,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACpC,MAAM;YACN,KAAK;SACN;QACD,QAAQ,EAAE,CAAC;gBACT,IAAI,EAAE,KAAK;gBACX,GAAG,EAAE,QAAQ;gBACb,OAAO,EAAE,wBAAwB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,aAAa;gBAClF,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;KACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface YahooNewsItem {
|
|
2
|
+
title: string;
|
|
3
|
+
link: string;
|
|
4
|
+
publisher?: string;
|
|
5
|
+
publishedAt?: string;
|
|
6
|
+
type?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Fetch Yahoo Finance news items by symbol or query.
|
|
10
|
+
* @tool
|
|
11
|
+
* @effect none
|
|
12
|
+
*/
|
|
13
|
+
export declare function yahooFinanceNews(args: {
|
|
14
|
+
query?: string;
|
|
15
|
+
symbol?: string;
|
|
16
|
+
newsCount?: number;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
maxBytes?: number;
|
|
19
|
+
}): Promise<{
|
|
20
|
+
result: {
|
|
21
|
+
query: string;
|
|
22
|
+
count: number;
|
|
23
|
+
news: YahooNewsItem[];
|
|
24
|
+
};
|
|
25
|
+
evidence: {
|
|
26
|
+
type: string;
|
|
27
|
+
ref: string;
|
|
28
|
+
summary: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
}[];
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=yahooFinanceNews.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yahooFinanceNews.d.ts","sourceRoot":"","sources":["../../../src/http/yahooFinanceNews.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA2HD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;GA8BA"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { getExtensionContext } from "../../index.js";
|
|
2
|
+
import { DEFAULT_TIMEOUT_MS, DEFAULT_MAX_HTTP_BYTES, DEFAULT_HTTP_USER_AGENT, DEFAULT_BLOCKED_CIDRS, } from "./defaults.js";
|
|
3
|
+
import { createTaggedError } from "@botbotgo/kit/sdk";
|
|
4
|
+
import { validateUrl } from "../platform/securityCompat.js";
|
|
5
|
+
import { overrideWithConfig } from "../util/overrideWithConfig.js";
|
|
6
|
+
const YAHOO_SEARCH_BASE = "https://query2.finance.yahoo.com/v1/finance/search";
|
|
7
|
+
function getYahooConfig() {
|
|
8
|
+
const defaults = {
|
|
9
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
10
|
+
maxBytes: DEFAULT_MAX_HTTP_BYTES,
|
|
11
|
+
userAgent: DEFAULT_HTTP_USER_AGENT,
|
|
12
|
+
blockedCidrs: DEFAULT_BLOCKED_CIDRS,
|
|
13
|
+
allowedHosts: [],
|
|
14
|
+
blockedHosts: [],
|
|
15
|
+
};
|
|
16
|
+
const cfg = overrideWithConfig(defaults, getExtensionContext().config);
|
|
17
|
+
return {
|
|
18
|
+
timeoutMs: cfg.timeoutMs ?? defaults.timeoutMs,
|
|
19
|
+
maxBytes: cfg.maxBytes ?? defaults.maxBytes,
|
|
20
|
+
userAgent: cfg.userAgent ?? defaults.userAgent,
|
|
21
|
+
blockedCidrs: Array.isArray(cfg.blockedCidrs) ? cfg.blockedCidrs : defaults.blockedCidrs,
|
|
22
|
+
allowedHosts: Array.isArray(cfg.allowedHosts) ? cfg.allowedHosts : defaults.allowedHosts,
|
|
23
|
+
blockedHosts: Array.isArray(cfg.blockedHosts) ? cfg.blockedHosts : defaults.blockedHosts,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function normalizeYahooNewsInput(args) {
|
|
27
|
+
const query = (args.query ?? args.symbol ?? "").trim();
|
|
28
|
+
if (!query) {
|
|
29
|
+
throw createTaggedError("YAHOO_INVALID", "query or symbol is required", {});
|
|
30
|
+
}
|
|
31
|
+
const rawCount = typeof args.newsCount === "number" ? args.newsCount : 10;
|
|
32
|
+
const newsCount = Math.max(1, Math.min(50, Math.floor(rawCount)));
|
|
33
|
+
return { query, newsCount };
|
|
34
|
+
}
|
|
35
|
+
async function fetchYahooSearchJson(args) {
|
|
36
|
+
const url = `${YAHOO_SEARCH_BASE}?q=${encodeURIComponent(args.query)}"esCount=0&newsCount=${args.newsCount}`;
|
|
37
|
+
await validateUrl(url, {
|
|
38
|
+
allowedHosts: args.allowedHosts,
|
|
39
|
+
blockedHosts: args.blockedHosts,
|
|
40
|
+
blockedCidrs: args.blockedCidrs,
|
|
41
|
+
});
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
const timer = setTimeout(() => controller.abort(), args.timeoutMs);
|
|
44
|
+
let response;
|
|
45
|
+
try {
|
|
46
|
+
response = await fetch(url, {
|
|
47
|
+
method: "GET",
|
|
48
|
+
headers: { "User-Agent": args.userAgent, Accept: "application/json" },
|
|
49
|
+
signal: controller.signal,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
55
|
+
throw createTaggedError("HTTP_TIMEOUT", `Yahoo Finance search for ${args.query} timed out after ${args.timeoutMs}ms`, {
|
|
56
|
+
query: args.query,
|
|
57
|
+
timeoutMs: args.timeoutMs,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
throw createTaggedError("UPSTREAM_ERROR", `Yahoo Finance search failed: ${err instanceof Error ? err.message : String(err)}`, {
|
|
61
|
+
query: args.query,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
const text = await response.text();
|
|
66
|
+
const bytes = Buffer.byteLength(text, "utf-8");
|
|
67
|
+
if (bytes > args.maxBytes) {
|
|
68
|
+
throw createTaggedError("HTTP_TOO_LARGE", `Yahoo Finance search response ${bytes} bytes exceeds limit of ${args.maxBytes} bytes`, {
|
|
69
|
+
query: args.query,
|
|
70
|
+
bytes,
|
|
71
|
+
limit: args.maxBytes,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(text);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw createTaggedError("UPSTREAM_ERROR", "Yahoo Finance search returned invalid JSON", {
|
|
79
|
+
query: args.query,
|
|
80
|
+
textPreview: text.slice(0, 200),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function toYahooNewsItems(response) {
|
|
85
|
+
const items = Array.isArray(response.news) ? response.news : [];
|
|
86
|
+
return items
|
|
87
|
+
.filter((item) => typeof item?.title === "string" && typeof item?.link === "string")
|
|
88
|
+
.map((item) => {
|
|
89
|
+
const publishedAt = typeof item.providerPublishTime === "number"
|
|
90
|
+
? new Date(item.providerPublishTime * 1000).toISOString()
|
|
91
|
+
: undefined;
|
|
92
|
+
return {
|
|
93
|
+
title: String(item.title),
|
|
94
|
+
link: String(item.link),
|
|
95
|
+
publisher: typeof item.publisher === "string" ? item.publisher : undefined,
|
|
96
|
+
publishedAt,
|
|
97
|
+
type: typeof item.type === "string" ? item.type : undefined,
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fetch Yahoo Finance news items by symbol or query.
|
|
103
|
+
* @tool
|
|
104
|
+
* @effect none
|
|
105
|
+
*/
|
|
106
|
+
export async function yahooFinanceNews(args) {
|
|
107
|
+
const cfg = getYahooConfig();
|
|
108
|
+
const { query, newsCount } = normalizeYahooNewsInput(args);
|
|
109
|
+
const timeoutMs = args.timeoutMs ?? cfg.timeoutMs;
|
|
110
|
+
const maxBytes = args.maxBytes ?? cfg.maxBytes;
|
|
111
|
+
const data = await fetchYahooSearchJson({
|
|
112
|
+
query,
|
|
113
|
+
newsCount,
|
|
114
|
+
timeoutMs,
|
|
115
|
+
maxBytes,
|
|
116
|
+
userAgent: cfg.userAgent,
|
|
117
|
+
allowedHosts: cfg.allowedHosts,
|
|
118
|
+
blockedHosts: cfg.blockedHosts,
|
|
119
|
+
blockedCidrs: cfg.blockedCidrs,
|
|
120
|
+
});
|
|
121
|
+
const news = toYahooNewsItems(data);
|
|
122
|
+
const ref = `${YAHOO_SEARCH_BASE}?q=${encodeURIComponent(query)}"esCount=0&newsCount=${newsCount}`;
|
|
123
|
+
return {
|
|
124
|
+
result: {
|
|
125
|
+
query,
|
|
126
|
+
count: news.length,
|
|
127
|
+
news,
|
|
128
|
+
},
|
|
129
|
+
evidence: [{
|
|
130
|
+
type: "url",
|
|
131
|
+
ref,
|
|
132
|
+
summary: `Yahoo Finance news: ${query} (${news.length} item(s))`,
|
|
133
|
+
createdAt: new Date().toISOString(),
|
|
134
|
+
}],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=yahooFinanceNews.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yahooFinanceNews.js","sourceRoot":"","sources":["../../../src/http/yahooFinanceNews.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botbotgo/kit-builtin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.94",
|
|
4
4
|
"description": "Tools extension for @botbotgo/kit: FS, HTTP, util, security (sandbox, SSRF). Same contract as any other extension.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,13 +18,15 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"dist"
|
|
21
|
+
"dist",
|
|
22
|
+
"skills"
|
|
22
23
|
],
|
|
23
24
|
"scripts": {
|
|
24
25
|
"preinstall": "node -e \"const fs=require('fs'); const {execSync}=require('child_process'); if (fs.existsSync('scripts/resolve-deps.js')) { execSync('node scripts/resolve-deps.js', { stdio: 'inherit' }); } else { console.log('Skipping resolve-deps for published package'); }\"",
|
|
25
26
|
"prebuild": "npm run build --prefix ../kit 2>/dev/null || true",
|
|
26
|
-
"build": "npm run check:tool-files && tsx generate-manifest.ts && tsc -p tsconfig.build.json && (mkdir -p dist/config && cp config/tool.yaml dist/config/tool.yaml)",
|
|
27
|
+
"build": "npm run check:tool-files && npm run check:skill-assets && tsx generate-manifest.ts && tsc -p tsconfig.build.json && (mkdir -p dist/config && cp config/tool.yaml dist/config/tool.yaml)",
|
|
27
28
|
"check:tool-files": "tsx scripts/check-tool-files.ts",
|
|
29
|
+
"check:skill-assets": "tsx scripts/check-skill-assets.ts",
|
|
28
30
|
"clean": "rm -rf dist",
|
|
29
31
|
"pretest": "npm run build",
|
|
30
32
|
"test": "vitest run",
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: company-report
|
|
3
|
+
description: Generate structured JSON company report data for a target company/ticker.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Company Report Workflow (JSON + HTML)
|
|
7
|
+
|
|
8
|
+
Write these files:
|
|
9
|
+
|
|
10
|
+
- `output/company-report.json` (generated by model)
|
|
11
|
+
- `output/company-report.html` (generated by script call)
|
|
12
|
+
|
|
13
|
+
## Inputs
|
|
14
|
+
|
|
15
|
+
- `COMPANY` (required)
|
|
16
|
+
- `SYMBOL` (preferred)
|
|
17
|
+
|
|
18
|
+
If `COMPANY` is missing, ask one clarifying question.
|
|
19
|
+
|
|
20
|
+
## Workflow (in order)
|
|
21
|
+
|
|
22
|
+
1. Resolve `COMPANY` and `SYMBOL`.
|
|
23
|
+
2. Fetch quote with exact args:
|
|
24
|
+
`yahooFinanceQuote({"symbol":"<SYMBOL>"})`
|
|
25
|
+
3. Fetch news with exact args:
|
|
26
|
+
`yahooFinanceNews({"symbol":"<SYMBOL>","newsCount":5})`
|
|
27
|
+
4. If news is empty/failed, retry `yahooFinanceNews` once with `query=COMPANY`.
|
|
28
|
+
5. Write `output/company-report.json` after quote+news steps have been attempted.
|
|
29
|
+
6. Call execute tool to run:
|
|
30
|
+
`node scripts/merge-report.mjs output/company-report.json output/company-report.html references/company-report.template.html`
|
|
31
|
+
|
|
32
|
+
Notes:
|
|
33
|
+
|
|
34
|
+
- Quote/news calls are independent and can run in parallel.
|
|
35
|
+
- Do not perform unrelated exploration.
|
|
36
|
+
- Do not handwrite HTML content directly.
|
|
37
|
+
- Do not call `glob` or `inspect files`.
|
|
38
|
+
- Do not re-read output files after writing.
|
|
39
|
+
- Write `output/company-report.json` exactly once.
|
|
40
|
+
- Run merge script exactly once.
|
|
41
|
+
- After merge succeeds, stop.
|
|
42
|
+
|
|
43
|
+
## Output Schema
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"company": {
|
|
48
|
+
"name": "string",
|
|
49
|
+
"symbol": "string",
|
|
50
|
+
"generatedAt": "YYYY-MM-DD"
|
|
51
|
+
},
|
|
52
|
+
"overview": ["paragraph1", "paragraph2"],
|
|
53
|
+
"stock": {
|
|
54
|
+
"available": true,
|
|
55
|
+
"summary": "string",
|
|
56
|
+
"metrics": {
|
|
57
|
+
"symbol": "string",
|
|
58
|
+
"price": 0,
|
|
59
|
+
"change": 0,
|
|
60
|
+
"changePercent": 0,
|
|
61
|
+
"dayLow": 0,
|
|
62
|
+
"dayHigh": 0,
|
|
63
|
+
"volume": 0,
|
|
64
|
+
"currency": "USD"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"news": [
|
|
68
|
+
{
|
|
69
|
+
"headline": "string",
|
|
70
|
+
"url": "https://...",
|
|
71
|
+
"source": "string",
|
|
72
|
+
"date": "YYYY-MM-DD",
|
|
73
|
+
"summary": "string"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"sources": [
|
|
77
|
+
{
|
|
78
|
+
"name": "string",
|
|
79
|
+
"url": "https://..."
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Failure Policy
|
|
86
|
+
|
|
87
|
+
- If quote fetch fails: set `stock.available=false` and provide placeholders.
|
|
88
|
+
- If all news fetches fail/empty: set `news=[]`.
|
|
89
|
+
- Never skip JSON generation because of partial data failure.
|
|
90
|
+
- Always run merge script after JSON is written.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Company Report Viewer</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700;800&display=swap" rel="stylesheet" />
|
|
10
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" />
|
|
11
|
+
<style>
|
|
12
|
+
:root {
|
|
13
|
+
--bg: #f4f7fb;
|
|
14
|
+
--ink: #13253a;
|
|
15
|
+
--muted: #5f738c;
|
|
16
|
+
--brand: #0f4c81;
|
|
17
|
+
--brand-soft: #e6eef7;
|
|
18
|
+
--card-border: #d7e2ef;
|
|
19
|
+
}
|
|
20
|
+
body { font-family: "Manrope", "Segoe UI", sans-serif; color: var(--ink); background: var(--bg); }
|
|
21
|
+
.report-wrap { max-width: 1080px; margin: 0 auto; padding: 2rem 1rem 3rem; }
|
|
22
|
+
.hero { background: linear-gradient(135deg, #0f4c81 0%, #1a6aa8 100%); color: #fff; border-radius: 1rem; padding: 1.25rem; margin-bottom: 1.25rem; }
|
|
23
|
+
.section-card { background: #fff; border: 1px solid var(--card-border); border-radius: .9rem; margin-bottom: 1rem; overflow: hidden; }
|
|
24
|
+
.section-head { background: var(--brand-soft); color: var(--brand); font-weight: 800; text-transform: uppercase; letter-spacing: .04em; font-size: .78rem; padding: .7rem 1rem; }
|
|
25
|
+
.section-body { padding: 1rem; }
|
|
26
|
+
.news-item + .news-item { margin-top: .75rem; }
|
|
27
|
+
.news-link { font-weight: 700; color: #15395f; text-decoration: none; }
|
|
28
|
+
.news-link:hover { text-decoration: underline; }
|
|
29
|
+
.news-meta { color: var(--muted); font-size: .85rem; }
|
|
30
|
+
.error-box { border: 1px solid #f0b4b4; background: #fff2f2; color: #862b2b; border-radius: .75rem; padding: .75rem 1rem; }
|
|
31
|
+
</style>
|
|
32
|
+
</head>
|
|
33
|
+
<body>
|
|
34
|
+
<main class="report-wrap">
|
|
35
|
+
<header class="hero">
|
|
36
|
+
<h1 id="hero-title" class="h2 m-0">Company Report</h1>
|
|
37
|
+
<p id="hero-date" class="m-0" style="opacity:.9;">Generated: -</p>
|
|
38
|
+
</header>
|
|
39
|
+
|
|
40
|
+
<section id="company-overview" class="section-card">
|
|
41
|
+
<div class="section-head">1. Company Overview</div>
|
|
42
|
+
<div id="overview-body" class="section-body"></div>
|
|
43
|
+
</section>
|
|
44
|
+
|
|
45
|
+
<section id="stock-data" class="section-card">
|
|
46
|
+
<div class="section-head">2. Stock Data</div>
|
|
47
|
+
<div class="section-body">
|
|
48
|
+
<p id="stock-summary" class="news-meta"></p>
|
|
49
|
+
<div class="table-responsive">
|
|
50
|
+
<table class="table table-striped table-hover align-middle mb-0">
|
|
51
|
+
<thead><tr><th>Metric</th><th>Value</th></tr></thead>
|
|
52
|
+
<tbody id="stock-table-body"></tbody>
|
|
53
|
+
</table>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</section>
|
|
57
|
+
|
|
58
|
+
<section id="news" class="section-card">
|
|
59
|
+
<div class="section-head">3. Recent News</div>
|
|
60
|
+
<div id="news-body" class="section-body"></div>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section id="sources" class="section-card">
|
|
64
|
+
<div class="section-head">4. Sources</div>
|
|
65
|
+
<div class="section-body"><ul id="sources-list" class="list-unstyled mb-0"></ul></div>
|
|
66
|
+
</section>
|
|
67
|
+
|
|
68
|
+
<div id="error" class="error-box d-none"></div>
|
|
69
|
+
</main>
|
|
70
|
+
|
|
71
|
+
<script>
|
|
72
|
+
const REPORT_DATA = __REPORT_JSON__;
|
|
73
|
+
|
|
74
|
+
function esc(v) {
|
|
75
|
+
return String(v ?? "")
|
|
76
|
+
.replaceAll("&", "&")
|
|
77
|
+
.replaceAll("<", "<")
|
|
78
|
+
.replaceAll(">", ">")
|
|
79
|
+
.replaceAll('"', """)
|
|
80
|
+
.replaceAll("'", "'");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function num(v, digits = 2) {
|
|
84
|
+
return typeof v === "number" && Number.isFinite(v)
|
|
85
|
+
? v.toLocaleString("en-US", { minimumFractionDigits: digits, maximumFractionDigits: digits })
|
|
86
|
+
: "Not available";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function int(v) {
|
|
90
|
+
return typeof v === "number" && Number.isFinite(v)
|
|
91
|
+
? v.toLocaleString("en-US")
|
|
92
|
+
: "Not available";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function renderReport(data) {
|
|
96
|
+
const errorEl = document.getElementById("error");
|
|
97
|
+
try {
|
|
98
|
+
const company = data.company ?? {};
|
|
99
|
+
const stock = data.stock ?? {};
|
|
100
|
+
const metrics = stock.metrics ?? {};
|
|
101
|
+
const stockAvailable = stock.available === true;
|
|
102
|
+
|
|
103
|
+
document.getElementById("hero-title").textContent = `Company Report: ${company.name ?? "Unknown"}`;
|
|
104
|
+
document.getElementById("hero-date").textContent = `Generated: ${company.generatedAt ?? "-"}`;
|
|
105
|
+
|
|
106
|
+
const overview = Array.isArray(data.overview) ? data.overview : [];
|
|
107
|
+
const overviewBody = document.getElementById("overview-body");
|
|
108
|
+
overviewBody.innerHTML = overview.length
|
|
109
|
+
? overview.map((p) => `<p>${esc(p)}</p>`).join("")
|
|
110
|
+
: `<p class="news-meta">Overview not available.</p>`;
|
|
111
|
+
|
|
112
|
+
document.getElementById("stock-summary").textContent = stock.summary ?? "Stock summary not available.";
|
|
113
|
+
const stockRows = [
|
|
114
|
+
["Symbol", metrics.symbol ?? company.symbol ?? "N/A"],
|
|
115
|
+
["Price", stockAvailable ? num(metrics.price) : "Not available"],
|
|
116
|
+
["Change", (stockAvailable && typeof metrics.change === "number" && typeof metrics.changePercent === "number")
|
|
117
|
+
? `${metrics.change >= 0 ? "+" : ""}${num(metrics.change)} (${metrics.changePercent >= 0 ? "+" : ""}${num(metrics.changePercent)}%)`
|
|
118
|
+
: "Not available"],
|
|
119
|
+
["Day Range", stockAvailable ? `${num(metrics.dayLow)} - ${num(metrics.dayHigh)}` : "Not available"],
|
|
120
|
+
["Volume", stockAvailable ? int(metrics.volume) : "Not available"],
|
|
121
|
+
];
|
|
122
|
+
document.getElementById("stock-table-body").innerHTML = stockRows
|
|
123
|
+
.map(([k, v]) => `<tr><td>${esc(k)}</td><td>${esc(v)}</td></tr>`)
|
|
124
|
+
.join("");
|
|
125
|
+
|
|
126
|
+
const news = Array.isArray(data.news) ? data.news : [];
|
|
127
|
+
const newsBody = document.getElementById("news-body");
|
|
128
|
+
newsBody.innerHTML = news.length
|
|
129
|
+
? news.map((n) => `
|
|
130
|
+
<div class="news-item">
|
|
131
|
+
<a class="news-link" href="${esc(n.url ?? "#")}">${esc(n.headline ?? "Untitled")}</a>
|
|
132
|
+
<div class="news-meta">${esc(n.source ?? "Unknown")}${n.date ? ` • ${esc(n.date)}` : ""}</div>
|
|
133
|
+
${n.summary ? `<div class="news-meta mt-1">${esc(n.summary)}</div>` : ""}
|
|
134
|
+
</div>
|
|
135
|
+
`).join("")
|
|
136
|
+
: `<div class="news-meta">No recent news found.</div>`;
|
|
137
|
+
|
|
138
|
+
const sources = Array.isArray(data.sources) ? data.sources : [];
|
|
139
|
+
document.getElementById("sources-list").innerHTML = sources.length
|
|
140
|
+
? sources.map((s) => `<li><a href="${esc(s.url ?? "#")}">${esc(s.name ?? "Source")}</a></li>`).join("")
|
|
141
|
+
: `<li>No sources available.</li>`;
|
|
142
|
+
} catch (err) {
|
|
143
|
+
errorEl.classList.remove("d-none");
|
|
144
|
+
errorEl.textContent = err instanceof Error ? err.message : String(err);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
renderReport(REPORT_DATA);
|
|
149
|
+
</script>
|
|
150
|
+
</body>
|
|
151
|
+
</html>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
|
|
7
|
+
export async function mergeReportHtml(jsonPath, htmlPath, templatePath) {
|
|
8
|
+
if (!existsSync(jsonPath)) {
|
|
9
|
+
throw new Error(`Missing JSON report: ${jsonPath}`);
|
|
10
|
+
}
|
|
11
|
+
if (!existsSync(templatePath)) {
|
|
12
|
+
throw new Error(`Missing HTML template: ${templatePath}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const report = JSON.parse(await readFile(jsonPath, "utf8"));
|
|
16
|
+
const template = await readFile(templatePath, "utf8");
|
|
17
|
+
const html = template.replace(/__REPORT_JSON__/g, JSON.stringify(report));
|
|
18
|
+
await writeFile(htmlPath, html, "utf8");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function main() {
|
|
22
|
+
const root = process.cwd();
|
|
23
|
+
const jsonPath = resolve(root, process.argv[2] || "output/company-report.json");
|
|
24
|
+
const htmlPath = resolve(root, process.argv[3] || "output/company-report.html");
|
|
25
|
+
const templatePath = resolve(
|
|
26
|
+
root,
|
|
27
|
+
process.argv[4] || "skills/company-report/references/company-report.template.html",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
await mergeReportHtml(jsonPath, htmlPath, templatePath);
|
|
31
|
+
process.stdout.write(`Merged report written to: ${htmlPath}\n`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const entrypointUrl = process.argv[1] ? pathToFileURL(realpathSync(resolve(process.argv[1]))).href : "";
|
|
35
|
+
|
|
36
|
+
if (import.meta.url === entrypointUrl) {
|
|
37
|
+
main().catch((error) => {
|
|
38
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-prompt-ops
|
|
3
|
+
description: Execute project-scoped instructions by calling Codex, Claude, or Cursor shell CLI in prompt mode. Use when the user asks to create, update, query, or question a specific project through codex/claude/cursor command-line workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Prompt Ops
|
|
7
|
+
|
|
8
|
+
Use shell prompt mode with exactly one provider and one mode per request.
|
|
9
|
+
Allowed providers: `codex`, `claude`, `cursor`.
|
|
10
|
+
Allowed modes: `create`, `update`, `query`, `question`.
|
|
11
|
+
|
|
12
|
+
## Inputs
|
|
13
|
+
|
|
14
|
+
- `PROJECT`: required project path
|
|
15
|
+
- `INSTRUCTION`: required task instruction
|
|
16
|
+
- `MODE`: optional explicit mode; infer if omitted
|
|
17
|
+
- `PROVIDER`: optional explicit provider; infer if omitted
|
|
18
|
+
|
|
19
|
+
If `PROJECT` is missing, ask one concise question and stop.
|
|
20
|
+
|
|
21
|
+
## Required Reads
|
|
22
|
+
|
|
23
|
+
1. `references/REQUEST_PATTERNS.md`
|
|
24
|
+
|
|
25
|
+
## Selection Rules
|
|
26
|
+
|
|
27
|
+
### Mode
|
|
28
|
+
|
|
29
|
+
- `create`: add new files or new behavior
|
|
30
|
+
- `update`: change existing behavior
|
|
31
|
+
- `query`: inspect codebase without edits
|
|
32
|
+
- `question`: answer technical question without edits
|
|
33
|
+
|
|
34
|
+
When ambiguous, prefer lower-risk mode in this order:
|
|
35
|
+
|
|
36
|
+
1. `query`
|
|
37
|
+
2. `question`
|
|
38
|
+
3. `update`
|
|
39
|
+
4. `create`
|
|
40
|
+
|
|
41
|
+
### Provider
|
|
42
|
+
|
|
43
|
+
- If user explicitly names provider, use it.
|
|
44
|
+
- Else default to `codex`.
|
|
45
|
+
|
|
46
|
+
## Mandatory Execution Path
|
|
47
|
+
|
|
48
|
+
Always invoke the script below. Do not directly call `codex`, `claude`, or `cursor-agent` in free-form.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
skills/project-prompt-ops/scripts/run_prompt_mode.sh \
|
|
52
|
+
--provider <codex|claude|cursor> \
|
|
53
|
+
--mode <create|update|query|question> \
|
|
54
|
+
--project <project-path> \
|
|
55
|
+
--instruction "<user-instruction>"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Optional:
|
|
59
|
+
|
|
60
|
+
- `--model <model-name>`
|
|
61
|
+
- `--output <path>`
|
|
62
|
+
- `--dry-run` (preview assembled command and prompt only)
|
|
63
|
+
|
|
64
|
+
The script internally:
|
|
65
|
+
|
|
66
|
+
1. Builds normalized prompt text with mode-specific constraints.
|
|
67
|
+
2. Calls provider shell CLI in prompt mode:
|
|
68
|
+
- `codex exec`
|
|
69
|
+
- `claude -p`
|
|
70
|
+
- `cursor-agent -p`
|
|
71
|
+
3. Returns provider output.
|
|
72
|
+
|
|
73
|
+
## Post-Run Requirements
|
|
74
|
+
|
|
75
|
+
- For `create` and `update`, run a relevant local validation command in `PROJECT` when possible.
|
|
76
|
+
- For `query` and `question`, do not edit project files.
|
|
77
|
+
|
|
78
|
+
## Response Structure
|
|
79
|
+
|
|
80
|
+
- `Mode`
|
|
81
|
+
- `Provider`
|
|
82
|
+
- `Project`
|
|
83
|
+
- `Changes` or `Findings`
|
|
84
|
+
- `Validation`
|
|
85
|
+
- `Open Risks` (only when non-empty)
|
|
86
|
+
|
|
87
|
+
## Constraints
|
|
88
|
+
|
|
89
|
+
- Do not perform destructive operations unless explicitly requested.
|
|
90
|
+
- Do not expand scope outside `PROJECT` unless asked.
|
|
91
|
+
- Do not skip the wrapper script.
|
|
92
|
+
- Keep output concise and implementation-focused.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Request Patterns
|
|
2
|
+
|
|
3
|
+
Use this file only when the user instruction is broad, mixed, or does not provide explicit mode labels.
|
|
4
|
+
|
|
5
|
+
## Canonical Instruction Shape
|
|
6
|
+
|
|
7
|
+
Normalize incoming instruction into:
|
|
8
|
+
|
|
9
|
+
- `project`: absolute or repo-relative path
|
|
10
|
+
- `mode`: create | update | query | question
|
|
11
|
+
- `provider`: codex | claude | cursor
|
|
12
|
+
- `goal`: one-sentence expected outcome
|
|
13
|
+
- `constraints`: tests, style, compatibility, forbidden operations
|
|
14
|
+
- `deliverable`: patch, answer, or findings format
|
|
15
|
+
|
|
16
|
+
## Mode Heuristics
|
|
17
|
+
|
|
18
|
+
- Mentions "add/new/build/implement" -> `create`
|
|
19
|
+
- Mentions "fix/change/modify/refactor/adjust" -> `update`
|
|
20
|
+
- Mentions "where/what/find/list/show" -> `query`
|
|
21
|
+
- Mentions "why/how/should/explain/compare" -> `question`
|
|
22
|
+
|
|
23
|
+
When multiple verbs appear, prioritize the user's final explicit ask.
|
|
24
|
+
|
|
25
|
+
## Provider Heuristics
|
|
26
|
+
|
|
27
|
+
- User explicitly says `codex` -> provider `codex`
|
|
28
|
+
- User explicitly says `claude` -> provider `claude`
|
|
29
|
+
- User explicitly says `cursor` -> provider `cursor`
|
|
30
|
+
- If omitted -> default provider `codex`
|
|
31
|
+
|
|
32
|
+
## Execution Command Template
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
skills/project-prompt-ops/scripts/run_prompt_mode.sh \
|
|
36
|
+
--provider "<provider>" \
|
|
37
|
+
--mode "<mode>" \
|
|
38
|
+
--project "<project>" \
|
|
39
|
+
--instruction "<goal>"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Output Template
|
|
43
|
+
|
|
44
|
+
Use this response shape:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
Mode: <mode>
|
|
48
|
+
Project: <project>
|
|
49
|
+
Changes|Findings:
|
|
50
|
+
- ...
|
|
51
|
+
Validation:
|
|
52
|
+
- command: <cmd or N/A>
|
|
53
|
+
- result: <pass/fail/not run>
|
|
54
|
+
Open Risks:
|
|
55
|
+
- ... (omit section when empty)
|
|
56
|
+
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
MODE=""
|
|
5
|
+
PROJECT=""
|
|
6
|
+
INSTRUCTION=""
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'EOF'
|
|
10
|
+
Usage: build_prompt.sh --mode <create|update|query|question> --project <path> --instruction <text>
|
|
11
|
+
EOF
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
while [[ $# -gt 0 ]]; do
|
|
15
|
+
case "$1" in
|
|
16
|
+
--mode)
|
|
17
|
+
MODE="${2:-}"
|
|
18
|
+
shift 2
|
|
19
|
+
;;
|
|
20
|
+
--project)
|
|
21
|
+
PROJECT="${2:-}"
|
|
22
|
+
shift 2
|
|
23
|
+
;;
|
|
24
|
+
--instruction)
|
|
25
|
+
INSTRUCTION="${2:-}"
|
|
26
|
+
shift 2
|
|
27
|
+
;;
|
|
28
|
+
-h|--help)
|
|
29
|
+
usage
|
|
30
|
+
exit 0
|
|
31
|
+
;;
|
|
32
|
+
*)
|
|
33
|
+
echo "Unknown argument: $1" >&2
|
|
34
|
+
usage >&2
|
|
35
|
+
exit 2
|
|
36
|
+
;;
|
|
37
|
+
esac
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
if [[ -z "$MODE" || -z "$PROJECT" || -z "$INSTRUCTION" ]]; then
|
|
41
|
+
usage >&2
|
|
42
|
+
exit 2
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
case "$MODE" in
|
|
46
|
+
create)
|
|
47
|
+
MODE_RULE="Create new code/files as requested. Keep scope strictly inside project and wire minimal required integration points."
|
|
48
|
+
;;
|
|
49
|
+
update)
|
|
50
|
+
MODE_RULE="Update existing code with minimal safe diffs. Preserve unrelated behavior and avoid broad refactors."
|
|
51
|
+
;;
|
|
52
|
+
query)
|
|
53
|
+
MODE_RULE="Read and analyze only. Do not modify files. Return concrete findings with file path references."
|
|
54
|
+
;;
|
|
55
|
+
question)
|
|
56
|
+
MODE_RULE="Answer the technical question directly. Do not modify files unless explicitly requested."
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
echo "Invalid mode: $MODE" >&2
|
|
60
|
+
exit 2
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
|
|
64
|
+
cat <<EOF
|
|
65
|
+
You are running in ${MODE} mode for a single project.
|
|
66
|
+
|
|
67
|
+
Project path:
|
|
68
|
+
${PROJECT}
|
|
69
|
+
|
|
70
|
+
User instruction:
|
|
71
|
+
${INSTRUCTION}
|
|
72
|
+
|
|
73
|
+
Rules:
|
|
74
|
+
- ${MODE_RULE}
|
|
75
|
+
- Stay within the specified project path.
|
|
76
|
+
- Avoid destructive operations unless explicitly requested.
|
|
77
|
+
- Keep response concise and implementation-focused.
|
|
78
|
+
- If editing is performed (create/update), include a short validation result.
|
|
79
|
+
|
|
80
|
+
Output format:
|
|
81
|
+
- Mode: ${MODE}
|
|
82
|
+
- Summary:
|
|
83
|
+
- Details:
|
|
84
|
+
- Validation:
|
|
85
|
+
- Risks: (omit if none)
|
|
86
|
+
EOF
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
|
|
6
|
+
PROVIDER=""
|
|
7
|
+
MODE=""
|
|
8
|
+
PROJECT=""
|
|
9
|
+
INSTRUCTION=""
|
|
10
|
+
MODEL=""
|
|
11
|
+
OUTPUT=""
|
|
12
|
+
DRY_RUN="false"
|
|
13
|
+
|
|
14
|
+
usage() {
|
|
15
|
+
cat <<'EOF'
|
|
16
|
+
Usage:
|
|
17
|
+
run_prompt_mode.sh \
|
|
18
|
+
--provider <codex|claude|cursor> \
|
|
19
|
+
--mode <create|update|query|question> \
|
|
20
|
+
--project <path> \
|
|
21
|
+
--instruction <text> \
|
|
22
|
+
[--model <model>] \
|
|
23
|
+
[--output <file>] \
|
|
24
|
+
[--dry-run]
|
|
25
|
+
EOF
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
while [[ $# -gt 0 ]]; do
|
|
29
|
+
case "$1" in
|
|
30
|
+
--provider)
|
|
31
|
+
PROVIDER="${2:-}"
|
|
32
|
+
shift 2
|
|
33
|
+
;;
|
|
34
|
+
--mode)
|
|
35
|
+
MODE="${2:-}"
|
|
36
|
+
shift 2
|
|
37
|
+
;;
|
|
38
|
+
--project)
|
|
39
|
+
PROJECT="${2:-}"
|
|
40
|
+
shift 2
|
|
41
|
+
;;
|
|
42
|
+
--instruction)
|
|
43
|
+
INSTRUCTION="${2:-}"
|
|
44
|
+
shift 2
|
|
45
|
+
;;
|
|
46
|
+
--model)
|
|
47
|
+
MODEL="${2:-}"
|
|
48
|
+
shift 2
|
|
49
|
+
;;
|
|
50
|
+
--output)
|
|
51
|
+
OUTPUT="${2:-}"
|
|
52
|
+
shift 2
|
|
53
|
+
;;
|
|
54
|
+
--dry-run)
|
|
55
|
+
DRY_RUN="true"
|
|
56
|
+
shift
|
|
57
|
+
;;
|
|
58
|
+
-h|--help)
|
|
59
|
+
usage
|
|
60
|
+
exit 0
|
|
61
|
+
;;
|
|
62
|
+
*)
|
|
63
|
+
echo "Unknown argument: $1" >&2
|
|
64
|
+
usage >&2
|
|
65
|
+
exit 2
|
|
66
|
+
;;
|
|
67
|
+
esac
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
if [[ -z "$PROVIDER" || -z "$MODE" || -z "$PROJECT" || -z "$INSTRUCTION" ]]; then
|
|
71
|
+
usage >&2
|
|
72
|
+
exit 2
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
if [[ ! -d "$PROJECT" ]]; then
|
|
76
|
+
echo "Project path not found: $PROJECT" >&2
|
|
77
|
+
exit 2
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
PROJECT_ABS="$(cd "$PROJECT" && pwd)"
|
|
81
|
+
|
|
82
|
+
PROMPT="$("$SCRIPT_DIR/build_prompt.sh" \
|
|
83
|
+
--mode "$MODE" \
|
|
84
|
+
--project "$PROJECT_ABS" \
|
|
85
|
+
--instruction "$INSTRUCTION")"
|
|
86
|
+
|
|
87
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
88
|
+
echo "provider: $PROVIDER"
|
|
89
|
+
echo "mode: $MODE"
|
|
90
|
+
echo "project: $PROJECT_ABS"
|
|
91
|
+
if [[ -n "$MODEL" ]]; then
|
|
92
|
+
echo "model: $MODEL"
|
|
93
|
+
fi
|
|
94
|
+
echo "----- prompt begin -----"
|
|
95
|
+
echo "$PROMPT"
|
|
96
|
+
echo "----- prompt end -----"
|
|
97
|
+
exit 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
run_and_capture() {
|
|
101
|
+
if [[ -n "$OUTPUT" ]]; then
|
|
102
|
+
mkdir -p "$(dirname "$OUTPUT")"
|
|
103
|
+
"$@" | tee "$OUTPUT"
|
|
104
|
+
else
|
|
105
|
+
"$@"
|
|
106
|
+
fi
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
case "$PROVIDER" in
|
|
110
|
+
codex)
|
|
111
|
+
if ! command -v codex >/dev/null 2>&1; then
|
|
112
|
+
echo "codex command not found" >&2
|
|
113
|
+
exit 127
|
|
114
|
+
fi
|
|
115
|
+
CMD=(codex exec --cd "$PROJECT_ABS")
|
|
116
|
+
if [[ -n "$MODEL" ]]; then
|
|
117
|
+
CMD+=(--model "$MODEL")
|
|
118
|
+
fi
|
|
119
|
+
CMD+=("$PROMPT")
|
|
120
|
+
run_and_capture "${CMD[@]}"
|
|
121
|
+
;;
|
|
122
|
+
claude)
|
|
123
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
124
|
+
echo "claude command not found" >&2
|
|
125
|
+
exit 127
|
|
126
|
+
fi
|
|
127
|
+
CMD=(claude -p)
|
|
128
|
+
if [[ -n "$MODEL" ]]; then
|
|
129
|
+
CMD+=(--model "$MODEL")
|
|
130
|
+
fi
|
|
131
|
+
CMD+=("$PROMPT")
|
|
132
|
+
(
|
|
133
|
+
cd "$PROJECT_ABS"
|
|
134
|
+
run_and_capture "${CMD[@]}"
|
|
135
|
+
)
|
|
136
|
+
;;
|
|
137
|
+
cursor)
|
|
138
|
+
if ! command -v cursor-agent >/dev/null 2>&1; then
|
|
139
|
+
echo "cursor-agent command not found" >&2
|
|
140
|
+
exit 127
|
|
141
|
+
fi
|
|
142
|
+
CMD=(cursor-agent -p --workspace "$PROJECT_ABS" --output-format text)
|
|
143
|
+
if [[ -n "$MODEL" ]]; then
|
|
144
|
+
CMD+=(--model "$MODEL")
|
|
145
|
+
fi
|
|
146
|
+
CMD+=("$PROMPT")
|
|
147
|
+
run_and_capture "${CMD[@]}"
|
|
148
|
+
;;
|
|
149
|
+
*)
|
|
150
|
+
echo "Unsupported provider: $PROVIDER" >&2
|
|
151
|
+
exit 2
|
|
152
|
+
;;
|
|
153
|
+
esac
|