auden 0.1.0-alpha.2
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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/auden-paths.d.ts +8 -0
- package/dist/auden-paths.d.ts.map +1 -0
- package/dist/auden-paths.js +10 -0
- package/dist/auden-paths.js.map +1 -0
- package/dist/bin.d.ts +11 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +13 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk.d.ts +3 -0
- package/dist/chunk.d.ts.map +1 -0
- package/dist/chunk.js +13 -0
- package/dist/chunk.js.map +1 -0
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +125 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/eval/index.d.ts +2 -0
- package/dist/commands/eval/index.d.ts.map +1 -0
- package/dist/commands/eval/index.js +2 -0
- package/dist/commands/eval/index.js.map +1 -0
- package/dist/commands/eval/run.d.ts +38 -0
- package/dist/commands/eval/run.d.ts.map +1 -0
- package/dist/commands/eval/run.js +179 -0
- package/dist/commands/eval/run.js.map +1 -0
- package/dist/commands/guides/active.d.ts +2 -0
- package/dist/commands/guides/active.d.ts.map +1 -0
- package/dist/commands/guides/active.js +38 -0
- package/dist/commands/guides/active.js.map +1 -0
- package/dist/commands/guides/index.d.ts +2 -0
- package/dist/commands/guides/index.d.ts.map +1 -0
- package/dist/commands/guides/index.js +13 -0
- package/dist/commands/guides/index.js.map +1 -0
- package/dist/commands/guides/project.d.ts +13 -0
- package/dist/commands/guides/project.d.ts.map +1 -0
- package/dist/commands/guides/project.js +71 -0
- package/dist/commands/guides/project.js.map +1 -0
- package/dist/commands/guides/search.d.ts +8 -0
- package/dist/commands/guides/search.d.ts.map +1 -0
- package/dist/commands/guides/search.js +46 -0
- package/dist/commands/guides/search.js.map +1 -0
- package/dist/commands/init.d.ts +43 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +436 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.d.ts +23 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +55 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/pull.d.ts +38 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +127 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/rules/export.d.ts +140 -0
- package/dist/commands/rules/export.d.ts.map +1 -0
- package/dist/commands/rules/export.js +635 -0
- package/dist/commands/rules/export.js.map +1 -0
- package/dist/commands/rules/import.d.ts +33 -0
- package/dist/commands/rules/import.d.ts.map +1 -0
- package/dist/commands/rules/import.js +122 -0
- package/dist/commands/rules/import.js.map +1 -0
- package/dist/commands/rules/index.d.ts +2 -0
- package/dist/commands/rules/index.d.ts.map +1 -0
- package/dist/commands/rules/index.js +13 -0
- package/dist/commands/rules/index.js.map +1 -0
- package/dist/commands/rules/watch.d.ts +43 -0
- package/dist/commands/rules/watch.d.ts.map +1 -0
- package/dist/commands/rules/watch.js +125 -0
- package/dist/commands/rules/watch.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +61 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/suggest.d.ts +8 -0
- package/dist/commands/suggest.d.ts.map +1 -0
- package/dist/commands/suggest.js +43 -0
- package/dist/commands/suggest.js.map +1 -0
- package/dist/commands/sync.d.ts +23 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +193 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/verdict/index.d.ts +2 -0
- package/dist/commands/verdict/index.d.ts.map +1 -0
- package/dist/commands/verdict/index.js +11 -0
- package/dist/commands/verdict/index.js.map +1 -0
- package/dist/commands/verdict/record.d.ts +18 -0
- package/dist/commands/verdict/record.d.ts.map +1 -0
- package/dist/commands/verdict/record.js +60 -0
- package/dist/commands/verdict/record.js.map +1 -0
- package/dist/config.d.ts +96 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +246 -0
- package/dist/config.js.map +1 -0
- package/dist/context/pull.d.ts +40 -0
- package/dist/context/pull.d.ts.map +1 -0
- package/dist/context/pull.js +46 -0
- package/dist/context/pull.js.map +1 -0
- package/dist/dashboard-health.d.ts +20 -0
- package/dist/dashboard-health.d.ts.map +1 -0
- package/dist/dashboard-health.js +24 -0
- package/dist/dashboard-health.js.map +1 -0
- package/dist/eval-provider.d.ts +30 -0
- package/dist/eval-provider.d.ts.map +1 -0
- package/dist/eval-provider.js +359 -0
- package/dist/eval-provider.js.map +1 -0
- package/dist/eval-summary.d.ts +24 -0
- package/dist/eval-summary.d.ts.map +1 -0
- package/dist/eval-summary.js +30 -0
- package/dist/eval-summary.js.map +1 -0
- package/dist/feedback/extract.d.ts +6 -0
- package/dist/feedback/extract.d.ts.map +1 -0
- package/dist/feedback/extract.js +580 -0
- package/dist/feedback/extract.js.map +1 -0
- package/dist/http-retry.d.ts +23 -0
- package/dist/http-retry.d.ts.map +1 -0
- package/dist/http-retry.js +54 -0
- package/dist/http-retry.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +70 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +121 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/scope.d.ts +30 -0
- package/dist/mcp/scope.d.ts.map +1 -0
- package/dist/mcp/scope.js +64 -0
- package/dist/mcp/scope.js.map +1 -0
- package/dist/mcp/server.d.ts +57 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +427 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/write-items.d.ts +34 -0
- package/dist/mcp/write-items.d.ts.map +1 -0
- package/dist/mcp/write-items.js +59 -0
- package/dist/mcp/write-items.js.map +1 -0
- package/dist/rules/deletions-client.d.ts +16 -0
- package/dist/rules/deletions-client.d.ts.map +1 -0
- package/dist/rules/deletions-client.js +40 -0
- package/dist/rules/deletions-client.js.map +1 -0
- package/dist/rules/diff.d.ts +19 -0
- package/dist/rules/diff.d.ts.map +1 -0
- package/dist/rules/diff.js +36 -0
- package/dist/rules/diff.js.map +1 -0
- package/dist/rules/discover.d.ts +81 -0
- package/dist/rules/discover.d.ts.map +1 -0
- package/dist/rules/discover.js +307 -0
- package/dist/rules/discover.js.map +1 -0
- package/dist/rules/file-origin.d.ts +16 -0
- package/dist/rules/file-origin.d.ts.map +1 -0
- package/dist/rules/file-origin.js +31 -0
- package/dist/rules/file-origin.js.map +1 -0
- package/dist/rules/global-flag.d.ts +12 -0
- package/dist/rules/global-flag.d.ts.map +1 -0
- package/dist/rules/global-flag.js +15 -0
- package/dist/rules/global-flag.js.map +1 -0
- package/dist/rules/import-client.d.ts +37 -0
- package/dist/rules/import-client.d.ts.map +1 -0
- package/dist/rules/import-client.js +98 -0
- package/dist/rules/import-client.js.map +1 -0
- package/dist/rules/init-pull.d.ts +34 -0
- package/dist/rules/init-pull.d.ts.map +1 -0
- package/dist/rules/init-pull.js +43 -0
- package/dist/rules/init-pull.js.map +1 -0
- package/dist/rules/member-files-client.d.ts +17 -0
- package/dist/rules/member-files-client.d.ts.map +1 -0
- package/dist/rules/member-files-client.js +29 -0
- package/dist/rules/member-files-client.js.map +1 -0
- package/dist/rules/path-contains.d.ts +9 -0
- package/dist/rules/path-contains.d.ts.map +1 -0
- package/dist/rules/path-contains.js +17 -0
- package/dist/rules/path-contains.js.map +1 -0
- package/dist/rules/payload.d.ts +13 -0
- package/dist/rules/payload.d.ts.map +1 -0
- package/dist/rules/payload.js +35 -0
- package/dist/rules/payload.js.map +1 -0
- package/dist/rules/pull-bundle.d.ts +13 -0
- package/dist/rules/pull-bundle.d.ts.map +1 -0
- package/dist/rules/pull-bundle.js +32 -0
- package/dist/rules/pull-bundle.js.map +1 -0
- package/dist/rules/watch.d.ts +121 -0
- package/dist/rules/watch.d.ts.map +1 -0
- package/dist/rules/watch.js +457 -0
- package/dist/rules/watch.js.map +1 -0
- package/dist/skill-template.d.ts +19 -0
- package/dist/skill-template.d.ts.map +1 -0
- package/dist/skill-template.js +174 -0
- package/dist/skill-template.js.map +1 -0
- package/dist/sync-batches.d.ts +37 -0
- package/dist/sync-batches.d.ts.map +1 -0
- package/dist/sync-batches.js +67 -0
- package/dist/sync-batches.js.map +1 -0
- package/dist/sync-client.d.ts +22 -0
- package/dist/sync-client.d.ts.map +1 -0
- package/dist/sync-client.js +38 -0
- package/dist/sync-client.js.map +1 -0
- package/dist/sync-response.d.ts +23 -0
- package/dist/sync-response.d.ts.map +1 -0
- package/dist/sync-response.js +22 -0
- package/dist/sync-response.js.map +1 -0
- package/dist/token-verify.d.ts +14 -0
- package/dist/token-verify.d.ts.map +1 -0
- package/dist/token-verify.js +30 -0
- package/dist/token-verify.js.map +1 -0
- package/dist/usage/extract.d.ts +31 -0
- package/dist/usage/extract.d.ts.map +1 -0
- package/dist/usage/extract.js +200 -0
- package/dist/usage/extract.js.map +1 -0
- package/dist/usage/providers.d.ts +8 -0
- package/dist/usage/providers.d.ts.map +1 -0
- package/dist/usage/providers.js +23 -0
- package/dist/usage/providers.js.map +1 -0
- package/dist/verdict-queue.d.ts +50 -0
- package/dist/verdict-queue.d.ts.map +1 -0
- package/dist/verdict-queue.js +131 -0
- package/dist/verdict-queue.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export const SKILL_MD = `---
|
|
2
|
+
name: auden
|
|
3
|
+
description: >-
|
|
4
|
+
Invoke when the user asks about Auden, evaluation results, or what happened
|
|
5
|
+
in the last session. Surfaces the current guide cache, lets the user inspect
|
|
6
|
+
or manually record verdicts, and shows pending guide suggestions. Do NOT call
|
|
7
|
+
this automatically before or after actions — Auden evaluates sessions
|
|
8
|
+
post-hoc; guides already flow into the agent's context via AGENTS.md and
|
|
9
|
+
CLAUDE.md.
|
|
10
|
+
user-invocable: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Auden
|
|
14
|
+
|
|
15
|
+
Auden is an on-device agent analytics layer. After each Claude Code session the Stop hook runs \`auden eval\`, which scores the session against your active guides and prints an alignment summary. Evaluation is post-hoc and happens once per session — not per action.
|
|
16
|
+
|
|
17
|
+
## When To Invoke This Skill
|
|
18
|
+
|
|
19
|
+
Only when the user explicitly asks. Examples:
|
|
20
|
+
|
|
21
|
+
- "What did Auden say about the last session?"
|
|
22
|
+
- "Show me the active guides"
|
|
23
|
+
- "Did the agent follow the guides?"
|
|
24
|
+
- "Run auden suggest"
|
|
25
|
+
|
|
26
|
+
Do NOT call \`auden\` commands during normal task execution. Guides already reach you through \`AGENTS.md\` / \`CLAUDE.md\` / \`.cursorrules\` — Auden's job is to evaluate what happened afterwards, not to gate each action.
|
|
27
|
+
|
|
28
|
+
## Commands
|
|
29
|
+
|
|
30
|
+
### \`auden guides active\`
|
|
31
|
+
|
|
32
|
+
Lists all currently enabled guides for this project, read from the local cache.
|
|
33
|
+
|
|
34
|
+
\`\`\`bash
|
|
35
|
+
auden guides active
|
|
36
|
+
\`\`\`
|
|
37
|
+
|
|
38
|
+
### \`auden guides search <query>\`
|
|
39
|
+
|
|
40
|
+
Searches active guides by keyword.
|
|
41
|
+
|
|
42
|
+
\`\`\`bash
|
|
43
|
+
auden guides search "TypeScript"
|
|
44
|
+
auden guides search "testing"
|
|
45
|
+
\`\`\`
|
|
46
|
+
|
|
47
|
+
### \`auden verdict record\`
|
|
48
|
+
|
|
49
|
+
Manually records an alignment verdict and queues it for the next \`auden sync\`. Use when the user wants to log a specific outcome. The Stop hook (\`auden eval\`) evaluates sessions but does not enqueue verdicts automatically.
|
|
50
|
+
|
|
51
|
+
\`\`\`bash
|
|
52
|
+
auden verdict record --verdict aligned --summary "ran tests before committing"
|
|
53
|
+
auden verdict record --verdict misaligned --summary "used var instead of const"
|
|
54
|
+
auden verdict record --verdict unguided --summary "added a new pattern with no existing rule"
|
|
55
|
+
\`\`\`
|
|
56
|
+
|
|
57
|
+
**Verdict values:** \`aligned\` | \`misaligned\` | \`unguided\`
|
|
58
|
+
|
|
59
|
+
### \`auden suggest\`
|
|
60
|
+
|
|
61
|
+
Surfaces guide suggestions extracted from recent session history.
|
|
62
|
+
|
|
63
|
+
\`\`\`bash
|
|
64
|
+
auden suggest
|
|
65
|
+
\`\`\`
|
|
66
|
+
|
|
67
|
+
### \`auden sync\`
|
|
68
|
+
|
|
69
|
+
Pushes queued verdicts and extracted guide/skill suggestions to the dashboard, and pulls the latest guide bundle. Verdicts recorded with \`auden verdict record\` are transmitted on the next \`auden sync\`.
|
|
70
|
+
|
|
71
|
+
\`\`\`bash
|
|
72
|
+
auden sync
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
## Notes
|
|
76
|
+
|
|
77
|
+
- Guides are cached in \`~/.auden/guides.json\` after \`auden sync\`. \`guides active\` and \`guides search\` read from cache — no network requests.
|
|
78
|
+
- Verdicts are queued locally in \`~/.auden/queue/\` and sent to the dashboard on the next \`auden sync\` (queue files are deleted after a successful send).
|
|
79
|
+
- The Stop hook (\`auden eval\`) is installed by \`auden init\` and runs once when the Claude Code session ends.
|
|
80
|
+
`;
|
|
81
|
+
export const AUDEN_CONTEXT_SKILL_MD = `---
|
|
82
|
+
name: auden-context
|
|
83
|
+
description: >-
|
|
84
|
+
Use when the user refers to their notes, context, inbox, or bundles saved in
|
|
85
|
+
Auden — e.g. "pull my notes from Auden", "what's in my inbox", "save this to
|
|
86
|
+
my context", "sync this back". Reads and writes the Auden context layer over
|
|
87
|
+
the Auden MCP server so context follows the user across every repo and agent.
|
|
88
|
+
user-invocable: true
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
# Auden Context
|
|
92
|
+
|
|
93
|
+
Auden's context layer is a portable store of the user's canonical documents,
|
|
94
|
+
notes, and reference material. It lives on the Auden dashboard and is reachable
|
|
95
|
+
from any repo through the **Auden MCP server** (\`auden mcp\`, configured once per
|
|
96
|
+
agent). Items are *canonical, not copies*: a document can belong to many bundles,
|
|
97
|
+
and editing it once propagates the change everywhere it is a member. Plain
|
|
98
|
+
Markdown/text is the source of truth.
|
|
99
|
+
|
|
100
|
+
Two surfaces sit on top of it:
|
|
101
|
+
|
|
102
|
+
- **Bundles** — named collections (\`notes\`, \`travel-log\`, …) you pull scoped
|
|
103
|
+
context from and push canonical results into.
|
|
104
|
+
- **Inbox** — a reserved bundle the user captures raw notes into (from the phone,
|
|
105
|
+
the app, or a share sheet). Agents pull recent inbox items, transform them, and
|
|
106
|
+
archive what they consumed.
|
|
107
|
+
|
|
108
|
+
## When To Use
|
|
109
|
+
|
|
110
|
+
Invoke when the user references their own saved context, for example:
|
|
111
|
+
|
|
112
|
+
- "Pull my notes from the last day and summarize them."
|
|
113
|
+
- "What context do I have on <topic>?" / "Search my Auden bundles for <x>."
|
|
114
|
+
- "Save this document to my \`notes\` bundle." / "Sync this back to Auden."
|
|
115
|
+
- "Clear my inbox once you've used it."
|
|
116
|
+
|
|
117
|
+
Do NOT use it for guide/verdict inspection — that is the \`auden\` skill. This
|
|
118
|
+
skill is about reading and writing *context*, not evaluating sessions.
|
|
119
|
+
|
|
120
|
+
## Tools (Auden MCP server)
|
|
121
|
+
|
|
122
|
+
If these tools are missing, the Auden MCP server is not configured. Tell the user
|
|
123
|
+
to run \`auden mcp\` and add it to their agent's MCP config (\`.mcp.json\` / Claude
|
|
124
|
+
Code / Cursor). \`auden mcp --read-only\` disables the write tools; \`auden mcp
|
|
125
|
+
--bundles a,b\` restricts which bundles are visible.
|
|
126
|
+
|
|
127
|
+
| Tool | Input | Use |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| \`list_bundles\` | \`{}\` | Discover which bundles exist before pulling or pushing. |
|
|
130
|
+
| \`pull_context\` | \`{ bundle, query?, types?, limit?, writeToDir? }\` | Pull *scoped* items from a bundle. Filter with \`types\` (\`document\`/\`reference\`/\`asset\`/\`guide\`), a \`query\` substring, and \`limit\`. Pass \`writeToDir\` to also write each item to disk. |
|
|
131
|
+
| \`push_context\` | \`{ bundle, name, content, contentType?, itemId?, origin?, sourceItemIds? }\` | Push a canonical item. Omit \`itemId\` to create; pass \`itemId\` to update in place (propagates to every bundle it belongs to). \`contentType\` defaults to \`document\`. When the item was produced from other context items, cite their ids as \`sourceItemIds\`. |
|
|
132
|
+
| \`list_inbox\` | \`{ since?, types? }\` | List unarchived inbox items. \`since\` takes an ISO timestamp or a relative window (\`"24h"\`, \`"7d"\`, \`"30m"\`). |
|
|
133
|
+
| \`pull_inbox\` | \`{ since?, types?, writeToDir? }\` | Like \`list_inbox\` but also supports \`writeToDir\` — the round-trip entry point. |
|
|
134
|
+
| \`archive_inbox\` | \`{ ids }\` | Archive inbox items once consumed so they drop out of future pulls (reversible on the dashboard). |
|
|
135
|
+
|
|
136
|
+
## How To Use It Well
|
|
137
|
+
|
|
138
|
+
- **Pull scoped, not everything.** Reach for \`query\`/\`types\`/\`limit\` so you only
|
|
139
|
+
load what the task needs — the context layer can be large.
|
|
140
|
+
- **Pushes are canonical and cross-repo.** A pushed document is visible from every
|
|
141
|
+
other repo, so name it clearly and target the right bundle. When refining
|
|
142
|
+
something you pulled, pass its \`itemId\` to \`push_context\` to update it in place
|
|
143
|
+
rather than creating a duplicate.
|
|
144
|
+
- **Close the loop on the inbox.** After you turn inbox items into a saved
|
|
145
|
+
document, call \`archive_inbox\` with the ids you consumed so the user's inbox
|
|
146
|
+
reflects that they were processed.
|
|
147
|
+
- **Cite your sources when transforming.** When a pushed document was produced
|
|
148
|
+
from other context items (inbox captures, bundle items), pass their ids as
|
|
149
|
+
\`sourceItemIds\` on \`push_context\`. The citation is optional provenance; if
|
|
150
|
+
one of the user's own guides covers the transform (its trigger matches, and
|
|
151
|
+
it carries eval criteria), Auden grades the round-trip against *that guide's*
|
|
152
|
+
criteria and the verdict lands in the user's feed. Auden has no built-in
|
|
153
|
+
quality bar — the user's guidance is the standard. Report the verdict from
|
|
154
|
+
the response's \`transform\` field when present.
|
|
155
|
+
- **Preserve the user's facts.** These are the user's own notes — never drop or
|
|
156
|
+
invent detail when you restructure them.
|
|
157
|
+
`;
|
|
158
|
+
/**
|
|
159
|
+
* Skills bundled into a repo by \`auden init\` (written under .claude/skills/<name>/SKILL.md).
|
|
160
|
+
* The \`auden\` skill covers evaluation/verdict inspection; \`auden-context\` covers
|
|
161
|
+
* the context layer over the Auden MCP server.
|
|
162
|
+
*
|
|
163
|
+
* Deliberately mechanics-only: Auden ships the mechanics (pull/push/inbox/
|
|
164
|
+
* grading), users bring the use cases — a concrete transform skill (e.g. notes
|
|
165
|
+
* cleanup) plus the guide with eval criteria that grades it is *user* content.
|
|
166
|
+
* A copy-paste example lives in docs/examples/notes-cleanup-skill.md; a user
|
|
167
|
+
* skill dropped into .claude/skills/ is discovered and graded like anything
|
|
168
|
+
* else they author (L3).
|
|
169
|
+
*/
|
|
170
|
+
export const BUNDLED_SKILLS = [
|
|
171
|
+
{ name: 'auden', content: SKILL_MD },
|
|
172
|
+
{ name: 'auden-context', content: AUDEN_CONTEXT_SKILL_MD },
|
|
173
|
+
];
|
|
174
|
+
//# sourceMappingURL=skill-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-template.js","sourceRoot":"","sources":["../src/skill-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+EvB,CAAA;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4ErC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,cAAc,GAAqD;IAC9E,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;IACpC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,sBAAsB,EAAE;CAC3D,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DashboardFeedbackCandidate, DashboardGuideSuggestion, DashboardRunUsage, DashboardSkillUsage, DashboardSyncAction, DashboardSyncRequest } from '@auden.to/protocol';
|
|
2
|
+
export type SyncBatchInput = {
|
|
3
|
+
actions: DashboardSyncAction[];
|
|
4
|
+
filePaths: string[];
|
|
5
|
+
guideSuggestions: DashboardGuideSuggestion[];
|
|
6
|
+
feedbackCandidates: DashboardFeedbackCandidate[];
|
|
7
|
+
runUsage: DashboardRunUsage[];
|
|
8
|
+
skillUsage: DashboardSkillUsage[];
|
|
9
|
+
};
|
|
10
|
+
export type SyncBatch = {
|
|
11
|
+
payload: DashboardSyncRequest;
|
|
12
|
+
/** Queue file paths whose actions are included in this batch's payload. */
|
|
13
|
+
filePaths: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Splits queued sync data into `POST /api/sync` request payloads that each
|
|
17
|
+
* stay under the server's `MAX_SYNC_ACTIONS_BATCH` / `MAX_SYNC_AUX_BATCH`
|
|
18
|
+
* caps. `actions` and `filePaths` are chunked in lockstep (same indices,
|
|
19
|
+
* same chunk size) since `readVerdictQueue` emits one queue file per action —
|
|
20
|
+
* this lets the caller delete only a batch's own files once that batch's
|
|
21
|
+
* request succeeds. Returns a single empty-arrays batch when there is
|
|
22
|
+
* nothing to send, so a caller can always iterate at least once.
|
|
23
|
+
*
|
|
24
|
+
* `runUsage`/`skillUsage` entries are keyed by session, not by action, and the
|
|
25
|
+
* server only creates a session's `run` row (`materializeRuns`) once that
|
|
26
|
+
* session's actions have actually been synced — so they are attached only to
|
|
27
|
+
* batches *after* every action batch, never at the same index. Aligning them
|
|
28
|
+
* index-for-index with the (differently-sized, differently-ordered) action
|
|
29
|
+
* chunks would let a usage entry for a session whose actions land in a later
|
|
30
|
+
* batch reach `/api/sync` before its run exists, silently dropping it as
|
|
31
|
+
* `no_matching_run` on a sync large enough to span multiple action batches.
|
|
32
|
+
* Batches are posted sequentially and awaited (`commands/sync.ts`), so by the
|
|
33
|
+
* time the trailing usage batches send, every prior batch's `materializeRuns`
|
|
34
|
+
* has already committed.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildSyncBatches(input: SyncBatchInput): SyncBatch[];
|
|
37
|
+
//# sourceMappingURL=sync-batches.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-batches.d.ts","sourceRoot":"","sources":["../src/sync-batches.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAE3B,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAA;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,gBAAgB,EAAE,wBAAwB,EAAE,CAAA;IAC5C,kBAAkB,EAAE,0BAA0B,EAAE,CAAA;IAChD,QAAQ,EAAE,iBAAiB,EAAE,CAAA;IAC7B,UAAU,EAAE,mBAAmB,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,oBAAoB,CAAA;IAC7B,2EAA2E;IAC3E,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,EAAE,CA+DnE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { MAX_SYNC_ACTIONS_BATCH, MAX_SYNC_AUX_BATCH } from '@auden.to/protocol';
|
|
2
|
+
import { chunkArray } from './chunk.js';
|
|
3
|
+
/**
|
|
4
|
+
* Splits queued sync data into `POST /api/sync` request payloads that each
|
|
5
|
+
* stay under the server's `MAX_SYNC_ACTIONS_BATCH` / `MAX_SYNC_AUX_BATCH`
|
|
6
|
+
* caps. `actions` and `filePaths` are chunked in lockstep (same indices,
|
|
7
|
+
* same chunk size) since `readVerdictQueue` emits one queue file per action —
|
|
8
|
+
* this lets the caller delete only a batch's own files once that batch's
|
|
9
|
+
* request succeeds. Returns a single empty-arrays batch when there is
|
|
10
|
+
* nothing to send, so a caller can always iterate at least once.
|
|
11
|
+
*
|
|
12
|
+
* `runUsage`/`skillUsage` entries are keyed by session, not by action, and the
|
|
13
|
+
* server only creates a session's `run` row (`materializeRuns`) once that
|
|
14
|
+
* session's actions have actually been synced — so they are attached only to
|
|
15
|
+
* batches *after* every action batch, never at the same index. Aligning them
|
|
16
|
+
* index-for-index with the (differently-sized, differently-ordered) action
|
|
17
|
+
* chunks would let a usage entry for a session whose actions land in a later
|
|
18
|
+
* batch reach `/api/sync` before its run exists, silently dropping it as
|
|
19
|
+
* `no_matching_run` on a sync large enough to span multiple action batches.
|
|
20
|
+
* Batches are posted sequentially and awaited (`commands/sync.ts`), so by the
|
|
21
|
+
* time the trailing usage batches send, every prior batch's `materializeRuns`
|
|
22
|
+
* has already committed.
|
|
23
|
+
*/
|
|
24
|
+
export function buildSyncBatches(input) {
|
|
25
|
+
if (input.actions.length !== input.filePaths.length) {
|
|
26
|
+
throw new Error(`buildSyncBatches: actions.length (${input.actions.length}) and filePaths.length (${input.filePaths.length}) must be equal`);
|
|
27
|
+
}
|
|
28
|
+
const actionChunks = chunkArray(input.actions, MAX_SYNC_ACTIONS_BATCH);
|
|
29
|
+
const filePathChunks = chunkArray(input.filePaths, MAX_SYNC_ACTIONS_BATCH);
|
|
30
|
+
const guideSuggestionChunks = chunkArray(input.guideSuggestions, MAX_SYNC_AUX_BATCH);
|
|
31
|
+
const feedbackCandidateChunks = chunkArray(input.feedbackCandidates, MAX_SYNC_AUX_BATCH);
|
|
32
|
+
const primaryBatchCount = Math.max(actionChunks.length, filePathChunks.length, guideSuggestionChunks.length, feedbackCandidateChunks.length) || 1;
|
|
33
|
+
const primaryBatches = Array.from({ length: primaryBatchCount }, (_, i) => ({
|
|
34
|
+
payload: {
|
|
35
|
+
actions: actionChunks[i] ?? [],
|
|
36
|
+
guideSuggestions: guideSuggestionChunks[i] ?? [],
|
|
37
|
+
feedbackCandidates: feedbackCandidateChunks[i] ?? [],
|
|
38
|
+
runUsage: [],
|
|
39
|
+
skillUsage: [],
|
|
40
|
+
},
|
|
41
|
+
filePaths: filePathChunks[i] ?? [],
|
|
42
|
+
}));
|
|
43
|
+
const runUsageChunks = chunkArray(input.runUsage, MAX_SYNC_AUX_BATCH);
|
|
44
|
+
const skillUsageChunks = chunkArray(input.skillUsage, MAX_SYNC_AUX_BATCH);
|
|
45
|
+
const usageBatchCount = Math.max(runUsageChunks.length, skillUsageChunks.length);
|
|
46
|
+
if (usageBatchCount === 0) {
|
|
47
|
+
return primaryBatches;
|
|
48
|
+
}
|
|
49
|
+
// The first usage chunk rides the last primary batch (no extra request when
|
|
50
|
+
// usage fits in one aux-sized chunk); any further chunks become trailing
|
|
51
|
+
// usage-only batches.
|
|
52
|
+
const lastPrimary = primaryBatches[primaryBatches.length - 1];
|
|
53
|
+
lastPrimary.payload.runUsage = runUsageChunks[0] ?? [];
|
|
54
|
+
lastPrimary.payload.skillUsage = skillUsageChunks[0] ?? [];
|
|
55
|
+
const trailingUsageBatches = Array.from({ length: usageBatchCount - 1 }, (_, i) => ({
|
|
56
|
+
payload: {
|
|
57
|
+
actions: [],
|
|
58
|
+
guideSuggestions: [],
|
|
59
|
+
feedbackCandidates: [],
|
|
60
|
+
runUsage: runUsageChunks[i + 1] ?? [],
|
|
61
|
+
skillUsage: skillUsageChunks[i + 1] ?? [],
|
|
62
|
+
},
|
|
63
|
+
filePaths: [],
|
|
64
|
+
}));
|
|
65
|
+
return [...primaryBatches, ...trailingUsageBatches];
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=sync-batches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-batches.js","sourceRoot":"","sources":["../src/sync-batches.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { RetryOptions } from './http-retry.js';
|
|
2
|
+
import type { DashboardSyncRequest } from '@auden.to/protocol';
|
|
3
|
+
export type PostSyncBatchOptions = {
|
|
4
|
+
dashboardUrl: string;
|
|
5
|
+
token: string;
|
|
6
|
+
payload: DashboardSyncRequest;
|
|
7
|
+
/** Override fetch for tests. Defaults to globalThis.fetch. */
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
retryOptions?: RetryOptions;
|
|
10
|
+
};
|
|
11
|
+
export type PostSyncBatchResult = {
|
|
12
|
+
synced: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* POST one `/api/sync` batch, retrying transport failures and 5xx responses
|
|
16
|
+
* with backoff (never a 4xx — a bad request or rejected token won't be fixed
|
|
17
|
+
* by retrying). Throws on a non-2xx response or a body that doesn't match
|
|
18
|
+
* the `{ synced }` contract, so the caller's existing behaviour of keeping
|
|
19
|
+
* this batch's queue files on failure is unchanged.
|
|
20
|
+
*/
|
|
21
|
+
export declare function postSyncBatch(options: PostSyncBatchOptions): Promise<PostSyncBatchResult>;
|
|
22
|
+
//# sourceMappingURL=sync-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAE9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,oBAAoB,CAAA;IAC7B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAMD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAmC9B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fetchWithRetry } from './http-retry.js';
|
|
2
|
+
import { parseSyncResponse } from './sync-response.js';
|
|
3
|
+
function trimTrailingSlashes(url) {
|
|
4
|
+
return url.replace(/\/+$/, '');
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* POST one `/api/sync` batch, retrying transport failures and 5xx responses
|
|
8
|
+
* with backoff (never a 4xx — a bad request or rejected token won't be fixed
|
|
9
|
+
* by retrying). Throws on a non-2xx response or a body that doesn't match
|
|
10
|
+
* the `{ synced }` contract, so the caller's existing behaviour of keeping
|
|
11
|
+
* this batch's queue files on failure is unchanged.
|
|
12
|
+
*/
|
|
13
|
+
export async function postSyncBatch(options) {
|
|
14
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
15
|
+
const url = `${trimTrailingSlashes(options.dashboardUrl)}/api/sync`;
|
|
16
|
+
const response = await fetchWithRetry(fetchImpl, url, {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
headers: {
|
|
19
|
+
Authorization: `Bearer ${options.token}`,
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify(options.payload),
|
|
23
|
+
}, options.retryOptions);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Sync failed with ${response.status}: ${await response.text()}`);
|
|
26
|
+
}
|
|
27
|
+
const rawBody = await response.json().catch(() => null);
|
|
28
|
+
const { synced, valid } = parseSyncResponse(rawBody);
|
|
29
|
+
if (!valid) {
|
|
30
|
+
// A 200 whose body isn't the `{ synced }` contract means we're not
|
|
31
|
+
// talking to an Auden /api/sync (e.g. a wrong --dashboard-url hitting a
|
|
32
|
+
// proxy that returns HTML). Treat it as a failure so this batch's queue
|
|
33
|
+
// files are kept and the token isn't persisted.
|
|
34
|
+
throw new Error(`Sync to ${url} returned ${response.status} but the response did not match the expected { synced } shape — keeping queued verdicts. Check that --dashboard-url points at an Auden server.`);
|
|
35
|
+
}
|
|
36
|
+
return { synced };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=sync-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-client.js","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAkBtD,SAAS,mBAAmB,CAAC,GAAW;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA6B;IAE7B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAA;IAC5C,MAAM,GAAG,GAAG,GAAG,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAA;IAEnE,MAAM,QAAQ,GAAG,MAAM,cAAc,CACnC,SAAS,EACT,GAAG,EACH;QACE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;YACxC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;KACtC,EACD,OAAO,CAAC,YAAY,CACrB,CAAA;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IACvD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,mEAAmE;QACnE,wEAAwE;QACxE,wEAAwE;QACxE,gDAAgD;QAChD,MAAM,IAAI,KAAK,CACb,WAAW,GAAG,aAAa,QAAQ,CAAC,MAAM,gJAAgJ,CAC3L,CAAA;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAA;AACnB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
/**
|
|
3
|
+
* Shape of a successful `POST /api/sync` response. The server returns the
|
|
4
|
+
* number of rows it persisted for the batch (`{ synced }`).
|
|
5
|
+
*/
|
|
6
|
+
export declare const SyncResponseSchema: v.ObjectSchema<{
|
|
7
|
+
readonly synced: v.NumberSchema<undefined>;
|
|
8
|
+
}, undefined>;
|
|
9
|
+
export type SyncResponse = v.InferOutput<typeof SyncResponseSchema>;
|
|
10
|
+
export type ParsedSyncResponse = {
|
|
11
|
+
/** Number of items the server reported as synced (0 when the shape drifted). */
|
|
12
|
+
synced: number;
|
|
13
|
+
/** False when the body did not match the expected contract. */
|
|
14
|
+
valid: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Validate a `/api/sync` response body without throwing. A 200 response means
|
|
18
|
+
* the items were already persisted server-side, so a drifted shape must not
|
|
19
|
+
* fail the sync — it is surfaced via `valid: false` and counted as 0 so the
|
|
20
|
+
* caller can warn while still treating the push as accepted.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseSyncResponse(raw: unknown): ParsedSyncResponse;
|
|
23
|
+
//# sourceMappingURL=sync-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-response.d.ts","sourceRoot":"","sources":["../src/sync-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;aAE7B,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEnE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAMlE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
/**
|
|
3
|
+
* Shape of a successful `POST /api/sync` response. The server returns the
|
|
4
|
+
* number of rows it persisted for the batch (`{ synced }`).
|
|
5
|
+
*/
|
|
6
|
+
export const SyncResponseSchema = v.object({
|
|
7
|
+
synced: v.number(),
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* Validate a `/api/sync` response body without throwing. A 200 response means
|
|
11
|
+
* the items were already persisted server-side, so a drifted shape must not
|
|
12
|
+
* fail the sync — it is surfaced via `valid: false` and counted as 0 so the
|
|
13
|
+
* caller can warn while still treating the push as accepted.
|
|
14
|
+
*/
|
|
15
|
+
export function parseSyncResponse(raw) {
|
|
16
|
+
const result = v.safeParse(SyncResponseSchema, raw);
|
|
17
|
+
if (result.success) {
|
|
18
|
+
return { synced: result.output.synced, valid: true };
|
|
19
|
+
}
|
|
20
|
+
return { synced: 0, valid: false };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=sync-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-response.js","sourceRoot":"","sources":["../src/sync-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC,CAAA;AAWF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IACnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACtD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AACpC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type TokenVerification = 'ok' | 'rejected' | 'unreachable';
|
|
2
|
+
/**
|
|
3
|
+
* Probe the dashboard with a bearer token to classify it before storing.
|
|
4
|
+
* Hits the same endpoint `auden sync` pulls guides from, with a short
|
|
5
|
+
* timeout so `auden init --token` stays fast even when the host is down.
|
|
6
|
+
*
|
|
7
|
+
* - 'ok' — the server accepted the token
|
|
8
|
+
* - 'rejected' — the server answered 401/403: the token itself is bad
|
|
9
|
+
* - 'unreachable' — network failure, timeout, or a non-auth error (5xx);
|
|
10
|
+
* says nothing about the token, so callers should store
|
|
11
|
+
* it and let the next `auden sync` settle the question
|
|
12
|
+
*/
|
|
13
|
+
export declare function verifyDashboardToken(dashboardUrl: string, token: string, fetchFn?: typeof fetch): Promise<TokenVerification>;
|
|
14
|
+
//# sourceMappingURL=token-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-verify.d.ts","sourceRoot":"","sources":["../src/token-verify.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,UAAU,GAAG,aAAa,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAc5B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probe the dashboard with a bearer token to classify it before storing.
|
|
3
|
+
* Hits the same endpoint `auden sync` pulls guides from, with a short
|
|
4
|
+
* timeout so `auden init --token` stays fast even when the host is down.
|
|
5
|
+
*
|
|
6
|
+
* - 'ok' — the server accepted the token
|
|
7
|
+
* - 'rejected' — the server answered 401/403: the token itself is bad
|
|
8
|
+
* - 'unreachable' — network failure, timeout, or a non-auth error (5xx);
|
|
9
|
+
* says nothing about the token, so callers should store
|
|
10
|
+
* it and let the next `auden sync` settle the question
|
|
11
|
+
*/
|
|
12
|
+
export async function verifyDashboardToken(dashboardUrl, token, fetchFn = fetch) {
|
|
13
|
+
const url = `${dashboardUrl.replace(/\/+$/, '')}/api/v1/guides`;
|
|
14
|
+
let response;
|
|
15
|
+
try {
|
|
16
|
+
response = await fetchFn(url, {
|
|
17
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
18
|
+
signal: AbortSignal.timeout(5000),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return 'unreachable';
|
|
23
|
+
}
|
|
24
|
+
if (response.ok)
|
|
25
|
+
return 'ok';
|
|
26
|
+
if (response.status === 401 || response.status === 403)
|
|
27
|
+
return 'rejected';
|
|
28
|
+
return 'unreachable';
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=token-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-verify.js","sourceRoot":"","sources":["../src/token-verify.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,KAAa,EACb,UAAwB,KAAK;IAE7B,MAAM,GAAG,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAA;IAC/D,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;YAC5B,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;YAC7C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAAA;IACtB,CAAC;IACD,IAAI,QAAQ,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAC5B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,UAAU,CAAA;IACzE,OAAO,aAAa,CAAA;AACtB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SkillUsageEntry, TokenUsage } from '@auden.to/protocol';
|
|
2
|
+
export type SessionUsage = {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
usage: TokenUsage[];
|
|
5
|
+
};
|
|
6
|
+
export type SessionSkillUsage = {
|
|
7
|
+
sessionId: string;
|
|
8
|
+
usage: SkillUsageEntry[];
|
|
9
|
+
};
|
|
10
|
+
export type ExtractedRunUsage = {
|
|
11
|
+
runUsage: SessionUsage[];
|
|
12
|
+
skillUsage: SessionSkillUsage[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Extracts per-session, per-model token usage from Claude Code JSONL
|
|
16
|
+
* transcripts (docs/plans/token-cost-tracking-plan.md §5.1), plus per-skill
|
|
17
|
+
* Tier-1 "load overhead" usage (§13.3): when an assistant message requests a
|
|
18
|
+
* `Skill` tool or reads a `SKILL.md`, the *next* assistant message's usage is
|
|
19
|
+
* the first-load cost of that skill (v1 approximation — see §13.3's caching
|
|
20
|
+
* nuance). Reads only `usage`/`model`/`sessionId` and tool_use `name`/`input`
|
|
21
|
+
* off assistant messages — never message text.
|
|
22
|
+
*
|
|
23
|
+
* Each message carries its own (non-cumulative) usage, so we sum every
|
|
24
|
+
* assistant message's usage per (session, model). Messages are deduped by
|
|
25
|
+
* their id so re-reading a transcript that grew since the last sync does not
|
|
26
|
+
* double-count lines already summed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractRunUsage(options?: {
|
|
29
|
+
transcriptsDir?: string;
|
|
30
|
+
}): Promise<ExtractedRunUsage>;
|
|
31
|
+
//# sourceMappingURL=extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/usage/extract.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAErE,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,UAAU,EAAE,iBAAiB,EAAE,CAAA;CAChC,CAAA;AAiGD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,OAAO,CAAC,EAAE;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkI7B"}
|