Skill: aronchick/expanso-sentiment-score (version 1.0.0)

# sentiment-score "Score text sentiment from -1 (negative) to +1 (positive)" ## Requirements - Expanso Edge installed (`expanso-edge` binary in PATH) - Install via: `clawhub install expanso-edge` ## Usage ### CLI Pipeline ```bash # Run standalone echo '<input>' | expanso-edge run pipeline-cli.yaml ``` ### MCP Pipeline ```bash # Start as MCP server expanso-edge run pipeline-mcp.yaml ``` ### Deploy to Expanso Cloud ```bash expanso-cli job deploy https://skills.expanso.io/sentiment-score/pipeline-cli.yaml ``` ## Files | File | Purpose | |------|---------| | `skill.yaml` | Skill metadata (inputs, outputs, credentials) | | `pipeline-cli.yaml` | Standalone CLI pipeline | | `pipeline-mcp.yaml` | MCP server pipeline |

path: README.md
content: # sentiment-score

Score text sentiment from -1 (negative) to +1 (positive).

## Usage

```bash
echo "I love this product!" | expanso-edge run pipeline-cli.yaml
echo "This is terrible" | expanso-edge run pipeline-cli.yaml
```

## Output

```json
{"score": 0.85, "label": "positive", "confidence": 0.92}
```


path: pipeline-cli.yaml
content: name: "sentiment-score-cli"
type: pipeline

config:
  input:
    stdin:
      codec: all
      max_buffer: 1048576

  pipeline:
    processors:
      - mapping: |
          meta trace_id = uuid_v4()
          root.messages = [
            {"role": "system", "content": "Score the sentiment of text. Return JSON: 'score' (-1 to 1, decimals ok), 'label' (positive/negative/neutral), 'confidence' (0-1). Be precise."},
            {"role": "user", "content": content()}
          ]

      - openai_chat_completion:
          [REDACTED_SECRET]"
          model: gpt-4o-mini

      - mapping: |
          let r = this.choices.0.message.content.parse_json().catch({"score": 0, "label": "neutral"})
          root.score = $r.score
          root.label = $r.label
          root.confidence = $r.confidence.or(0.5)
          root.metadata = {"skill": "sentiment-score", "mode": "cli", "trace_id": meta("trace_id"), "timestamp": now()}

  output:
    stdout:
      codec: json_object


path: pipeline-mcp.yaml
content: name: "sentiment-score-mcp"
type: pipeline

config:
  http:
    enabled: true
    address: "0.0.0.0:${PORT:-8080}"

  input:
    http_server:
      path: /score
      allowed_verbs: [POST]
      timeout: 60s

  pipeline:
    processors:
      - mapping: |
          let text = this.text.or(content())
          meta trace_id = uuid_v4()
          root.messages = [
            {"role": "system", "content": "Score the sentiment of text. Return JSON: 'score' (-1 to 1), 'label' (positive/negative/neutral), 'confidence' (0-1)."},
            {"role": "user", "content": $text}
          ]

      - openai_chat_completion:
          [REDACTED_SECRET]"
          model: gpt-4o-mini

      - mapping: |
          let r = this.choices.0.message.content.parse_json().catch({"score": 0, "label": "neutral"})
          root.score = $r.score
          root.label = $r.label
          root.confidence = $r.confidence.or(0.5)
          root.metadata = {"skill": "sentiment-score", "mode": "mcp", "trace_id": meta("trace_id"), "timestamp": now()}

  output:
    sync_response: {}

selector:
  match_labels:
    capability: llm


path: skill.yaml
content: # Skill: sentiment-score
name: "sentiment-score"
version: "1.0.0"
description: "Score text sentiment from -1 (negative) to +1 (positive)"

author:
  name: "Expanso Team"
  url: "https://expanso.io"
  avatar: "EX"

credentials:
  - name: OPENAI_API_KEY
    required: false

inputs:
  - name: text
    type: string
    required: true

outputs:
  - name: score
    type: number
    description: Sentiment score -1 to +1
  - name: label
    type: string
    description: positive, negative, or neutral

backends:
  - name: openai
    type: remote
    requires: [OPENAI_API_KEY]
  - name: ollama
    type: local
    models: [llama3.2]

components:
  inputs: [stdin, http_server]
  processors: [mapping, openai_chat_completion]
  outputs: [stdout, sync_response]


path: test/fixtures/input.txt
content: I absolutely love this product!


path: test/test.yaml
content: tests:
  - name: "Score positive text"
    input: "I love this!"
    expected:
      has_field: score
      has_field: label
      metadata_has: [skill, trace_id]


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)