sverklo 0.28.3 → 0.29.0
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 +5 -3
- package/dist/bin/sverklo.js +128 -0
- package/dist/bin/sverklo.js.map +1 -1
- package/dist/src/indexer/parser-tree-sitter.js +0 -1
- package/dist/src/indexer/parser-tree-sitter.js.map +1 -1
- package/dist/src/init-global.js +25 -24
- package/dist/src/init-global.js.map +1 -1
- package/dist/src/marketing/campaign-cycle.d.ts +13 -0
- package/dist/src/marketing/campaign-cycle.js +107 -0
- package/dist/src/marketing/campaign-cycle.js.map +1 -0
- package/dist/src/marketing/content-quality.d.ts +11 -0
- package/dist/src/marketing/content-quality.js +51 -0
- package/dist/src/marketing/content-quality.js.map +1 -0
- package/dist/src/marketing/content-seeding.d.ts +2 -0
- package/dist/src/marketing/content-seeding.js +105 -0
- package/dist/src/marketing/content-seeding.js.map +1 -0
- package/dist/src/marketing/decisions.d.ts +10 -0
- package/dist/src/marketing/decisions.js +142 -0
- package/dist/src/marketing/decisions.js.map +1 -0
- package/dist/src/marketing/index.d.ts +12 -0
- package/dist/src/marketing/index.js +13 -0
- package/dist/src/marketing/index.js.map +1 -0
- package/dist/src/marketing/models.d.ts +189 -0
- package/dist/src/marketing/models.js +5 -0
- package/dist/src/marketing/models.js.map +1 -0
- package/dist/src/marketing/opportunity-scout.d.ts +8 -0
- package/dist/src/marketing/opportunity-scout.js +73 -0
- package/dist/src/marketing/opportunity-scout.js.map +1 -0
- package/dist/src/marketing/profile-health.d.ts +2 -0
- package/dist/src/marketing/profile-health.js +96 -0
- package/dist/src/marketing/profile-health.js.map +1 -0
- package/dist/src/marketing/report.d.ts +4 -0
- package/dist/src/marketing/report.js +67 -0
- package/dist/src/marketing/report.js.map +1 -0
- package/dist/src/marketing/scoring.d.ts +5 -0
- package/dist/src/marketing/scoring.js +89 -0
- package/dist/src/marketing/scoring.js.map +1 -0
- package/dist/src/marketing/status.d.ts +3 -0
- package/dist/src/marketing/status.js +58 -0
- package/dist/src/marketing/status.js.map +1 -0
- package/dist/src/marketing/storage.d.ts +29 -0
- package/dist/src/marketing/storage.js +99 -0
- package/dist/src/marketing/storage.js.map +1 -0
- package/dist/src/marketing/test-fixtures.d.ts +7 -0
- package/dist/src/marketing/test-fixtures.js +31 -0
- package/dist/src/marketing/test-fixtures.js.map +1 -0
- package/dist/src/marketing/validation.d.ts +9 -0
- package/dist/src/marketing/validation.js +66 -0
- package/dist/src/marketing/validation.js.map +1 -0
- package/dist/src/server/tools/review-diff.js +0 -1
- package/dist/src/server/tools/review-diff.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -22,7 +22,9 @@ sverklo prove
|
|
|
22
22
|
|
|
23
23
|
`sverklo init` writes the MCP config for your agent, appends local instructions to `AGENTS.md` or `CLAUDE.md`, and runs `sverklo doctor` to verify the handshake. `sverklo prove` then shows central files, a real symbol with callers, and the exact prompt to paste into your agent. Your code stays on your machine.
|
|
24
24
|
|
|
25
|
-
Need something shareable? Run `sverklo prove --markdown` to print a GitHub/Discord-ready proof receipt from your repo.
|
|
25
|
+
Need something shareable? Run `sverklo prove --markdown` to print a GitHub/Discord-ready proof receipt from your repo, then [post it in the proof thread](https://github.com/sverklo/sverklo/discussions/79).
|
|
26
|
+
|
|
27
|
+
Need local launch planning for the Sverklo account? `sverklo marketing` runs a local-first Twitter/X agent-team workflow from operator-provided snapshots. It ranks opportunities, drafts seed-content queues, checks profile health, and records human decisions without posting, scraping, replying, liking, reposting, following, or changing the profile.
|
|
26
28
|
|
|
27
29
|
> *"The map is not the territory."* — Alfred Korzybski
|
|
28
30
|
>
|
|
@@ -80,7 +82,7 @@ cd your-project && sverklo init
|
|
|
80
82
|
sverklo prove
|
|
81
83
|
```
|
|
82
84
|
|
|
83
|
-
That's it. `sverklo init` auto-detects your installed AI coding agent (Claude Code, Cursor, Windsurf, Zed), writes the right MCP config, appends instructions to `AGENTS.md` if present (otherwise `CLAUDE.md`), and runs `sverklo doctor` to verify the setup. `sverklo prove` shows the first useful repo-memory proof from your own codebase; `sverklo prove --markdown` makes that proof shareable. Works on macOS, Linux, and Windows. **No API keys. No cloud. Telemetry off by default.**
|
|
85
|
+
That's it. `sverklo init` auto-detects your installed AI coding agent (Claude Code, Cursor, Windsurf, Zed), writes the right MCP config, appends instructions to `AGENTS.md` if present (otherwise `CLAUDE.md`), and runs `sverklo doctor` to verify the setup. `sverklo prove` shows the first useful repo-memory proof from your own codebase; `sverklo prove --markdown` makes that proof shareable in [the public proof thread](https://github.com/sverklo/sverklo/discussions/79). Works on macOS, Linux, and Windows. **No API keys. No cloud. Telemetry off by default.**
|
|
84
86
|
|
|
85
87
|
> The embedding model (`all-MiniLM-L6-v2` ONNX, ~86 MB) is downloaded from HuggingFace on first use into `~/.sverklo/models/` and cached forever — every subsequent run is fully offline.
|
|
86
88
|
|
|
@@ -454,7 +456,7 @@ cd your-project && sverklo init
|
|
|
454
456
|
sverklo prove
|
|
455
457
|
```
|
|
456
458
|
|
|
457
|
-
`sverklo init` auto-detects which AI coding agents you have (Claude Code, Cursor, Windsurf, Zed, Antigravity) and writes the right MCP config files. `sverklo prove` prints central files, a real caller graph, and a prompt to paste into your agent. Add `--markdown` or `--receipt` for a shareable proof artifact. Idempotent — safe to re-run. If sverklo doesn't appear in your agent after restart, run `sverklo doctor`.
|
|
459
|
+
`sverklo init` auto-detects which AI coding agents you have (Claude Code, Cursor, Windsurf, Zed, Antigravity) and writes the right MCP config files. `sverklo prove` prints central files, a real caller graph, and a prompt to paste into your agent. Add `--markdown` or `--receipt` for a shareable proof artifact, then post it in [the proof thread](https://github.com/sverklo/sverklo/discussions/79). Idempotent — safe to re-run. If sverklo doesn't appear in your agent after restart, run `sverklo doctor`.
|
|
458
460
|
|
|
459
461
|
**Per-agent config locations** (`sverklo init` writes these for you):
|
|
460
462
|
- Claude Code: `.mcp.json` at project root + appends to `CLAUDE.md` (or `AGENTS.md` if present)
|
package/dist/bin/sverklo.js
CHANGED
|
@@ -102,6 +102,7 @@ if (command && command !== "--help" && command !== "-h") {
|
|
|
102
102
|
digest: "5-line summary of what changed in this project. Flags: --since 7d, --format markdown|plain.",
|
|
103
103
|
receipt: "Token-spend receipt for your recent Claude Code sessions. Shows where tokens went and projected yearly cost. Flags: --since 7d, --format plain|json.",
|
|
104
104
|
memory: "Manage the memory store. Subcommands: show, edit, import, export.",
|
|
105
|
+
marketing: "Run the local-first Sverklo Twitter agent team workflow. Subcommands: init, run-cycle, decide, status.",
|
|
105
106
|
grammars: "Manage tree-sitter grammars for the SVERKLO_PARSER=tree-sitter opt-in path. Subcommands: install.",
|
|
106
107
|
weights: "Inspect .sverklo.yaml weight rules. Subcommands: explain <path> — show which glob matched and the effective weight.",
|
|
107
108
|
"audit-prompt": "Print a ready-to-paste codebase-audit prompt (hybrid agent workflow).",
|
|
@@ -149,6 +150,132 @@ if (command === "--version" || command === "-v" || command === "-V") {
|
|
|
149
150
|
console.log("sverklo (version unknown)");
|
|
150
151
|
process.exit(0);
|
|
151
152
|
}
|
|
153
|
+
if (command === "marketing") {
|
|
154
|
+
const subcommand = args[1];
|
|
155
|
+
const flags = args.slice(2);
|
|
156
|
+
const flagVal = (name) => {
|
|
157
|
+
const idx = flags.indexOf(name);
|
|
158
|
+
if (idx !== -1 && flags[idx + 1])
|
|
159
|
+
return flags[idx + 1];
|
|
160
|
+
const prefixed = flags.find((f) => f.startsWith(`${name}=`));
|
|
161
|
+
return prefixed ? prefixed.slice(name.length + 1) : undefined;
|
|
162
|
+
};
|
|
163
|
+
const requireFlag = (name) => {
|
|
164
|
+
const value = flagVal(name);
|
|
165
|
+
if (!value) {
|
|
166
|
+
console.error(`✗ ${name} is required`);
|
|
167
|
+
process.exit(2);
|
|
168
|
+
}
|
|
169
|
+
return value;
|
|
170
|
+
};
|
|
171
|
+
const format = flagVal("--format") ?? "text";
|
|
172
|
+
if (format !== "text" && format !== "json") {
|
|
173
|
+
console.error(`✗ --format must be text or json, got "${format}"`);
|
|
174
|
+
process.exit(2);
|
|
175
|
+
}
|
|
176
|
+
const { appendOperatorDecision, applyOperatorDecision, assertEvidenceCatalog, assertProfileSnapshot, assertRecentPostsSnapshot, assertTrendSnapshot, buildStatusSummary, createOperatorDecision, initMarketingWorkspace, jsonFile, loadActiveCampaignCycle, loadCampaignCycle, loadMarketingWorkspace, marketingPaths, normalizeAccountHandle, recomputeCampaignReadiness, renderContentReport, renderOpportunityReport, renderProfileHealthReport, renderStatusText, resolveMarketingWorkspace, runCampaignCycle, saveCampaignCycle, saveMarketingWorkspace, writeReport, } = await import("../src/marketing/index.js");
|
|
177
|
+
const { existsSync } = await import("node:fs");
|
|
178
|
+
const { join } = await import("node:path");
|
|
179
|
+
const workspacePath = flagVal("--workspace");
|
|
180
|
+
const readOptional = (path) => {
|
|
181
|
+
return path && existsSync(path) ? jsonFile(path) : undefined;
|
|
182
|
+
};
|
|
183
|
+
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
184
|
+
console.log(`\nsverklo marketing — local-first Twitter agent team workflow\n\n` +
|
|
185
|
+
`Usage:\n` +
|
|
186
|
+
` sverklo marketing init --account @sverklo [--workspace PATH]\n` +
|
|
187
|
+
` sverklo marketing run-cycle [--workspace PATH] [--trends PATH] [--profile PATH] [--recent-posts PATH] [--evidence PATH] [--format text|json]\n` +
|
|
188
|
+
` sverklo marketing decide --target-type TYPE --target-id ID --decision VALUE [--reason TEXT] [--future]\n` +
|
|
189
|
+
` sverklo marketing status [--workspace PATH] [--format text|json]\n\n` +
|
|
190
|
+
`No command posts to X/Twitter, scrapes X, sends DMs, likes, reposts, follows, unfollows, or mutates the profile.\n`);
|
|
191
|
+
process.exit(0);
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
if (subcommand === "init") {
|
|
195
|
+
const account = normalizeAccountHandle(requireFlag("--account"));
|
|
196
|
+
const workspace = initMarketingWorkspace({ workspacePath, accountHandle: account });
|
|
197
|
+
console.log(`Initialized marketing workspace for ${workspace.account_handle} at ${resolveMarketingWorkspace(workspacePath)}`);
|
|
198
|
+
process.exit(0);
|
|
199
|
+
}
|
|
200
|
+
if (subcommand === "run-cycle") {
|
|
201
|
+
const workspace = loadMarketingWorkspace(workspacePath);
|
|
202
|
+
const root = resolveMarketingWorkspace(workspacePath);
|
|
203
|
+
const inputDir = marketingPaths(root).inputs;
|
|
204
|
+
const existing = loadActiveCampaignCycle(workspacePath, workspace);
|
|
205
|
+
const trends = readOptional(flagVal("--trends") ?? join(inputDir, "trend-snapshot.json"));
|
|
206
|
+
const profile = readOptional(flagVal("--profile") ?? join(inputDir, "profile-snapshot.json"));
|
|
207
|
+
const recentPosts = readOptional(flagVal("--recent-posts") ?? join(inputDir, "recent-posts.json"));
|
|
208
|
+
const evidence = readOptional(flagVal("--evidence") ?? join(inputDir, "evidence.json"));
|
|
209
|
+
if (trends)
|
|
210
|
+
assertTrendSnapshot(trends);
|
|
211
|
+
if (profile)
|
|
212
|
+
assertProfileSnapshot(profile);
|
|
213
|
+
if (recentPosts)
|
|
214
|
+
assertRecentPostsSnapshot(recentPosts);
|
|
215
|
+
if (evidence)
|
|
216
|
+
assertEvidenceCatalog(evidence);
|
|
217
|
+
if (!trends && !profile && !recentPosts && !evidence && !existing) {
|
|
218
|
+
throw new Error("no local marketing inputs found; provide --trends, --profile, --recent-posts, or --evidence");
|
|
219
|
+
}
|
|
220
|
+
const cycle = runCampaignCycle({
|
|
221
|
+
workspace,
|
|
222
|
+
existingCycle: existing,
|
|
223
|
+
trendSnapshot: trends,
|
|
224
|
+
profileSnapshot: profile,
|
|
225
|
+
recentPosts,
|
|
226
|
+
evidence,
|
|
227
|
+
cycleId: flagVal("--cycle"),
|
|
228
|
+
});
|
|
229
|
+
saveMarketingWorkspace(workspacePath, workspace);
|
|
230
|
+
saveCampaignCycle(workspacePath, cycle);
|
|
231
|
+
writeReport(workspacePath, cycle.cycle_id, "opportunities", renderOpportunityReport(cycle));
|
|
232
|
+
writeReport(workspacePath, cycle.cycle_id, "content", renderContentReport(cycle));
|
|
233
|
+
writeReport(workspacePath, cycle.cycle_id, "profile-health", renderProfileHealthReport(cycle));
|
|
234
|
+
const summary = buildStatusSummary(cycle);
|
|
235
|
+
if (format === "json")
|
|
236
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
237
|
+
else
|
|
238
|
+
process.stdout.write(renderStatusText(summary));
|
|
239
|
+
process.exit(0);
|
|
240
|
+
}
|
|
241
|
+
if (subcommand === "decide") {
|
|
242
|
+
const workspace = loadMarketingWorkspace(workspacePath);
|
|
243
|
+
if (!workspace.active_cycle_id)
|
|
244
|
+
throw new Error("no active marketing cycle");
|
|
245
|
+
const cycle = loadCampaignCycle(workspacePath, workspace.active_cycle_id);
|
|
246
|
+
const decision = createOperatorDecision({
|
|
247
|
+
targetType: requireFlag("--target-type"),
|
|
248
|
+
targetId: requireFlag("--target-id"),
|
|
249
|
+
decision: requireFlag("--decision"),
|
|
250
|
+
reason: flagVal("--reason"),
|
|
251
|
+
future: flags.includes("--future"),
|
|
252
|
+
});
|
|
253
|
+
applyOperatorDecision(workspace, cycle, decision);
|
|
254
|
+
recomputeCampaignReadiness(cycle);
|
|
255
|
+
saveMarketingWorkspace(workspacePath, workspace);
|
|
256
|
+
saveCampaignCycle(workspacePath, cycle);
|
|
257
|
+
appendOperatorDecision(workspacePath, decision);
|
|
258
|
+
console.log(`Recorded decision ${decision.decision_id}`);
|
|
259
|
+
process.exit(0);
|
|
260
|
+
}
|
|
261
|
+
if (subcommand === "status") {
|
|
262
|
+
const workspace = loadMarketingWorkspace(workspacePath);
|
|
263
|
+
const cycle = loadActiveCampaignCycle(workspacePath, workspace);
|
|
264
|
+
const summary = buildStatusSummary(cycle);
|
|
265
|
+
if (format === "json")
|
|
266
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
267
|
+
else
|
|
268
|
+
process.stdout.write(renderStatusText(summary));
|
|
269
|
+
process.exit(0);
|
|
270
|
+
}
|
|
271
|
+
console.error(`✗ unknown marketing subcommand: ${subcommand}`);
|
|
272
|
+
process.exit(2);
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
console.error(`✗ ${err instanceof Error ? err.message : String(err)}`);
|
|
276
|
+
process.exit(2);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
152
279
|
if (command === "init") {
|
|
153
280
|
// Parse flags: --auto-capture, --mine-chats, --global
|
|
154
281
|
const flags = args.filter((a) => a.startsWith("--"));
|
|
@@ -2646,6 +2773,7 @@ Memory + offline maintenance:
|
|
|
2646
2773
|
sverklo wiki Generate a markdown wiki from the indexed codebase
|
|
2647
2774
|
sverklo digest 5-line summary of what changed in this project (--since 7d)
|
|
2648
2775
|
sverklo memory export Export memories to markdown / Notion / JSON
|
|
2776
|
+
sverklo marketing Local Sverklo Twitter agent team workflow
|
|
2649
2777
|
sverklo grammars install Install tree-sitter grammars for the v0.17 opt-in parser
|
|
2650
2778
|
sverklo prune Decay stale memories + consolidate similar episodic ones
|
|
2651
2779
|
sverklo concept-index Label clusters with an LLM (requires Ollama)
|