Help us improve
Share bugs, ideas, or general feedback.
From finny
Decide when to call Finny (vs answering from Claude's own knowledge) and which of the three finny_* tools to use. Activates when the user asks a question about ShareChat financial data, NetSuite records, vendors, bills, GSTIN, or POs.
npx claudepluginhub postergully/finny-claude-plugin --plugin finnyHow this skill is triggered — by the user, by Claude, or both
Slash command
/finny:finny-usage <question><question>The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Finny is the ShareChat NetSuite agent. Call her when the user asks about
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
Finny is the ShareChat NetSuite agent. Call her when the user asks about
actual ShareChat financial data — never for generic accounting or schema
questions. Every Finny call MUST be followed by a judging-output pass before
the user sees an answer.
Call Finny if ANY of these are true:
Do NOT call Finny for:
When in doubt and the question touches live data, call Finny.
Pick one. In rough order of preference:
finny_report — matches a registered reportUse when the question clearly maps to one of the 6 registered reports. This is the most predictable surface — the preamble is canned, so Finny's answer shape is stable.
Registered reports:
| report | use when the user asks about… |
|---|---|
vendor_balance | open balance for a named vendor |
open_bills | list of open bills (VendBill status IN ('A','D')) |
bill_detail | line items / breakdown of a specific bill |
vendor_summary | 3-query vendor rollup: VendBill + VPrep + PurchOrd |
gstin_lookup | vendor's GSTIN (pulls via REST taxRegistration) |
po_status | PO state, approvals, linked receipts |
If the question matches, finny_report wins over finny_query.
finny_query — free-form natural-language questionThe 90% tool. Use when the question is about live data but doesn't match a registered report, or combines signals ("show me the top 5 vendors by open balance whose GSTIN starts with 29").
Pass:
question — the user's question, lightly cleaned up.expected_shape — 'scalar' for counts/totals, 'rows' for lists,
'narrative' for explain/why questions.entity_hints — at minimum { env: 'production' }.finny_task_status — poll a running taskOnly use to poll a task_id returned by a prior finny_query or
finny_report call that came back with status: 'running'. Never invoked
standalone. Poll every 5–10 s; see judging-output for retry limits.
env: default 'production'. Switch to 'sandbox' only if the user
explicitly asks or is clearly testing. Never silently switch envs.deadline_ms: default 10000 for finny_query (returns running
quickly so the cowork agent can poll). For reports known to be slow
(vendor_summary, bulk open_bills), the user can raise to 60000.expected_shape: guess from the question:
'scalar''rows''narrative'status: 'running'. That means Finny accepted the
task and is working. Poll finny_task_status({task_id}) instead.data.rows and reformat numbers. The envelope has
already applied ShareChat's flipped sign conventions (sandbox vs prod).
Re-signing or adding currency symbols will corrupt the answer.status: 'refused' or error.code: 'other' as
retryable. Surface to the user via judging-output. Finny refused for a
reason.finny_task_status without a task_id from a prior
call. There is no listing mode.User: "What's vendor Acme's open balance?"
This matches vendor_balance.
finny_report({
"report": "vendor_balance",
"params": { "vendor_name": "Acme" },
"env": "production"
})
Then hand the envelope to judging-output.
User: "Show me the last 5 open bills for vendor Beta."
There's an open_bills report, but the "for vendor Beta" + "last 5" narrows
it; use finny_query to let Finny compose the right SuiteQL:
finny_query({
"question": "List the last 5 open bills for vendor Beta",
"expected_shape": "rows",
"entity_hints": { "env": "production" }
})
Then hand the envelope to judging-output.
The prior finny_query returned:
{
"status": "running",
"task_id": "task_xyz",
"data": {
"value": "task_xyz",
"rendered_markdown": "{\"task_id\":\"task_xyz\",\"deadline_exceeded_ms\":10000}"
}
}
Note on envelope shape: for
runningenvelopes thetask_idappears at both the top level AND indata.value. Read it from either — they're the same string.data.rendered_markdownholds a JSON blob with{task_id, deadline_exceeded_ms}for debugging; do not parse it for the poll loop.
Wait ~10 s, then:
finny_task_status({ "task_id": "task_xyz" })
Each resulting envelope goes through judging-output. Repeat up to the
limit defined there (don't spin forever).
Every finny_* response — success, partial, running, refused, or error —
MUST pass through the judging-output skill before the user sees anything.
That skill owns:
running poll loop (how often, how many times),error.code branch including the 'other' escape valve for Finny's
semantic self-reports (approval_required, needs_clarification),Call Finny, get envelope, invoke judging-output. No exceptions.