adsinagents 0.1.5 → 0.1.7
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/cli/dist/index.js +11 -3
- package/daemon/dist/main.js +40 -14
- package/native/build.sh +7 -0
- package/package.json +1 -1
- package/statusline/dist/index.js +7 -2
package/cli/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { hostname } from "node:os";
|
|
|
19
19
|
import { homedir } from "node:os";
|
|
20
20
|
import { join } from "node:path";
|
|
21
21
|
var ADLINE_DIR = join(homedir(), ".adsinagents");
|
|
22
|
+
var HOOK_PORT = 8473;
|
|
22
23
|
var PATHS = {
|
|
23
24
|
root: ADLINE_DIR,
|
|
24
25
|
config: join(ADLINE_DIR, "config.json"),
|
|
@@ -4097,6 +4098,7 @@ function isCategory(value) {
|
|
|
4097
4098
|
}
|
|
4098
4099
|
|
|
4099
4100
|
// ../../shared/dist/schemas.js
|
|
4101
|
+
var AdSourceSchema = external_exports.enum(["gravity", "direct"]);
|
|
4100
4102
|
var AdSchema = external_exports.object({
|
|
4101
4103
|
/** Stable impression id for this rotation; idempotency key for firing. */
|
|
4102
4104
|
id: external_exports.string().min(1),
|
|
@@ -4113,7 +4115,7 @@ var AdSchema = external_exports.object({
|
|
|
4113
4115
|
/** Gravity click pixel (GET). Empty for direct campaigns. */
|
|
4114
4116
|
clickUrl: external_exports.string().default(""),
|
|
4115
4117
|
/** Source of demand. */
|
|
4116
|
-
source:
|
|
4118
|
+
source: AdSourceSchema,
|
|
4117
4119
|
/** Unix ms when this ad was fetched into cache. */
|
|
4118
4120
|
fetchedAt: external_exports.number().int(),
|
|
4119
4121
|
/**
|
|
@@ -4216,7 +4218,11 @@ var ImpressionSchema = external_exports.object({
|
|
|
4216
4218
|
verifiedAt: external_exports.number().int().nullable(),
|
|
4217
4219
|
impFired: external_exports.boolean(),
|
|
4218
4220
|
clicked: external_exports.boolean(),
|
|
4219
|
-
source:
|
|
4221
|
+
source: AdSourceSchema,
|
|
4222
|
+
/** Render surface the ad painted on. Only "statusline" is billable today
|
|
4223
|
+
* (spinner reach is un-billable and never writes a row). Recorded so the
|
|
4224
|
+
* publisher log can show *where* the ad showed. Older daemons omit it. */
|
|
4225
|
+
slot: external_exports.enum(["statusline", "spinner"]).default("statusline"),
|
|
4220
4226
|
/** Server serve-proof echoed back on sync. Empty for standalone/unverified. */
|
|
4221
4227
|
nonce: external_exports.string().default("")
|
|
4222
4228
|
});
|
|
@@ -4899,7 +4905,7 @@ function buildPlan(placement, spinnerVerbs) {
|
|
|
4899
4905
|
const statuslineCommand = existsSync5(nativeStatusline) ? nativeStatusline : `node ${join5(HERE2, "..", "..", "statusline", "dist", "index.js")}`;
|
|
4900
4906
|
return {
|
|
4901
4907
|
statuslineCommand,
|
|
4902
|
-
hookBaseUrl:
|
|
4908
|
+
hookBaseUrl: `http://127.0.0.1:${HOOK_PORT}`,
|
|
4903
4909
|
placement,
|
|
4904
4910
|
spinnerVerbs,
|
|
4905
4911
|
version: VERSION
|
|
@@ -4946,6 +4952,7 @@ async function cmdInit(flags) {
|
|
|
4946
4952
|
}
|
|
4947
4953
|
} else {
|
|
4948
4954
|
process.stdout.write("\u2022 device already registered\n");
|
|
4955
|
+
if (cfg.claimToken) claimUrl = `${cfg.serverUrl}/claim?t=${cfg.claimToken}`;
|
|
4949
4956
|
}
|
|
4950
4957
|
const platform = getPlatform();
|
|
4951
4958
|
const nodeBin = process.execPath;
|
|
@@ -4958,6 +4965,7 @@ async function cmdInit(flags) {
|
|
|
4958
4965
|
process.stdout.write(`
|
|
4959
4966
|
AdsInAgents is live (placement=${placement}). Run \`adsinagents doctor\` to verify.
|
|
4960
4967
|
`);
|
|
4968
|
+
process.stdout.write("Restart Claude Code (quit + reopen) so the status line picks up the ad.\n");
|
|
4961
4969
|
if (claimUrl) {
|
|
4962
4970
|
process.stdout.write(
|
|
4963
4971
|
`
|
package/daemon/dist/main.js
CHANGED
|
@@ -14,6 +14,7 @@ import { writeFileSync as writeFileSync4 } from "node:fs";
|
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
var ADLINE_DIR = join(homedir(), ".adsinagents");
|
|
17
|
+
var HOOK_PORT = 8473;
|
|
17
18
|
var PATHS = {
|
|
18
19
|
root: ADLINE_DIR,
|
|
19
20
|
config: join(ADLINE_DIR, "config.json"),
|
|
@@ -4102,6 +4103,9 @@ function matchesBlocked(ad, blocked) {
|
|
|
4102
4103
|
}
|
|
4103
4104
|
|
|
4104
4105
|
// ../../shared/dist/schemas.js
|
|
4106
|
+
var AdSourceSchema = external_exports.enum(["gravity", "direct"]);
|
|
4107
|
+
var GRAVITY_CAMPAIGN_ID = "gravity";
|
|
4108
|
+
var FALLBACK_AD_URL = "https://trygravity.ai";
|
|
4105
4109
|
var AdSchema = external_exports.object({
|
|
4106
4110
|
/** Stable impression id for this rotation; idempotency key for firing. */
|
|
4107
4111
|
id: external_exports.string().min(1),
|
|
@@ -4118,7 +4122,7 @@ var AdSchema = external_exports.object({
|
|
|
4118
4122
|
/** Gravity click pixel (GET). Empty for direct campaigns. */
|
|
4119
4123
|
clickUrl: external_exports.string().default(""),
|
|
4120
4124
|
/** Source of demand. */
|
|
4121
|
-
source:
|
|
4125
|
+
source: AdSourceSchema,
|
|
4122
4126
|
/** Unix ms when this ad was fetched into cache. */
|
|
4123
4127
|
fetchedAt: external_exports.number().int(),
|
|
4124
4128
|
/**
|
|
@@ -4222,7 +4226,11 @@ var ImpressionSchema = external_exports.object({
|
|
|
4222
4226
|
verifiedAt: external_exports.number().int().nullable(),
|
|
4223
4227
|
impFired: external_exports.boolean(),
|
|
4224
4228
|
clicked: external_exports.boolean(),
|
|
4225
|
-
source:
|
|
4229
|
+
source: AdSourceSchema,
|
|
4230
|
+
/** Render surface the ad painted on. Only "statusline" is billable today
|
|
4231
|
+
* (spinner reach is un-billable and never writes a row). Recorded so the
|
|
4232
|
+
* publisher log can show *where* the ad showed. Older daemons omit it. */
|
|
4233
|
+
slot: external_exports.enum(["statusline", "spinner"]).default("statusline"),
|
|
4226
4234
|
/** Server serve-proof echoed back on sync. Empty for standalone/unverified. */
|
|
4227
4235
|
nonce: external_exports.string().default("")
|
|
4228
4236
|
});
|
|
@@ -4818,6 +4826,7 @@ var Ledger = class {
|
|
|
4818
4826
|
imp_fired INTEGER NOT NULL DEFAULT 0,
|
|
4819
4827
|
clicked INTEGER NOT NULL DEFAULT 0,
|
|
4820
4828
|
nonce TEXT NOT NULL DEFAULT '',
|
|
4829
|
+
slot TEXT NOT NULL DEFAULT 'statusline',
|
|
4821
4830
|
synced INTEGER NOT NULL DEFAULT 0
|
|
4822
4831
|
);
|
|
4823
4832
|
CREATE INDEX IF NOT EXISTS idx_imp_unsynced ON impressions(synced);
|
|
@@ -4827,14 +4836,17 @@ var Ledger = class {
|
|
|
4827
4836
|
if (!cols.some((c) => c.name === "nonce")) {
|
|
4828
4837
|
this.db.exec(`ALTER TABLE impressions ADD COLUMN nonce TEXT NOT NULL DEFAULT ''`);
|
|
4829
4838
|
}
|
|
4839
|
+
if (!cols.some((c) => c.name === "slot")) {
|
|
4840
|
+
this.db.exec(`ALTER TABLE impressions ADD COLUMN slot TEXT NOT NULL DEFAULT 'statusline'`);
|
|
4841
|
+
}
|
|
4830
4842
|
}
|
|
4831
4843
|
/** Record an impression starting (idempotent — ignore if id already present). */
|
|
4832
4844
|
startImpression(row) {
|
|
4833
4845
|
this.db.prepare(
|
|
4834
4846
|
`INSERT OR IGNORE INTO impressions
|
|
4835
|
-
(id, ad_id, campaign_id, session_id, source, started_at, nonce)
|
|
4836
|
-
VALUES (@id, @adId, @campaignId, @sessionId, @source, @startedAt, @nonce)`
|
|
4837
|
-
).run({ ...row, nonce: row.nonce ?? "" });
|
|
4847
|
+
(id, ad_id, campaign_id, session_id, source, started_at, nonce, slot)
|
|
4848
|
+
VALUES (@id, @adId, @campaignId, @sessionId, @source, @startedAt, @nonce, @slot)`
|
|
4849
|
+
).run({ ...row, nonce: row.nonce ?? "", slot: row.slot ?? "statusline" });
|
|
4838
4850
|
}
|
|
4839
4851
|
/**
|
|
4840
4852
|
* Mark verified + fired. Persist-before-fire: call this, then fire impUrl.
|
|
@@ -4874,7 +4886,7 @@ var Ledger = class {
|
|
|
4874
4886
|
const rows = this.db.prepare(
|
|
4875
4887
|
`SELECT id, ad_id as adId, campaign_id as campaignId, session_id as sessionId,
|
|
4876
4888
|
source, started_at as startedAt, verified_at as verifiedAt,
|
|
4877
|
-
imp_fired as impFired, clicked, nonce
|
|
4889
|
+
imp_fired as impFired, clicked, nonce, slot
|
|
4878
4890
|
FROM impressions WHERE synced = 0 ORDER BY started_at LIMIT @limit`
|
|
4879
4891
|
).all({ limit });
|
|
4880
4892
|
return rows.map((r) => ({
|
|
@@ -4887,6 +4899,7 @@ var Ledger = class {
|
|
|
4887
4899
|
verifiedAt: r.verifiedAt ?? null,
|
|
4888
4900
|
impFired: !!r.impFired,
|
|
4889
4901
|
clicked: !!r.clicked,
|
|
4902
|
+
slot: r.slot ?? "statusline",
|
|
4890
4903
|
nonce: r.nonce ?? ""
|
|
4891
4904
|
}));
|
|
4892
4905
|
}
|
|
@@ -5027,7 +5040,7 @@ function newImpId(nowMs) {
|
|
|
5027
5040
|
}
|
|
5028
5041
|
var BUILTIN_TEST_ADS = [
|
|
5029
5042
|
{
|
|
5030
|
-
campaignId:
|
|
5043
|
+
campaignId: GRAVITY_CAMPAIGN_ID,
|
|
5031
5044
|
text: "Ship faster \u2014 catch errors before users do",
|
|
5032
5045
|
brandName: "Sentry",
|
|
5033
5046
|
url: "https://sentry.io",
|
|
@@ -5036,7 +5049,7 @@ var BUILTIN_TEST_ADS = [
|
|
|
5036
5049
|
source: "gravity"
|
|
5037
5050
|
},
|
|
5038
5051
|
{
|
|
5039
|
-
campaignId:
|
|
5052
|
+
campaignId: GRAVITY_CAMPAIGN_ID,
|
|
5040
5053
|
text: "Postgres without the ops \u2014 serverless branches",
|
|
5041
5054
|
brandName: "Neon",
|
|
5042
5055
|
url: "https://neon.tech",
|
|
@@ -5045,7 +5058,7 @@ var BUILTIN_TEST_ADS = [
|
|
|
5045
5058
|
source: "gravity"
|
|
5046
5059
|
},
|
|
5047
5060
|
{
|
|
5048
|
-
campaignId:
|
|
5061
|
+
campaignId: GRAVITY_CAMPAIGN_ID,
|
|
5049
5062
|
text: "Deploy in seconds, scale to zero",
|
|
5050
5063
|
brandName: "Vercel",
|
|
5051
5064
|
url: "https://vercel.com",
|
|
@@ -5133,7 +5146,7 @@ function startServer(deps) {
|
|
|
5133
5146
|
const ad = readCurrentAd();
|
|
5134
5147
|
deps.ledger.markClicked(impId);
|
|
5135
5148
|
if (ad && ad.id === impId && ad.clickUrl) deps.firePixel(ad.clickUrl);
|
|
5136
|
-
const dest = ad?.url ||
|
|
5149
|
+
const dest = ad?.url || FALLBACK_AD_URL;
|
|
5137
5150
|
res.writeHead(302, { location: dest });
|
|
5138
5151
|
res.end();
|
|
5139
5152
|
return;
|
|
@@ -5172,12 +5185,22 @@ function startServer(deps) {
|
|
|
5172
5185
|
res.end("error");
|
|
5173
5186
|
}
|
|
5174
5187
|
});
|
|
5175
|
-
return new Promise((resolve) => {
|
|
5176
|
-
|
|
5188
|
+
return new Promise((resolve, reject) => {
|
|
5189
|
+
const onListening = () => {
|
|
5177
5190
|
const addr = server.address();
|
|
5178
5191
|
const port = typeof addr === "object" && addr ? addr.port : 0;
|
|
5179
5192
|
resolve({ server, port });
|
|
5180
|
-
}
|
|
5193
|
+
};
|
|
5194
|
+
const onError = (err) => {
|
|
5195
|
+
if (err.code === "EADDRINUSE") {
|
|
5196
|
+
server.once("error", reject);
|
|
5197
|
+
server.listen(0, "127.0.0.1", onListening);
|
|
5198
|
+
return;
|
|
5199
|
+
}
|
|
5200
|
+
reject(err);
|
|
5201
|
+
};
|
|
5202
|
+
server.once("error", onError);
|
|
5203
|
+
server.listen(HOOK_PORT, "127.0.0.1", onListening);
|
|
5181
5204
|
});
|
|
5182
5205
|
}
|
|
5183
5206
|
|
|
@@ -5361,7 +5384,10 @@ async function main() {
|
|
|
5361
5384
|
sessionId: sid,
|
|
5362
5385
|
source: ad.source,
|
|
5363
5386
|
startedAt: nowMs,
|
|
5364
|
-
nonce: ad.nonce
|
|
5387
|
+
nonce: ad.nonce,
|
|
5388
|
+
// Only the status line writes a billable impression — spinner reach
|
|
5389
|
+
// is un-billable and never reaches this path. Recorded for the log.
|
|
5390
|
+
slot: "statusline"
|
|
5365
5391
|
});
|
|
5366
5392
|
}
|
|
5367
5393
|
} catch (e) {
|
package/native/build.sh
CHANGED
|
@@ -7,6 +7,13 @@ set -euo pipefail
|
|
|
7
7
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
8
8
|
OUT="${1:-$HERE/build}"
|
|
9
9
|
|
|
10
|
+
# macOS-only: these helpers import AppKit. On any non-Darwin host (Linux CI),
|
|
11
|
+
# skip cleanly — the binary is compiled on the user's Mac at runtime, never in CI.
|
|
12
|
+
if [ "$(uname -s)" != "Darwin" ]; then
|
|
13
|
+
echo "native: skipping Swift build on non-macOS ($(uname -s))" >&2
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
10
17
|
if ! xcrun --find swiftc >/dev/null 2>&1 && ! command -v swiftc >/dev/null 2>&1; then
|
|
11
18
|
echo "swiftc not found (install Xcode Command Line Tools: xcode-select --install)" >&2
|
|
12
19
|
exit 3
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adsinagents",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Get paid while you build. AdsInAgents is the terminal-native ad layer for AI coding agents. Verified impressions pay you.",
|
|
5
5
|
"homepage": "https://adsinagents.com",
|
|
6
6
|
"license": "UNLICENSED",
|
package/statusline/dist/index.js
CHANGED
|
@@ -4082,6 +4082,7 @@ var CATEGORY_KEYS = Object.keys(CATEGORIES);
|
|
|
4082
4082
|
var CategorySchema = external_exports.enum(CATEGORY_KEYS);
|
|
4083
4083
|
|
|
4084
4084
|
// ../../shared/dist/schemas.js
|
|
4085
|
+
var AdSourceSchema = external_exports.enum(["gravity", "direct"]);
|
|
4085
4086
|
var AdSchema = external_exports.object({
|
|
4086
4087
|
/** Stable impression id for this rotation; idempotency key for firing. */
|
|
4087
4088
|
id: external_exports.string().min(1),
|
|
@@ -4098,7 +4099,7 @@ var AdSchema = external_exports.object({
|
|
|
4098
4099
|
/** Gravity click pixel (GET). Empty for direct campaigns. */
|
|
4099
4100
|
clickUrl: external_exports.string().default(""),
|
|
4100
4101
|
/** Source of demand. */
|
|
4101
|
-
source:
|
|
4102
|
+
source: AdSourceSchema,
|
|
4102
4103
|
/** Unix ms when this ad was fetched into cache. */
|
|
4103
4104
|
fetchedAt: external_exports.number().int(),
|
|
4104
4105
|
/**
|
|
@@ -4201,7 +4202,11 @@ var ImpressionSchema = external_exports.object({
|
|
|
4201
4202
|
verifiedAt: external_exports.number().int().nullable(),
|
|
4202
4203
|
impFired: external_exports.boolean(),
|
|
4203
4204
|
clicked: external_exports.boolean(),
|
|
4204
|
-
source:
|
|
4205
|
+
source: AdSourceSchema,
|
|
4206
|
+
/** Render surface the ad painted on. Only "statusline" is billable today
|
|
4207
|
+
* (spinner reach is un-billable and never writes a row). Recorded so the
|
|
4208
|
+
* publisher log can show *where* the ad showed. Older daemons omit it. */
|
|
4209
|
+
slot: external_exports.enum(["statusline", "spinner"]).default("statusline"),
|
|
4205
4210
|
/** Server serve-proof echoed back on sync. Empty for standalone/unverified. */
|
|
4206
4211
|
nonce: external_exports.string().default("")
|
|
4207
4212
|
});
|