@planckspace/cli 0.1.1 → 0.2.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 +24 -1
- package/dist/anomaly/constants.d.ts +13 -0
- package/dist/anomaly/constants.d.ts.map +1 -0
- package/dist/anomaly/constants.js +13 -0
- package/dist/anomaly/constants.js.map +1 -0
- package/dist/anomaly/detector.d.ts +12 -0
- package/dist/anomaly/detector.d.ts.map +1 -0
- package/dist/anomaly/detector.js +98 -0
- package/dist/anomaly/detector.js.map +1 -0
- package/dist/anomaly/types.d.ts +19 -0
- package/dist/anomaly/types.d.ts.map +1 -0
- package/dist/anomaly/types.js +2 -0
- package/dist/anomaly/types.js.map +1 -0
- package/dist/commands/budget.d.ts +26 -0
- package/dist/commands/budget.d.ts.map +1 -0
- package/dist/commands/budget.js +91 -0
- package/dist/commands/budget.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +45 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/connect.d.ts +17 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +191 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/daemon.d.ts +8 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +310 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/diagnose.d.ts +2 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +81 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +67 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/export.d.ts +40 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +184 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/init.d.ts +3 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +14 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/insights.d.ts +2 -0
- package/dist/commands/insights.d.ts.map +1 -0
- package/dist/commands/insights.js +71 -0
- package/dist/commands/insights.js.map +1 -0
- package/dist/commands/inspect.d.ts +2 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +81 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/integrations.d.ts +2 -0
- package/dist/commands/integrations.d.ts.map +1 -0
- package/dist/commands/integrations.js +46 -0
- package/dist/commands/integrations.js.map +1 -0
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +45 -6
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/metrics.d.ts +6 -0
- package/dist/commands/metrics.d.ts.map +1 -0
- package/dist/commands/metrics.js +85 -0
- package/dist/commands/metrics.js.map +1 -0
- package/dist/commands/reconcile.d.ts +2 -0
- package/dist/commands/reconcile.d.ts.map +1 -0
- package/dist/commands/reconcile.js +63 -0
- package/dist/commands/reconcile.js.map +1 -0
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +53 -10
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +84 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/subscription.d.ts +15 -0
- package/dist/commands/subscription.d.ts.map +1 -0
- package/dist/commands/subscription.js +62 -0
- package/dist/commands/subscription.js.map +1 -0
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +77 -10
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/value.d.ts +5 -0
- package/dist/commands/value.d.ts.map +1 -0
- package/dist/commands/value.js +95 -0
- package/dist/commands/value.js.map +1 -0
- package/dist/config.d.ts +28 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -1
- package/dist/config.js.map +1 -1
- package/dist/correlate.d.ts +7 -0
- package/dist/correlate.d.ts.map +1 -1
- package/dist/correlate.js +102 -15
- package/dist/correlate.js.map +1 -1
- package/dist/daemon/daemon.d.ts +2 -0
- package/dist/daemon/daemon.d.ts.map +1 -0
- package/dist/daemon/daemon.js +188 -0
- package/dist/daemon/daemon.js.map +1 -0
- package/dist/daemon/daemonState.d.ts +25 -0
- package/dist/daemon/daemonState.d.ts.map +1 -0
- package/dist/daemon/daemonState.js +82 -0
- package/dist/daemon/daemonState.js.map +1 -0
- package/dist/daemon/logger.d.ts +7 -0
- package/dist/daemon/logger.d.ts.map +1 -0
- package/dist/daemon/logger.js +61 -0
- package/dist/daemon/logger.js.map +1 -0
- package/dist/daemon/syncLoop.d.ts +38 -0
- package/dist/daemon/syncLoop.d.ts.map +1 -0
- package/dist/daemon/syncLoop.js +119 -0
- package/dist/daemon/syncLoop.js.map +1 -0
- package/dist/daemon/watcher.d.ts +26 -0
- package/dist/daemon/watcher.d.ts.map +1 -0
- package/dist/daemon/watcher.js +187 -0
- package/dist/daemon/watcher.js.map +1 -0
- package/dist/db/store.d.ts +123 -2
- package/dist/db/store.d.ts.map +1 -1
- package/dist/db/store.js +397 -11
- package/dist/db/store.js.map +1 -1
- package/dist/detectors/cache-gap.d.ts +3 -0
- package/dist/detectors/cache-gap.d.ts.map +1 -0
- package/dist/detectors/cache-gap.js +70 -0
- package/dist/detectors/cache-gap.js.map +1 -0
- package/dist/detectors/context-bloat.d.ts +3 -0
- package/dist/detectors/context-bloat.d.ts.map +1 -0
- package/dist/detectors/context-bloat.js +68 -0
- package/dist/detectors/context-bloat.js.map +1 -0
- package/dist/detectors/fileTokens.d.ts +3 -0
- package/dist/detectors/fileTokens.d.ts.map +1 -0
- package/dist/detectors/fileTokens.js +12 -0
- package/dist/detectors/fileTokens.js.map +1 -0
- package/dist/detectors/index.d.ts +20 -0
- package/dist/detectors/index.d.ts.map +1 -0
- package/dist/detectors/index.js +41 -0
- package/dist/detectors/index.js.map +1 -0
- package/dist/detectors/model-routing.d.ts +3 -0
- package/dist/detectors/model-routing.d.ts.map +1 -0
- package/dist/detectors/model-routing.js +71 -0
- package/dist/detectors/model-routing.js.map +1 -0
- package/dist/detectors/repeat-read.d.ts +3 -0
- package/dist/detectors/repeat-read.d.ts.map +1 -0
- package/dist/detectors/repeat-read.js +69 -0
- package/dist/detectors/repeat-read.js.map +1 -0
- package/dist/detectors/seat-efficiency.d.ts +4 -0
- package/dist/detectors/seat-efficiency.d.ts.map +1 -0
- package/dist/detectors/seat-efficiency.js +86 -0
- package/dist/detectors/seat-efficiency.js.map +1 -0
- package/dist/detectors/types.d.ts +46 -0
- package/dist/detectors/types.d.ts.map +1 -0
- package/dist/detectors/types.js +2 -0
- package/dist/detectors/types.js.map +1 -0
- package/dist/health.d.ts +59 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +106 -0
- package/dist/health.js.map +1 -0
- package/dist/index.js +389 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics.d.ts +29 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +205 -0
- package/dist/metrics.js.map +1 -0
- package/dist/scrapers/claudeCode.d.ts +1 -0
- package/dist/scrapers/claudeCode.d.ts.map +1 -1
- package/dist/scrapers/claudeCode.js +43 -13
- package/dist/scrapers/claudeCode.js.map +1 -1
- package/dist/scrapers/cursor.d.ts +3 -2
- package/dist/scrapers/cursor.d.ts.map +1 -1
- package/dist/scrapers/cursor.js +56 -16
- package/dist/scrapers/cursor.js.map +1 -1
- package/dist/scrapers/jetbrains.d.ts +15 -0
- package/dist/scrapers/jetbrains.d.ts.map +1 -0
- package/dist/scrapers/jetbrains.js +232 -0
- package/dist/scrapers/jetbrains.js.map +1 -0
- package/dist/scrapers/types.d.ts +4 -1
- package/dist/scrapers/types.d.ts.map +1 -1
- package/dist/scrapers/windsurf.d.ts +3 -2
- package/dist/scrapers/windsurf.d.ts.map +1 -1
- package/dist/scrapers/windsurf.js +25 -9
- package/dist/scrapers/windsurf.js.map +1 -1
- package/dist/sync/payload.d.ts +4 -5
- package/dist/sync/payload.d.ts.map +1 -1
- package/dist/sync/payload.js +88 -7
- package/dist/sync/payload.js.map +1 -1
- package/dist/sync/syncEngine.d.ts +19 -3
- package/dist/sync/syncEngine.d.ts.map +1 -1
- package/dist/sync/syncEngine.js +116 -10
- package/dist/sync/syncEngine.js.map +1 -1
- package/install.sh +27 -10
- package/package.json +43 -42
package/dist/sync/syncEngine.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getUnsyncedSessions, markSessionsSynced, recordSyncError, } from "../db/store.js";
|
|
1
|
+
import { getUnsyncedSessions, markSessionsSynced, recordSyncError, getUnsyncedInsights, markInsightsSynced, getUnsyncedAnomalies, markAnomaliesSynced, } from "../db/store.js";
|
|
2
2
|
import { buildTelemetryPayload } from "./payload.js";
|
|
3
3
|
const BATCH_SIZE = 100;
|
|
4
4
|
const MAX_RETRIES = 3;
|
|
@@ -17,7 +17,50 @@ function isTransient(outcome) {
|
|
|
17
17
|
return true;
|
|
18
18
|
return outcome.status >= 500 || outcome.status === 429;
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
function buildInsightPayload(r) {
|
|
21
|
+
return {
|
|
22
|
+
id: r.id,
|
|
23
|
+
detectorId: r.detectorId,
|
|
24
|
+
repoName: r.repoName ?? null,
|
|
25
|
+
scope: r.workspaceScope, // backend column is `scope`
|
|
26
|
+
developerEmail: null, // future: per-developer insights
|
|
27
|
+
titleShort: r.titleShort,
|
|
28
|
+
estimatedMonthlySavingsUsd: r.estimatedMonthlySavingsUsd,
|
|
29
|
+
confidence: r.confidence,
|
|
30
|
+
evidence: JSON.parse(r.evidenceJson),
|
|
31
|
+
manualFix: r.manualFix,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function buildAnomalyPayload(r) {
|
|
35
|
+
// Map local field names → backend IngestAnomalySchema field names.
|
|
36
|
+
const kind = r.type === "daily_cost_spike" ? "repo-spike" : "session-outlier";
|
|
37
|
+
const scope = r.repoName ?? r.sessionId ?? "unknown";
|
|
38
|
+
const severity = r.ratio >= 5 ? "critical" : "warn";
|
|
39
|
+
return {
|
|
40
|
+
kind,
|
|
41
|
+
scope,
|
|
42
|
+
severity,
|
|
43
|
+
baselineUsd: r.baselineUsd,
|
|
44
|
+
observedUsd: r.costUsd,
|
|
45
|
+
dedupeKey: r.id,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function buildBudgetPayload(b) {
|
|
49
|
+
// Map CLI Budget → backend IngestBudgetSchema.
|
|
50
|
+
return {
|
|
51
|
+
scope: b.scope,
|
|
52
|
+
scopeName: b.name,
|
|
53
|
+
monthlyUsd: b.monthly,
|
|
54
|
+
alertChannels: [],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* POST one batch to /api/ingest.
|
|
59
|
+
* Insights, subscriptions, anomalies, budgets, and productivity metrics ride in
|
|
60
|
+
* the same envelope — the backend processes them all atomically so there's no
|
|
61
|
+
* separate endpoint needed while B-series endpoints are being deployed.
|
|
62
|
+
*/
|
|
63
|
+
async function postBatch(deps, payloads, insightPayloads = [], anomalyPayloads = [], productivityMetrics = null) {
|
|
21
64
|
try {
|
|
22
65
|
const res = await fetch(`${deps.apiUrl}/api/ingest`, {
|
|
23
66
|
method: "POST",
|
|
@@ -25,7 +68,14 @@ async function postBatch(deps, payloads) {
|
|
|
25
68
|
"Content-Type": "application/json",
|
|
26
69
|
Authorization: `Bearer ${deps.token}`,
|
|
27
70
|
},
|
|
28
|
-
body: JSON.stringify(
|
|
71
|
+
body: JSON.stringify({
|
|
72
|
+
sessions: payloads,
|
|
73
|
+
workspaceSubscriptions: deps.workspaceSubscriptions ?? [],
|
|
74
|
+
insights: insightPayloads,
|
|
75
|
+
anomalies: anomalyPayloads,
|
|
76
|
+
budgets: (deps.budgets ?? []).map(buildBudgetPayload),
|
|
77
|
+
productivityMetric: null,
|
|
78
|
+
}),
|
|
29
79
|
});
|
|
30
80
|
if (res.ok)
|
|
31
81
|
return { ok: true, status: res.status };
|
|
@@ -41,22 +91,62 @@ async function postBatch(deps, payloads) {
|
|
|
41
91
|
}
|
|
42
92
|
}
|
|
43
93
|
/**
|
|
44
|
-
* Push all unsynced sessions to {apiUrl}/api/ingest in
|
|
45
|
-
*
|
|
46
|
-
*
|
|
94
|
+
* Push all unsynced sessions and insights to {apiUrl}/api/ingest in one envelope.
|
|
95
|
+
* Insights ride in the first batch (or the empty-sessions batch) so the backend
|
|
96
|
+
* sees them as soon as they exist, without waiting for a separate endpoint.
|
|
97
|
+
*
|
|
98
|
+
* Transient failures (network / 5xx / 429) retry with exponential backoff.
|
|
99
|
+
* Auth failures (401/403) abort remaining batches and add a warning to the result.
|
|
47
100
|
*/
|
|
48
101
|
export async function syncOnce(deps) {
|
|
102
|
+
const authWarnings = [];
|
|
103
|
+
// Compute workspace-level payloads once — they go in the first batch only.
|
|
104
|
+
// Metrics suppressed — CLI payload shape doesn't match backend schema yet.
|
|
105
|
+
const metricsResult = null;
|
|
106
|
+
const [unsyncedInsightRows, unsyncedAnomalyRows] = await Promise.all([
|
|
107
|
+
Promise.resolve(getUnsyncedInsights()),
|
|
108
|
+
Promise.resolve(getUnsyncedAnomalies()),
|
|
109
|
+
]);
|
|
110
|
+
const insightPayloads = unsyncedInsightRows.map(buildInsightPayload);
|
|
111
|
+
const anomalyPayloads = unsyncedAnomalyRows.map(buildAnomalyPayload);
|
|
49
112
|
const rows = getUnsyncedSessions();
|
|
50
|
-
if (rows.length === 0)
|
|
51
|
-
return { synced: 0, failed: 0 };
|
|
52
113
|
let synced = 0;
|
|
53
114
|
let failed = 0;
|
|
115
|
+
let metricsIncluded = false;
|
|
116
|
+
if (rows.length === 0) {
|
|
117
|
+
// No sessions — push subscriptions + insights + anomalies + budgets + metrics via
|
|
118
|
+
// an empty-sessions envelope so the backend stays current even between scans.
|
|
119
|
+
const outcome = await postBatch(deps, [], insightPayloads, anomalyPayloads, metricsResult);
|
|
120
|
+
if (outcome.ok) {
|
|
121
|
+
if (insightPayloads.length > 0) {
|
|
122
|
+
markInsightsSynced(unsyncedInsightRows.map((r) => r.id));
|
|
123
|
+
}
|
|
124
|
+
if (anomalyPayloads.length > 0) {
|
|
125
|
+
markAnomaliesSynced(unsyncedAnomalyRows.map((r) => r.id));
|
|
126
|
+
}
|
|
127
|
+
metricsIncluded = false;
|
|
128
|
+
const subscriptionCount = deps.workspaceSubscriptions?.length ?? 0;
|
|
129
|
+
return { synced: 0, failed: 0, subscriptionCount, pending: [], authWarnings, metricsIncluded };
|
|
130
|
+
}
|
|
131
|
+
if (outcome.status === 401 || outcome.status === 403)
|
|
132
|
+
authWarnings.push("sessions");
|
|
133
|
+
return { synced: 0, failed: 0, subscriptionCount: 0, pending: [], authWarnings, metricsIncluded: false };
|
|
134
|
+
}
|
|
135
|
+
let anyBatchOk = false;
|
|
136
|
+
let insightsSynced = false;
|
|
137
|
+
let anomaliesSynced = false;
|
|
138
|
+
let firstBatch = true;
|
|
54
139
|
for (const batch of chunk(rows, BATCH_SIZE)) {
|
|
55
140
|
const ids = batch.map((r) => r.id);
|
|
56
141
|
const payloads = batch.map((r) => buildTelemetryPayload(r, deps.workspaceId));
|
|
142
|
+
// Include insights + anomalies in the first batch only. Metrics always null (see above).
|
|
143
|
+
const batchInsights = firstBatch ? insightPayloads : [];
|
|
144
|
+
const batchAnomalies = firstBatch ? anomalyPayloads : [];
|
|
145
|
+
const batchMetrics = null;
|
|
146
|
+
firstBatch = false;
|
|
57
147
|
let outcome = { ok: false };
|
|
58
148
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
59
|
-
outcome = await postBatch(deps, payloads);
|
|
149
|
+
outcome = await postBatch(deps, payloads, batchInsights, batchAnomalies, batchMetrics);
|
|
60
150
|
if (outcome.ok || !isTransient(outcome) || attempt === MAX_RETRIES)
|
|
61
151
|
break;
|
|
62
152
|
// Exponential backoff: 500ms, 1s, 2s.
|
|
@@ -65,12 +155,28 @@ export async function syncOnce(deps) {
|
|
|
65
155
|
if (outcome.ok) {
|
|
66
156
|
markSessionsSynced(ids);
|
|
67
157
|
synced += ids.length;
|
|
158
|
+
anyBatchOk = true;
|
|
159
|
+
if (!insightsSynced && batchInsights.length > 0) {
|
|
160
|
+
markInsightsSynced(unsyncedInsightRows.map((r) => r.id));
|
|
161
|
+
insightsSynced = true;
|
|
162
|
+
}
|
|
163
|
+
if (!anomaliesSynced && batchAnomalies.length > 0) {
|
|
164
|
+
markAnomaliesSynced(unsyncedAnomalyRows.map((r) => r.id));
|
|
165
|
+
anomaliesSynced = true;
|
|
166
|
+
}
|
|
167
|
+
if (batchMetrics !== null)
|
|
168
|
+
metricsIncluded = true;
|
|
68
169
|
}
|
|
69
170
|
else {
|
|
70
171
|
recordSyncError(ids, outcome.error ?? "unknown error");
|
|
71
172
|
failed += ids.length;
|
|
173
|
+
if (outcome.status === 401 || outcome.status === 403) {
|
|
174
|
+
authWarnings.push("sessions");
|
|
175
|
+
break; // All batches will fail — stop early.
|
|
176
|
+
}
|
|
72
177
|
}
|
|
73
178
|
}
|
|
74
|
-
|
|
179
|
+
const subscriptionCount = anyBatchOk ? (deps.workspaceSubscriptions?.length ?? 0) : 0;
|
|
180
|
+
return { synced, failed, subscriptionCount, pending: [], authWarnings, metricsIncluded };
|
|
75
181
|
}
|
|
76
182
|
//# sourceMappingURL=syncEngine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncEngine.js","sourceRoot":"","sources":["../../src/sync/syncEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,
|
|
1
|
+
{"version":3,"file":"syncEngine.js","sourceRoot":"","sources":["../../src/sync/syncEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GAGpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAOrD,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,WAAW,GAAG,CAAC,CAAC;AAyBtB,SAAS,KAAK,CAAI,GAAQ,EAAE,IAAY;IACtC,MAAM,GAAG,GAAU,EAAE,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC5E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AASD,sFAAsF;AACtF,SAAS,WAAW,CAAC,OAAoB;IACvC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,OAAO,CAAC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,CAAC;AACzD,CAAC;AAED,SAAS,mBAAmB,CAAC,CAAa;IACxC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;QAC5B,KAAK,EAAE,CAAC,CAAC,cAAc,EAAW,4BAA4B;QAC9D,cAAc,EAAE,IAAI,EAAc,iCAAiC;QACnE,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,0BAA0B,EAAE,CAAC,CAAC,0BAA0B;QACxD,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAY;QAC/C,SAAS,EAAE,CAAC,CAAC,SAAS;KACvB,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,CAAa;IACxC,mEAAmE;IACnE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAC9E,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC;IACrD,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IACpD,OAAO;QACL,IAAI;QACJ,KAAK;QACL,QAAQ;QACR,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,WAAW,EAAE,CAAC,CAAC,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,EAAE;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAS;IACnC,+CAA+C;IAC/C,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,SAAS,EAAE,CAAC,CAAC,IAAI;QACjB,UAAU,EAAE,CAAC,CAAC,OAAO;QACrB,aAAa,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,SAAS,CACtB,IAAc,EACd,QAAmB,EACnB,kBAA6B,EAAE,EAC/B,kBAA6B,EAAE,EAC/B,sBAAkD,IAAI;IAEtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,aAAa,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;aACtC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,QAAQ,EAAE,QAAQ;gBAClB,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,IAAI,EAAE;gBACzD,QAAQ,EAAE,eAAe;gBACzB,SAAS,EAAE,eAAe;gBAC1B,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC;gBACrD,kBAAkB,EAAE,IAAI;aACzB,CAAC;SACH,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;SACpE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IAC/D,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc;IAC3C,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,aAAa,GAA+B,IAAI,CAAC;IACvD,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnE,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACtC,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;KACxC,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,mBAAmB,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,mBAAmB,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAErE,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IACnC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,kFAAkF;QAClF,8EAA8E;QAC9E,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;QAC3F,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,kBAAkB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3D,CAAC;YACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,mBAAmB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5D,CAAC;YACD,eAAe,GAAG,KAAK,CAAC;YACxB,MAAM,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,EAAE,MAAM,IAAI,CAAC,CAAC;YACnE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC;QACjG,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG;YAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpF,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IAC3G,CAAC;IAED,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,UAAU,GAAG,IAAI,CAAC;IAEtB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;QAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9E,yFAAyF;QACzF,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC;QAC1B,UAAU,GAAG,KAAK,CAAC;QAEnB,IAAI,OAAO,GAAgB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;QACzC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;YACxD,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;YACvF,IAAI,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,WAAW;gBAAE,MAAM;YAC1E,sCAAsC;YACtC,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;YACrB,UAAU,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,cAAc,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,kBAAkB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzD,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,eAAe,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClD,mBAAmB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC1D,eAAe,GAAG,IAAI,CAAC;YACzB,CAAC;YACD,IAAI,YAAY,KAAK,IAAI;gBAAE,eAAe,GAAG,IAAI,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;YACvD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;YACrB,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACrD,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC9B,MAAM,CAAC,sCAAsC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC;AAC3F,CAAC"}
|
package/install.sh
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
|
|
9
9
|
DASHBOARD_URL="https://app.planckspace.dev"
|
|
10
|
-
|
|
10
|
+
VSCODE_EXT_ID="planckspace.planckspace-extension"
|
|
11
|
+
VSCODE_EXT_URL="https://marketplace.visualstudio.com/items?itemName=${VSCODE_EXT_ID}"
|
|
12
|
+
OPENVSX_EXT_URL="https://open-vsx.org/extension/planckspace/planckspace-extension"
|
|
11
13
|
PKG="@planckspace/cli"
|
|
12
14
|
|
|
13
15
|
# ── helpers ──────────────────────────────────────────────────────────────────
|
|
@@ -72,8 +74,8 @@ info "Node $NODE_VER found."
|
|
|
72
74
|
command -v npm >/dev/null 2>&1 || die "npm not found. Re-install Node.js from https://nodejs.org"
|
|
73
75
|
|
|
74
76
|
# ── install CLI ──────────────────────────────────────────────────────────────
|
|
75
|
-
say "Installing $PKG..."
|
|
76
|
-
npm install -g "$PKG" --loglevel error
|
|
77
|
+
say "Installing $PKG@latest..."
|
|
78
|
+
npm install -g "$PKG@latest" --loglevel error
|
|
77
79
|
|
|
78
80
|
# verify the binary is reachable
|
|
79
81
|
command -v planck >/dev/null 2>&1 || {
|
|
@@ -102,13 +104,23 @@ else
|
|
|
102
104
|
fi
|
|
103
105
|
|
|
104
106
|
# ── scan (backfill existing history) ─────────────────────────────────────────
|
|
105
|
-
say "Scanning local AI session history
|
|
107
|
+
say "Scanning local AI session history..."
|
|
106
108
|
planck scan
|
|
107
109
|
|
|
108
110
|
# ── sync (only when connected) ───────────────────────────────────────────────
|
|
109
111
|
if [[ "$CONNECTED" == "true" ]]; then
|
|
110
112
|
say "Syncing data to your workspace..."
|
|
111
|
-
planck sync
|
|
113
|
+
planck scan --sync
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# ── VS Code extension ─────────────────────────────────────────────────────────
|
|
117
|
+
say "Installing VS Code extension..."
|
|
118
|
+
if command -v code >/dev/null 2>&1; then
|
|
119
|
+
code --install-extension "$VSCODE_EXT_ID" --force 2>/dev/null && \
|
|
120
|
+
info "Extension installed via 'code' CLI." || \
|
|
121
|
+
info "Extension install via CLI failed — install manually (see below)."
|
|
122
|
+
else
|
|
123
|
+
info "'code' CLI not found — install the extension manually."
|
|
112
124
|
fi
|
|
113
125
|
|
|
114
126
|
# ── done ─────────────────────────────────────────────────────────────────────
|
|
@@ -116,11 +128,16 @@ say "--------------------------------------"
|
|
|
116
128
|
say "PlanckSpace is ready."
|
|
117
129
|
say "--------------------------------------"
|
|
118
130
|
if [[ "$CONNECTED" == "true" ]]; then
|
|
119
|
-
info "Dashboard:
|
|
131
|
+
info "Dashboard: $DASHBOARD_URL"
|
|
120
132
|
else
|
|
121
|
-
info "Next step:
|
|
122
|
-
info "Dashboard:
|
|
133
|
+
info "Next step: planck login <token>"
|
|
134
|
+
info "Dashboard: $DASHBOARD_URL"
|
|
123
135
|
fi
|
|
124
|
-
info "
|
|
125
|
-
info "
|
|
136
|
+
info ""
|
|
137
|
+
info "VS Code extension:"
|
|
138
|
+
info " Marketplace: $VSCODE_EXT_URL"
|
|
139
|
+
info " Open VSX: $OPENVSX_EXT_URL"
|
|
140
|
+
info " Headless CLI: code --install-extension $VSCODE_EXT_ID"
|
|
141
|
+
info ""
|
|
142
|
+
info "Check setup: planck status"
|
|
126
143
|
say ""
|
package/package.json
CHANGED
|
@@ -1,42 +1,43 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@planckspace/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "PlanckSpace CLI — sync AI token usage from your editor to the team ledger",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"planck": "dist/index.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
-
"dev": "tsx src/index.ts",
|
|
12
|
-
"clean": "rm -rf dist",
|
|
13
|
-
"scan:test": "tsx src/scripts/scanTest.ts",
|
|
14
|
-
"test": "vitest run",
|
|
15
|
-
"prepublishOnly": "npm run build",
|
|
16
|
-
"release": "npm publish"
|
|
17
|
-
},
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": ">=20"
|
|
20
|
-
},
|
|
21
|
-
"files": [
|
|
22
|
-
"dist",
|
|
23
|
-
"install.sh"
|
|
24
|
-
],
|
|
25
|
-
"publishConfig": {
|
|
26
|
-
"access": "public"
|
|
27
|
-
},
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"@planckspace/core": "
|
|
30
|
-
"better-sqlite3": "^12.10.0",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"@types/
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@planckspace/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "PlanckSpace CLI — sync AI token usage from your editor to the team ledger",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"planck": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"clean": "rm -rf dist",
|
|
13
|
+
"scan:test": "tsx src/scripts/scanTest.ts",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
16
|
+
"release": "npm publish"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"install.sh"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@planckspace/core": "0.2.2",
|
|
30
|
+
"better-sqlite3": "^12.10.0",
|
|
31
|
+
"chokidar": "^5.0.0",
|
|
32
|
+
"commander": "^15.0.0",
|
|
33
|
+
"dotenv": "^17.4.2",
|
|
34
|
+
"simple-git": "^3.36.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
38
|
+
"@types/node": "^25.9.1",
|
|
39
|
+
"tsx": "^4.22.4",
|
|
40
|
+
"typescript": "^6.0.3",
|
|
41
|
+
"vitest": "^4.1.7"
|
|
42
|
+
}
|
|
43
|
+
}
|