@pdpp/local-collector 0.1.0-beta.5 → 0.1.0-beta.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.
@@ -1,12 +1,37 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync } from "node:fs";
2
+ import { existsSync, readFileSync } from "node:fs";
3
3
  import { basename, dirname, extname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { ALLOW_CUSTOM_COMMAND_ENV, CollectorCustomCommandRefusedError, CollectorUsageError, } from "../src/errors.js";
6
6
  import { BUNDLED_CONNECTOR_IDS, COLLECTOR_PROTOCOL_VERSION, COLLECTOR_RUNTIME_CAPABILITIES, LocalDeviceOutbox, enrollCollector, getBundledConnector, isMainModule, runCollectorConnector, } from "../src/runner.js";
7
7
  const DEFAULT_QUEUE_PATH = join(dirname(fileURLToPath(import.meta.url)), "..", ".pdpp-data", "collector-runner-queue.json");
8
8
  const LOCAL_COLLECTOR_PACKAGE_NAME = "@pdpp/local-collector";
9
- const LOCAL_COLLECTOR_PACKAGE_VERSION = "0.0.0";
9
+ const LOCAL_COLLECTOR_PACKAGE_VERSION_FALLBACK = "0.0.0";
10
+ export function resolveLocalCollectorPackageVersion(startUrl = import.meta.url) {
11
+ let current = typeof startUrl === "string" && !startUrl.startsWith("file:")
12
+ ? dirname(startUrl)
13
+ : dirname(fileURLToPath(startUrl));
14
+ for (;;) {
15
+ const manifestPath = join(current, "package.json");
16
+ if (existsSync(manifestPath)) {
17
+ try {
18
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
19
+ if (manifest.name === LOCAL_COLLECTOR_PACKAGE_NAME &&
20
+ typeof manifest.version === "string" &&
21
+ manifest.version) {
22
+ return manifest.version;
23
+ }
24
+ }
25
+ catch {
26
+ }
27
+ }
28
+ const parent = dirname(current);
29
+ if (parent === current) {
30
+ return LOCAL_COLLECTOR_PACKAGE_VERSION_FALLBACK;
31
+ }
32
+ current = parent;
33
+ }
34
+ }
10
35
  const HELP_TEXT = `pdpp-local-collector — PDPP local collector runner.
11
36
 
12
37
  Ownership: the local device/host supervisor decides when filesystem-class
@@ -153,7 +178,7 @@ export function inspectLocalOutboxStatus(options) {
153
178
  },
154
179
  package: {
155
180
  name: LOCAL_COLLECTOR_PACKAGE_NAME,
156
- version: LOCAL_COLLECTOR_PACKAGE_VERSION,
181
+ version: resolveLocalCollectorPackageVersion(),
157
182
  },
158
183
  source: {
159
184
  connection_id: options.sourceInstanceId ?? null,
@@ -148,6 +148,17 @@ export function observeJsonlFields(obj, obs, forcedSessionId) {
148
148
  }
149
149
  }
150
150
  }
151
+ function updateSessionAccumulatorFromCurrentLine(sessionAccumulators, projectDir, obs, obj, messageCountDelta) {
152
+ if (!obs.sessionId) {
153
+ return;
154
+ }
155
+ updateSessionAccumulator(sessionAccumulators, projectDir, {
156
+ ...obs,
157
+ firstTimestamp: obj.timestamp ?? null,
158
+ lastTimestamp: obj.timestamp ?? null,
159
+ messageCount: messageCountDelta,
160
+ });
161
+ }
151
162
  export function isMessageType(type) {
152
163
  return type === "user" || type === "assistant";
153
164
  }
@@ -357,11 +368,12 @@ async function parseJsonlFile(args) {
357
368
  message: ` ${path}: ${lineCount} lines parsed`,
358
369
  });
359
370
  }
371
+ const messageCountBeforeLine = obs.messageCount;
360
372
  observeJsonlFields(obj, obs, forcedSessionId);
361
373
  await processJsonlLine({ buildOnly, deps: { emitRecord, requested }, obj, obs });
362
- }
363
- if (buildOnly) {
364
- updateSessionAccumulator(sessionAccumulators, projectDir, obs);
374
+ if (buildOnly) {
375
+ updateSessionAccumulatorFromCurrentLine(sessionAccumulators, projectDir, obs, obj, obs.messageCount - messageCountBeforeLine);
376
+ }
365
377
  }
366
378
  return obs.sessionId;
367
379
  }
@@ -732,7 +744,8 @@ if (isMainModule(import.meta.url)) {
732
744
  const baseDir = process.env.CLAUDE_CODE_PROJECTS_DIR || join(claudeHome, "projects");
733
745
  await assertRequestedClaudeSources({ baseDir, claudeHome, requested });
734
746
  const typedState = state;
735
- const fileMtimes = streamFileMtimes(typedState, "messages") ?? typedState.file_mtimes ?? {};
747
+ const messageFileMtimes = streamFileMtimes(typedState, "messages") ?? typedState.file_mtimes ?? {};
748
+ const sessionFileMtimes = streamFileMtimes(typedState, "sessions") ?? {};
736
749
  const skillsMtimes = streamFileMtimes(typedState, "skills") ?? {};
737
750
  const slashCommandMtimes = streamFileMtimes(typedState, "slash_commands") ?? {};
738
751
  const memoryNoteMtimes = streamFileMtimes(typedState, "memory_notes") ?? {};
@@ -753,15 +766,16 @@ if (isMainModule(import.meta.url)) {
753
766
  if (!needsProjects) {
754
767
  return;
755
768
  }
756
- const newMtimes = { ...fileMtimes };
769
+ const newMessageFileMtimes = { ...messageFileMtimes };
770
+ const newSessionFileMtimes = { ...sessionFileMtimes };
757
771
  const sessionAccumulators = new Map();
758
772
  await scanProjectDirs({
759
773
  baseDir,
760
774
  buildOnly: true,
761
775
  emit,
762
776
  emitRecord,
763
- fileMtimes,
764
- newMtimes,
777
+ fileMtimes: sessionFileMtimes,
778
+ newMtimes: newSessionFileMtimes,
765
779
  memoryNoteMtimes,
766
780
  newMemoryNoteMtimes,
767
781
  requested,
@@ -772,7 +786,7 @@ if (isMainModule(import.meta.url)) {
772
786
  await emit({
773
787
  type: "STATE",
774
788
  stream: "sessions",
775
- cursor: { fetched_at: nowIso() },
789
+ cursor: { file_mtimes: newSessionFileMtimes, fetched_at: nowIso() },
776
790
  });
777
791
  }
778
792
  if (requested.has("memory_notes")) {
@@ -788,8 +802,8 @@ if (isMainModule(import.meta.url)) {
788
802
  buildOnly: false,
789
803
  emit,
790
804
  emitRecord,
791
- fileMtimes,
792
- newMtimes,
805
+ fileMtimes: messageFileMtimes,
806
+ newMtimes: newMessageFileMtimes,
793
807
  requested,
794
808
  sessionAccumulators,
795
809
  });
@@ -798,7 +812,7 @@ if (isMainModule(import.meta.url)) {
798
812
  await emit({
799
813
  type: "STATE",
800
814
  stream: "messages",
801
- cursor: { file_mtimes: newMtimes, fetched_at: nowIso() },
815
+ cursor: { file_mtimes: newMessageFileMtimes, fetched_at: nowIso() },
802
816
  });
803
817
  }
804
818
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdpp/local-collector",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Publishable local collector runtime for PDPP: filesystem-class connectors (Claude Code, Codex) plus the device-exporter ingest client.",
5
5
  "type": "module",
6
6
  "private": false,