kankaku 0.7.1 → 0.8.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 +60 -21
- package/dist/adapters/export-writer.d.ts +13 -0
- package/dist/adapters/export-writer.js +28 -0
- package/dist/adapters/hub-actions.d.ts +35 -0
- package/dist/adapters/hub-actions.js +70 -0
- package/dist/adapters/project-config.d.ts +42 -0
- package/dist/adapters/project-config.js +108 -0
- package/dist/adapters/report-data.d.ts +12 -0
- package/dist/adapters/report-data.js +8 -0
- package/dist/adapters/report-views.d.ts +45 -0
- package/dist/adapters/report-views.js +73 -0
- package/dist/adapters/report.d.ts +112 -0
- package/dist/adapters/report.js +236 -0
- package/dist/adapters/sync-runner.d.ts +21 -6
- package/dist/adapters/sync-runner.js +8 -1
- package/dist/domain/hub-entry.d.ts +26 -2
- package/dist/domain/hub-entry.js +50 -6
- package/dist/domain/sync-plan.js +10 -0
- package/dist/domain/work-record.d.ts +17 -0
- package/dist/domain/work-record.js +5 -1
- package/dist/hub/index.d.ts +6 -0
- package/dist/hub/index.js +6 -0
- package/package.json +1 -1
- package/src/adapters/hub-actions.ts +2 -3
- package/src/adapters/kankaku-command.ts +5 -9
- package/src/adapters/pi-tracker.ts +8 -0
- package/src/adapters/report-data.ts +13 -0
- package/src/adapters/report-views.ts +1 -1
- package/src/adapters/sync-runner.ts +21 -7
- package/src/domain/hub-entry.ts +87 -8
- package/src/domain/sync-plan.ts +10 -0
- package/src/domain/work-record.ts +22 -1
- package/src/hub/index.ts +6 -0
|
@@ -6,15 +6,14 @@
|
|
|
6
6
|
* see odd/tasks/kankaku-panel.md P4.
|
|
7
7
|
*/
|
|
8
8
|
import type { CatalogSnapshot } from "../ports/catalog.ts";
|
|
9
|
-
import type {
|
|
10
|
-
import type { SyncSummary } from "./sync-runner.ts";
|
|
9
|
+
import type { SyncStatusSnapshot, SyncSummary } from "./sync-runner.ts";
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* `/kankaku sync status`'s report lines: the watermark, the pending count,
|
|
14
13
|
* how many tasks fell outside this run's revisit window (R3), and the last
|
|
15
14
|
* error, when any. Exact body of `handleSyncCommand`'s `status` branch.
|
|
16
15
|
*/
|
|
17
|
-
export function buildSyncStatusLines(status:
|
|
16
|
+
export function buildSyncStatusLines(status: SyncStatusSnapshot): string[] {
|
|
18
17
|
const { state, pending, staleOutsideWindow } = status;
|
|
19
18
|
const lines = [state?.syncedThrough ? `synced through ${state.syncedThrough}` : "never synced", `pending: ${pending}`];
|
|
20
19
|
if (staleOutsideWindow > 0) {
|
|
@@ -7,24 +7,20 @@ import { formatWorkTargetLabel } from "../domain/work-target.ts";
|
|
|
7
7
|
import { findAmbiguousToolNames } from "../domain/subagent-profile.ts";
|
|
8
8
|
import type { SubagentProfile } from "../domain/subagent-profile.ts";
|
|
9
9
|
import type { RejectedChildEnvMarker } from "../config.ts";
|
|
10
|
-
import type { SyncState } from "../domain/sync-plan.ts";
|
|
11
10
|
import type { RegistryClassification } from "../domain/registry-health.ts";
|
|
12
11
|
import type { Catalog } from "../ports/catalog.ts";
|
|
13
12
|
import type { WorkLog } from "../ports/work-log.ts";
|
|
14
13
|
import { buildSyncStatusLines, formatBackfillLines, formatCatalogRefreshLines, formatSyncSummaryLines } from "./hub-actions.ts";
|
|
15
14
|
import { buildClientsView, buildExportContent, buildProjectsView, buildSessionsView, buildSummaryView, buildTasksView } from "./report-views.ts";
|
|
16
|
-
import type { SyncSummary, SyncTrigger } from "./sync-runner.ts";
|
|
15
|
+
import type { SyncStatusSnapshot, SyncSummary, SyncTrigger } from "./sync-runner.ts";
|
|
17
16
|
import type { SessionClient } from "./session-client.ts";
|
|
18
17
|
import { readNonDefaultSessionDir } from "./session-dir.ts";
|
|
19
18
|
import type { SessionTarget } from "./session-target.ts";
|
|
19
|
+
import type { KankakuReportData } from "./report-data.ts";
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
export type { KankakuReportData } from "./report-data.ts";
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
export interface KankakuReportData {
|
|
25
|
-
title: string;
|
|
26
|
-
lines: string[];
|
|
27
|
-
}
|
|
23
|
+
const REPORT_ENTRY_TYPE = "kankaku-report";
|
|
28
24
|
|
|
29
25
|
/** Notify the user of an error through the UI, when one is available. */
|
|
30
26
|
export function notifyError(ctx: ExtensionContext, error: unknown): void {
|
|
@@ -217,7 +213,7 @@ export interface SyncCommandDeps {
|
|
|
217
213
|
* count, and (R3) how many tasks changed since their last sync but fall
|
|
218
214
|
* outside this run's revisit window — needs `sync all`. No network.
|
|
219
215
|
*/
|
|
220
|
-
status: () =>
|
|
216
|
+
status: () => SyncStatusSnapshot;
|
|
221
217
|
}
|
|
222
218
|
|
|
223
219
|
export interface KankakuCommandDeps {
|
|
@@ -496,6 +496,14 @@ export function createPiTracker(pi: ExtensionAPI, deps: PiTrackerDeps): void {
|
|
|
496
496
|
...(roleConfidence !== undefined ? { roleConfidence } : {}),
|
|
497
497
|
...(deps.orchestratorRef !== undefined ? { orchestratorRef: deps.orchestratorRef } : {}),
|
|
498
498
|
...(deps.profile !== undefined ? { profile: deps.profile } : {}),
|
|
499
|
+
// Who measured this record, not who later syncs it — see
|
|
500
|
+
// `domain/work-record.ts#WorkRecordMetadata.agent`. Always stamped for
|
|
501
|
+
// every record this process appends; the versions are the same ones
|
|
502
|
+
// `extension.ts` already resolves for the `about` screen.
|
|
503
|
+
agent: "pi",
|
|
504
|
+
...(deps.agentVersion !== undefined ? { agentVersion: deps.agentVersion } : {}),
|
|
505
|
+
plugin: "kankaku",
|
|
506
|
+
...(deps.pluginVersion !== undefined ? { pluginVersion: deps.pluginVersion } : {}),
|
|
499
507
|
};
|
|
500
508
|
}
|
|
501
509
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi-free home for {@link KankakuReportData}, the shape every `/kankaku`
|
|
3
|
+
* report view and the panel's report screen produce. Extracted out of
|
|
4
|
+
* `kankaku-command.ts` (which still re-exports it) so `report-views.ts` can
|
|
5
|
+
* be published through `kankaku/hub` without pulling in anything that
|
|
6
|
+
* touches `@earendil-works/*` — see AGENTS.md "Code conventions".
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Durable report rendered inside the chat transcript; never sent to the LLM. */
|
|
10
|
+
export interface KankakuReportData {
|
|
11
|
+
title: string;
|
|
12
|
+
lines: string[];
|
|
13
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { buildSessions, buildTasks } from "../domain/task-view.ts";
|
|
10
10
|
import { exportRows, toCsv, toJson } from "../domain/export.ts";
|
|
11
11
|
import type { WorkRecord } from "../domain/work-record.ts";
|
|
12
|
-
import type { KankakuReportData } from "./
|
|
12
|
+
import type { KankakuReportData } from "./report-data.ts";
|
|
13
13
|
import { countUncertain, formatClients, formatProjects, formatReport, formatSessions, formatTasks, localDay, summarize, summarizeByClient, summarizeByProject } from "./report.ts";
|
|
14
14
|
|
|
15
15
|
/** Shared by every view except `buildTasksView`: `all` includes every day, otherwise only today's local day. */
|
|
@@ -250,12 +250,31 @@ function persistError(deps: SyncRunnerDeps, state: ReturnType<SyncStateStore["re
|
|
|
250
250
|
});
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
/**
|
|
253
|
+
/**
|
|
254
|
+
* Number of tasks pending a sync right now — computed locally, no network.
|
|
255
|
+
*
|
|
256
|
+
* @deprecated Superseded by {@link computeSyncStatus}, which returns the same
|
|
257
|
+
* `pending` count together with `state` and `staleOutsideWindow`. Nothing in
|
|
258
|
+
* kankaku calls this any more; it stays only because it is part of the
|
|
259
|
+
* published `kankaku/hub` surface. It will be removed in the next minor.
|
|
260
|
+
*/
|
|
254
261
|
export function pendingCount(tasks: TaskView[], state: ReturnType<SyncStateStore["read"]>, target: string, windowHours?: number): number {
|
|
255
262
|
const plan = planSync(tasks, state, { target, ...(windowHours !== undefined ? { windowHours } : {}) });
|
|
256
263
|
return plan.toSync.length + plan.correctionsDeferred;
|
|
257
264
|
}
|
|
258
265
|
|
|
266
|
+
/**
|
|
267
|
+
* {@link computeSyncStatus}'s return shape, exported so a caller (e.g.
|
|
268
|
+
* `hub-actions.ts#buildSyncStatusLines`, or a future standalone TUI reusing
|
|
269
|
+
* `kankaku/hub`) can depend on this type without importing anything that
|
|
270
|
+
* touches `@earendil-works/*` — see AGENTS.md "Code conventions".
|
|
271
|
+
*/
|
|
272
|
+
export interface SyncStatusSnapshot {
|
|
273
|
+
state: SyncState | undefined;
|
|
274
|
+
pending: number;
|
|
275
|
+
staleOutsideWindow: number;
|
|
276
|
+
}
|
|
277
|
+
|
|
259
278
|
/**
|
|
260
279
|
* `/kankaku sync status`: the persisted state, a locally-computed pending
|
|
261
280
|
* count, and (R3) how many tasks changed since their last sync but fall
|
|
@@ -263,12 +282,7 @@ export function pendingCount(tasks: TaskView[], state: ReturnType<SyncStateStore
|
|
|
263
282
|
* (see `domain/sync-plan.ts#SyncPlan.staleOutsideWindow`, and README "Hub
|
|
264
283
|
* (PocketBase)" > "Sync" > "Limitations"). No network.
|
|
265
284
|
*/
|
|
266
|
-
export function computeSyncStatus(
|
|
267
|
-
log: WorkLog,
|
|
268
|
-
stateStore: SyncStateStore,
|
|
269
|
-
target: string,
|
|
270
|
-
windowHours?: number,
|
|
271
|
-
): { state: ReturnType<SyncStateStore["read"]>; pending: number; staleOutsideWindow: number } {
|
|
285
|
+
export function computeSyncStatus(log: WorkLog, stateStore: SyncStateStore, target: string, windowHours?: number): SyncStatusSnapshot {
|
|
272
286
|
const state = stateStore.read();
|
|
273
287
|
const tasks = buildTasks(log.readAll());
|
|
274
288
|
const plan = planSync(tasks, state, { target, ...(windowHours !== undefined ? { windowHours } : {}) });
|
package/src/domain/hub-entry.ts
CHANGED
|
@@ -207,10 +207,12 @@ export interface TaskEntryPayload {
|
|
|
207
207
|
legacy_client_label: string;
|
|
208
208
|
repo_project: string;
|
|
209
209
|
schema: number;
|
|
210
|
+
/** Coding agent that MEASURED this task, lowercase slug — the orchestrator record's own {@link WorkRecordMetadata.agent} when it carries one (who measured, not who syncs), else `ctx.agent` (the syncing process's own identity) as a legacy fallback. See {@link WorkRecordMetadata.agent}. */
|
|
210
211
|
agent: string;
|
|
211
212
|
agent_version?: string;
|
|
212
213
|
/** Non-default session directory, see `TaskView.sessionDir`. A measurement field, not assignment: sent on both create and update. */
|
|
213
214
|
session_dir?: string;
|
|
215
|
+
/** The integration that wrote this task's records, lowercase slug — same record-wins-over-ctx rule as {@link agent}. */
|
|
214
216
|
plugin: string;
|
|
215
217
|
plugin_version?: string;
|
|
216
218
|
waiting_quality: WaitingQuality;
|
|
@@ -218,12 +220,59 @@ export interface TaskEntryPayload {
|
|
|
218
220
|
subagent_linkage: SubagentLinkage;
|
|
219
221
|
}
|
|
220
222
|
|
|
221
|
-
/**
|
|
222
|
-
|
|
223
|
+
/**
|
|
224
|
+
* `TaskEntryPayload` minus the assignment fields — what an update sends. See
|
|
225
|
+
* the module docs' CRITICAL rule.
|
|
226
|
+
*
|
|
227
|
+
* `agent`/`agent_version`/`plugin`/`plugin_version` are optional here (unlike
|
|
228
|
+
* on `TaskEntryPayload`, where they are always sent on create): an update for
|
|
229
|
+
* a task whose orchestrator record carries no who-measured identity (a
|
|
230
|
+
* legacy record, written before this feature existed) omits them entirely,
|
|
231
|
+
* so a re-sync by a DIFFERENT process never overwrites a row's original
|
|
232
|
+
* identity with its own. See {@link buildTaskEntryUpdatePayload}.
|
|
233
|
+
*/
|
|
234
|
+
export type TaskEntryUpdatePayload = Omit<
|
|
235
|
+
TaskEntryPayload,
|
|
236
|
+
"client" | "project" | "task" | "legacy_client_label" | "agent" | "agent_version" | "plugin" | "plugin_version"
|
|
237
|
+
> & {
|
|
238
|
+
agent?: string;
|
|
239
|
+
agent_version?: string;
|
|
240
|
+
plugin?: string;
|
|
241
|
+
plugin_version?: string;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* The who-measured identity (`agent`/`agentVersion`/`plugin`/`pluginVersion`)
|
|
246
|
+
* for a task's payload: the orchestrator record's own fields, taken as a
|
|
247
|
+
* unit, when it carries an `agent` — a missing version on the record is
|
|
248
|
+
* omitted, never backfilled from `ctx` — otherwise `ctx`'s identity (the
|
|
249
|
+
* syncing process's own), exactly as before this feature existed. See
|
|
250
|
+
* `domain/work-record.ts#WorkRecordMetadata.agent`'s doc comment.
|
|
251
|
+
*/
|
|
252
|
+
function resolveTaskIdentity(
|
|
253
|
+
task: TaskView,
|
|
254
|
+
ctx: HubEntryContext,
|
|
255
|
+
): { agent: string; agentVersion?: string; plugin: string; pluginVersion?: string } {
|
|
256
|
+
const orchestrator = task.orchestrator;
|
|
257
|
+
if (orchestrator.agent !== undefined) {
|
|
258
|
+
// The record's four fields are taken as a unit. A record written by an
|
|
259
|
+
// integration that stamped `agent` but not `plugin` gets the syncing
|
|
260
|
+
// context's `plugin` ONLY on create, so the row is never blank; the
|
|
261
|
+
// update payload below never resends a plugin the record does not own.
|
|
262
|
+
return {
|
|
263
|
+
agent: orchestrator.agent,
|
|
264
|
+
agentVersion: orchestrator.agentVersion,
|
|
265
|
+
plugin: orchestrator.plugin ?? ctx.plugin,
|
|
266
|
+
pluginVersion: orchestrator.plugin !== undefined ? orchestrator.pluginVersion : undefined,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return { agent: ctx.agent, agentVersion: ctx.agentVersion, plugin: ctx.plugin, pluginVersion: ctx.pluginVersion };
|
|
270
|
+
}
|
|
223
271
|
|
|
224
272
|
/** Build the full `task_entries` payload for a **create** request — every field, including assignment. */
|
|
225
273
|
export function buildTaskEntryCreatePayload(task: TaskView, ctx: HubEntryContext): TaskEntryPayload {
|
|
226
274
|
const assignment = resolveTaskAssignment(task, ctx.clients, ctx.projects, ctx.tasks);
|
|
275
|
+
const identity = resolveTaskIdentity(task, ctx);
|
|
227
276
|
return {
|
|
228
277
|
task_id: task.id,
|
|
229
278
|
client: assignment.clientId,
|
|
@@ -253,11 +302,11 @@ export function buildTaskEntryCreatePayload(task: TaskView, ctx: HubEntryContext
|
|
|
253
302
|
legacy_client_label: assignment.legacyClientLabel,
|
|
254
303
|
repo_project: task.project,
|
|
255
304
|
schema: task.orchestrator.schema,
|
|
256
|
-
agent:
|
|
257
|
-
...(
|
|
305
|
+
agent: identity.agent,
|
|
306
|
+
...(identity.agentVersion !== undefined ? { agent_version: identity.agentVersion } : {}),
|
|
258
307
|
...(task.sessionDir !== undefined ? { session_dir: task.sessionDir } : {}),
|
|
259
|
-
plugin:
|
|
260
|
-
...(
|
|
308
|
+
plugin: identity.plugin,
|
|
309
|
+
...(identity.pluginVersion !== undefined ? { plugin_version: identity.pluginVersion } : {}),
|
|
261
310
|
waiting_quality: computeWaitingQuality(),
|
|
262
311
|
cost_quality: computeCostQuality(task),
|
|
263
312
|
subagent_linkage: computeSubagentLinkage(task),
|
|
@@ -269,10 +318,40 @@ export function buildTaskEntryCreatePayload(task: TaskView, ctx: HubEntryContext
|
|
|
269
318
|
* fields only — never `client`, `project`, `task` or `legacy_client_label`,
|
|
270
319
|
* so a re-sync can never undo a reassignment made in the web. See the
|
|
271
320
|
* module docs' CRITICAL rule.
|
|
321
|
+
*
|
|
322
|
+
* `agent`/`agent_version`/`plugin`/`plugin_version` are included ONLY when
|
|
323
|
+
* the orchestrator record itself carries a who-measured `agent` — otherwise
|
|
324
|
+
* they are OMITTED entirely (never sent as `ctx`'s own identity), so a
|
|
325
|
+
* re-sync of a legacy record by a different process never overwrites the
|
|
326
|
+
* row's original identity in the hub. See `domain/work-record.ts`'s
|
|
327
|
+
* "Measurement rules" and {@link resolveTaskIdentity}.
|
|
272
328
|
*/
|
|
273
329
|
export function buildTaskEntryUpdatePayload(task: TaskView, ctx: HubEntryContext): TaskEntryUpdatePayload {
|
|
274
|
-
const {
|
|
275
|
-
|
|
330
|
+
const {
|
|
331
|
+
client: _client,
|
|
332
|
+
project: _project,
|
|
333
|
+
task: _task,
|
|
334
|
+
legacy_client_label: _legacy,
|
|
335
|
+
agent,
|
|
336
|
+
agent_version,
|
|
337
|
+
plugin,
|
|
338
|
+
plugin_version,
|
|
339
|
+
...rest
|
|
340
|
+
} = buildTaskEntryCreatePayload(task, ctx);
|
|
341
|
+
|
|
342
|
+
if (task.orchestrator.agent === undefined) return rest;
|
|
343
|
+
|
|
344
|
+
// `plugin`/`plugin_version` are resent only when the record itself carries
|
|
345
|
+
// them; a record with `agent` but no `plugin` must never have the syncing
|
|
346
|
+
// process's plugin written over the row's original one.
|
|
347
|
+
const recordHasPlugin = task.orchestrator.plugin !== undefined;
|
|
348
|
+
return {
|
|
349
|
+
...rest,
|
|
350
|
+
agent,
|
|
351
|
+
...(agent_version !== undefined ? { agent_version } : {}),
|
|
352
|
+
...(recordHasPlugin ? { plugin } : {}),
|
|
353
|
+
...(recordHasPlugin && plugin_version !== undefined ? { plugin_version } : {}),
|
|
354
|
+
};
|
|
276
355
|
}
|
|
277
356
|
|
|
278
357
|
/** One `work_records` row — raw per-`WorkRecord` detail, always `rollup: false`. */
|
package/src/domain/sync-plan.ts
CHANGED
|
@@ -134,6 +134,16 @@ export function computeTaskContentHash(task: TaskView): string {
|
|
|
134
134
|
// `undefined` is dropped by the serialiser, so a task that never knew
|
|
135
135
|
// its reasoning effort keeps the hash it had before this field existed.
|
|
136
136
|
thinkingLevel: task.orchestrator.thinkingLevel,
|
|
137
|
+
// A task gaining a who-measured identity
|
|
138
|
+
// (domain/hub-entry.ts#resolveTaskIdentity) must resync, since it
|
|
139
|
+
// changes which agent/plugin the row is attributed to; the version
|
|
140
|
+
// fields are left out on purpose so a version-only bump alone does not
|
|
141
|
+
// force a resync. The keys are added CONDITIONALLY: `stableStringify`
|
|
142
|
+
// renders an `undefined` value as `"agent":undefined`, so an
|
|
143
|
+
// unconditional key would change every legacy task's hash and force a
|
|
144
|
+
// full resync right after upgrading (see the golden-hash test).
|
|
145
|
+
...(task.orchestrator.agent !== undefined ? { agent: task.orchestrator.agent } : {}),
|
|
146
|
+
...(task.orchestrator.plugin !== undefined ? { plugin: task.orchestrator.plugin } : {}),
|
|
137
147
|
}),
|
|
138
148
|
);
|
|
139
149
|
}
|
|
@@ -201,6 +201,23 @@ export interface WorkRecordMetadata {
|
|
|
201
201
|
* (SUBAGENT-REQ-017). Never set on an `orchestrator` record.
|
|
202
202
|
*/
|
|
203
203
|
profile?: string;
|
|
204
|
+
/**
|
|
205
|
+
* Coding agent that MEASURED this record, lowercase slug (e.g. `"pi"`).
|
|
206
|
+
* Who measured, not who syncs — a different process (a standalone
|
|
207
|
+
* `kankaku` TUI, or a session for a different agent sharing the same
|
|
208
|
+
* `worklog.jsonl`) may later push this record to the hub, and must never
|
|
209
|
+
* overwrite this identity with its own. See kankaku-hub `docs/contract.md`
|
|
210
|
+
* "Agent and measurement quality" and `domain/hub-entry.ts`. Optional and
|
|
211
|
+
* additive: `WORK_RECORD_SCHEMA` is unchanged and an older record without
|
|
212
|
+
* it still validates.
|
|
213
|
+
*/
|
|
214
|
+
agent?: string;
|
|
215
|
+
/** The measuring agent's own version, when it could be determined without a hot-path cost. Never guessed — omitted rather than sent wrong. */
|
|
216
|
+
agentVersion?: string;
|
|
217
|
+
/** The integration that wrote this record, lowercase slug (e.g. `"kankaku"`). Same who-measured-not-who-syncs rule as {@link agent}. */
|
|
218
|
+
plugin?: string;
|
|
219
|
+
/** This integration's own version, from its `package.json`, read once. */
|
|
220
|
+
pluginVersion?: string;
|
|
204
221
|
}
|
|
205
222
|
|
|
206
223
|
export type WorkRecord = WorkRecordCore & WorkRecordMetadata;
|
|
@@ -294,6 +311,10 @@ export function isWorkRecord(value: unknown): value is WorkRecord {
|
|
|
294
311
|
(record["roleConfidence"] === undefined || record["roleConfidence"] === "uncertain") &&
|
|
295
312
|
(record["orchestratorRef"] === undefined || isOrchestratorRef(record["orchestratorRef"])) &&
|
|
296
313
|
(record["costObserved"] === undefined || record["costObserved"] === true) &&
|
|
297
|
-
(record["profile"] === undefined || typeof record["profile"] === "string")
|
|
314
|
+
(record["profile"] === undefined || typeof record["profile"] === "string") &&
|
|
315
|
+
(record["agent"] === undefined || typeof record["agent"] === "string") &&
|
|
316
|
+
(record["agentVersion"] === undefined || typeof record["agentVersion"] === "string") &&
|
|
317
|
+
(record["plugin"] === undefined || typeof record["plugin"] === "string") &&
|
|
318
|
+
(record["pluginVersion"] === undefined || typeof record["pluginVersion"] === "string")
|
|
298
319
|
);
|
|
299
320
|
}
|
package/src/hub/index.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* for which ones and why.
|
|
8
8
|
*/
|
|
9
9
|
export * from "../adapters/cached-catalog.ts";
|
|
10
|
+
export * from "../adapters/export-writer.ts";
|
|
10
11
|
export * from "../adapters/file-modes.ts";
|
|
12
|
+
export * from "../adapters/hub-actions.ts";
|
|
11
13
|
export * from "../adapters/hub-credentials.ts";
|
|
12
14
|
export * from "../adapters/jsonl-work-log.ts";
|
|
13
15
|
export * from "../adapters/kankaku-dir.ts";
|
|
@@ -15,5 +17,9 @@ export * from "../adapters/lazy-jsonl-work-log.ts";
|
|
|
15
17
|
export * from "../adapters/pocketbase-catalog.ts";
|
|
16
18
|
export * from "../adapters/pocketbase-client.ts";
|
|
17
19
|
export * from "../adapters/pocketbase-sink.ts";
|
|
20
|
+
export * from "../adapters/project-config.ts";
|
|
21
|
+
export * from "../adapters/report-data.ts";
|
|
22
|
+
export * from "../adapters/report.ts";
|
|
23
|
+
export * from "../adapters/report-views.ts";
|
|
18
24
|
export * from "../adapters/sync-runner.ts";
|
|
19
25
|
export * from "../adapters/sync-state-store.ts";
|