@oharness/engine 0.1.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/dist/agent/agent.d.ts +196 -0
- package/dist/agent/agent.js +758 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/compaction.d.ts +68 -0
- package/dist/agent/compaction.js +179 -0
- package/dist/agent/compaction.js.map +1 -0
- package/dist/agent/hooks.d.ts +77 -0
- package/dist/agent/hooks.js +152 -0
- package/dist/agent/hooks.js.map +1 -0
- package/dist/agent/memory.d.ts +45 -0
- package/dist/agent/memory.js +147 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/overflow.d.ts +35 -0
- package/dist/agent/overflow.js +69 -0
- package/dist/agent/overflow.js.map +1 -0
- package/dist/agent/permissions.d.ts +181 -0
- package/dist/agent/permissions.js +289 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/prompt.d.ts +25 -0
- package/dist/agent/prompt.js +63 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/session.d.ts +108 -0
- package/dist/agent/session.js +231 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/agent/settings.d.ts +37 -0
- package/dist/agent/settings.js +113 -0
- package/dist/agent/settings.js.map +1 -0
- package/dist/agent/skills.d.ts +58 -0
- package/dist/agent/skills.js +225 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/store.d.ts +308 -0
- package/dist/agent/store.js +596 -0
- package/dist/agent/store.js.map +1 -0
- package/dist/agent/subagent.d.ts +44 -0
- package/dist/agent/subagent.js +138 -0
- package/dist/agent/subagent.js.map +1 -0
- package/dist/agent/titles.d.ts +8 -0
- package/dist/agent/titles.js +23 -0
- package/dist/agent/titles.js.map +1 -0
- package/dist/agent/workspace.d.ts +60 -0
- package/dist/agent/workspace.js +156 -0
- package/dist/agent/workspace.js.map +1 -0
- package/dist/artifacts/publish.d.ts +94 -0
- package/dist/artifacts/publish.js +104 -0
- package/dist/artifacts/publish.js.map +1 -0
- package/dist/artifacts/store.d.ts +324 -0
- package/dist/artifacts/store.js +500 -0
- package/dist/artifacts/store.js.map +1 -0
- package/dist/auth/index.d.ts +13 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/manager.d.ts +83 -0
- package/dist/auth/manager.js +266 -0
- package/dist/auth/manager.js.map +1 -0
- package/dist/auth/oauth.d.ts +83 -0
- package/dist/auth/oauth.js +327 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/providers/account.d.ts +59 -0
- package/dist/auth/providers/account.js +282 -0
- package/dist/auth/providers/account.js.map +1 -0
- package/dist/auth/providers/anthropic.d.ts +24 -0
- package/dist/auth/providers/anthropic.js +209 -0
- package/dist/auth/providers/anthropic.js.map +1 -0
- package/dist/auth/providers/generic.d.ts +57 -0
- package/dist/auth/providers/generic.js +155 -0
- package/dist/auth/providers/generic.js.map +1 -0
- package/dist/auth/providers/official.d.ts +3 -0
- package/dist/auth/providers/official.js +90 -0
- package/dist/auth/providers/official.js.map +1 -0
- package/dist/auth/providers/ottoport.d.ts +3 -0
- package/dist/auth/providers/ottoport.js +60 -0
- package/dist/auth/providers/ottoport.js.map +1 -0
- package/dist/auth/store.d.ts +22 -0
- package/dist/auth/store.js +138 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/auth/types.d.ts +167 -0
- package/dist/auth/types.js +16 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/config.d.ts +197 -0
- package/dist/config.js +195 -0
- package/dist/config.js.map +1 -0
- package/dist/core/errors.d.ts +46 -0
- package/dist/core/errors.js +83 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/tokens.d.ts +12 -0
- package/dist/core/tokens.js +56 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/types.d.ts +91 -0
- package/dist/core/types.js +49 -0
- package/dist/core/types.js.map +1 -0
- package/dist/harness.d.ts +302 -0
- package/dist/harness.js +695 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +55 -0
- package/dist/mcp/client.js +199 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +77 -0
- package/dist/mcp/manager.js +325 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/oauth.d.ts +63 -0
- package/dist/mcp/oauth.js +302 -0
- package/dist/mcp/oauth.js.map +1 -0
- package/dist/mcp/protocol.d.ts +130 -0
- package/dist/mcp/protocol.js +14 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/registry.d.ts +52 -0
- package/dist/mcp/registry.js +100 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/registry.json +293 -0
- package/dist/mcp/secrets.d.ts +20 -0
- package/dist/mcp/secrets.js +75 -0
- package/dist/mcp/secrets.js.map +1 -0
- package/dist/mcp/transport.d.ts +51 -0
- package/dist/mcp/transport.js +158 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/paths.d.ts +37 -0
- package/dist/paths.js +63 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugins.d.ts +55 -0
- package/dist/plugins.js +201 -0
- package/dist/plugins.js.map +1 -0
- package/dist/providers/builtin.d.ts +23 -0
- package/dist/providers/builtin.js +141 -0
- package/dist/providers/builtin.js.map +1 -0
- package/dist/providers/catalog.d.ts +129 -0
- package/dist/providers/catalog.js +254 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/catalog.json +472 -0
- package/dist/providers/discovery.d.ts +16 -0
- package/dist/providers/discovery.js +161 -0
- package/dist/providers/discovery.js.map +1 -0
- package/dist/providers/http.d.ts +24 -0
- package/dist/providers/http.js +139 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/providers/index.d.ts +10 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/piai.d.ts +124 -0
- package/dist/providers/piai.js +551 -0
- package/dist/providers/piai.js.map +1 -0
- package/dist/providers/registry.d.ts +65 -0
- package/dist/providers/registry.js +195 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/resilient.d.ts +46 -0
- package/dist/providers/resilient.js +117 -0
- package/dist/providers/resilient.js.map +1 -0
- package/dist/providers/types.d.ts +182 -0
- package/dist/providers/types.js +50 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/schedule/cron.d.ts +35 -0
- package/dist/schedule/cron.js +125 -0
- package/dist/schedule/cron.js.map +1 -0
- package/dist/schedule/scheduler.d.ts +87 -0
- package/dist/schedule/scheduler.js +237 -0
- package/dist/schedule/scheduler.js.map +1 -0
- package/dist/storage/kv.d.ts +56 -0
- package/dist/storage/kv.js +173 -0
- package/dist/storage/kv.js.map +1 -0
- package/dist/storage/migrate.d.ts +11 -0
- package/dist/storage/migrate.js +93 -0
- package/dist/storage/migrate.js.map +1 -0
- package/dist/storage/project.d.ts +9 -0
- package/dist/storage/project.js +57 -0
- package/dist/storage/project.js.map +1 -0
- package/dist/storage/records.d.ts +32 -0
- package/dist/storage/records.js +48 -0
- package/dist/storage/records.js.map +1 -0
- package/dist/sync/client.d.ts +79 -0
- package/dist/sync/client.js +118 -0
- package/dist/sync/client.js.map +1 -0
- package/dist/sync/mirror.d.ts +85 -0
- package/dist/sync/mirror.js +389 -0
- package/dist/sync/mirror.js.map +1 -0
- package/dist/sync/protocol.d.ts +67 -0
- package/dist/sync/protocol.js +16 -0
- package/dist/sync/protocol.js.map +1 -0
- package/dist/sync/settings.d.ts +56 -0
- package/dist/sync/settings.js +60 -0
- package/dist/sync/settings.js.map +1 -0
- package/dist/tools/builtin/artifact.d.ts +16 -0
- package/dist/tools/builtin/artifact.js +134 -0
- package/dist/tools/builtin/artifact.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts +3 -0
- package/dist/tools/builtin/bash.js +142 -0
- package/dist/tools/builtin/bash.js.map +1 -0
- package/dist/tools/builtin/fs.d.ts +19 -0
- package/dist/tools/builtin/fs.js +280 -0
- package/dist/tools/builtin/fs.js.map +1 -0
- package/dist/tools/builtin/index.d.ts +22 -0
- package/dist/tools/builtin/index.js +42 -0
- package/dist/tools/builtin/index.js.map +1 -0
- package/dist/tools/builtin/mcp-resource.d.ts +3 -0
- package/dist/tools/builtin/mcp-resource.js +220 -0
- package/dist/tools/builtin/mcp-resource.js.map +1 -0
- package/dist/tools/builtin/memory.d.ts +10 -0
- package/dist/tools/builtin/memory.js +76 -0
- package/dist/tools/builtin/memory.js.map +1 -0
- package/dist/tools/builtin/recall.d.ts +13 -0
- package/dist/tools/builtin/recall.js +163 -0
- package/dist/tools/builtin/recall.js.map +1 -0
- package/dist/tools/builtin/search.d.ts +3 -0
- package/dist/tools/builtin/search.js +240 -0
- package/dist/tools/builtin/search.js.map +1 -0
- package/dist/tools/builtin/skill.d.ts +10 -0
- package/dist/tools/builtin/skill.js +46 -0
- package/dist/tools/builtin/skill.js.map +1 -0
- package/dist/tools/builtin/task.d.ts +9 -0
- package/dist/tools/builtin/task.js +68 -0
- package/dist/tools/builtin/task.js.map +1 -0
- package/dist/tools/builtin/todo.d.ts +20 -0
- package/dist/tools/builtin/todo.js +63 -0
- package/dist/tools/builtin/todo.js.map +1 -0
- package/dist/tools/define.d.ts +19 -0
- package/dist/tools/define.js +39 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.js +101 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +112 -0
- package/dist/tools/types.js +22 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/util/id.d.ts +9 -0
- package/dist/util/id.js +19 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/json.d.ts +25 -0
- package/dist/util/json.js +100 -0
- package/dist/util/json.js.map +1 -0
- package/dist/util/jwt.d.ts +74 -0
- package/dist/util/jwt.js +177 -0
- package/dist/util/jwt.js.map +1 -0
- package/dist/util/logger.d.ts +13 -0
- package/dist/util/logger.js +59 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/queue.d.ts +26 -0
- package/dist/util/queue.js +106 -0
- package/dist/util/queue.js.map +1 -0
- package/dist/util/schema.d.ts +17 -0
- package/dist/util/schema.js +98 -0
- package/dist/util/schema.js.map +1 -0
- package/dist/util/shell.d.ts +20 -0
- package/dist/util/shell.js +24 -0
- package/dist/util/shell.js.map +1 -0
- package/official.json +4 -0
- package/package.json +38 -0
- package/skills/artifact-authoring/SKILL.md +81 -0
- package/skills/canvas/SKILL.md +85 -0
- package/skills/skill-authoring/SKILL.md +85 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/sync/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { SessionStore } from "../agent/store.ts";
|
|
2
|
+
import { JsonStore } from "../storage/kv.ts";
|
|
3
|
+
import { SyncClient } from "./client.ts";
|
|
4
|
+
export interface MirrorOptions {
|
|
5
|
+
store: SessionStore;
|
|
6
|
+
client: SyncClient;
|
|
7
|
+
/** The feed this mirror is bound to — a repository, not a path. */
|
|
8
|
+
projectId: string;
|
|
9
|
+
/** Where the cursor is kept. Defaults to the store's own root. */
|
|
10
|
+
state?: JsonStore;
|
|
11
|
+
/** Told about failures. Sync problems are worth a log line, never a throw. */
|
|
12
|
+
onError?: (message: string) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Seconds to hold a poll open, capped by the protocol.
|
|
15
|
+
*
|
|
16
|
+
* The maximum is the right answer for a harness someone is working in, and
|
|
17
|
+
* the wrong one for anything short-lived: a held connection keeps the
|
|
18
|
+
* process alive, so a scheduled run or a test would sit waiting on a server
|
|
19
|
+
* that has nothing to say.
|
|
20
|
+
*/
|
|
21
|
+
pollSeconds?: number;
|
|
22
|
+
/** Overridable for tests, which should not wait in real seconds. */
|
|
23
|
+
timers?: {
|
|
24
|
+
setTimeout: (fn: () => void, ms: number) => unknown;
|
|
25
|
+
clearTimeout: (handle: unknown) => void;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare class SessionMirror {
|
|
29
|
+
private readonly store;
|
|
30
|
+
private readonly client;
|
|
31
|
+
private readonly projectId;
|
|
32
|
+
private readonly state;
|
|
33
|
+
private readonly onError;
|
|
34
|
+
private readonly pollSeconds;
|
|
35
|
+
private readonly timers;
|
|
36
|
+
private unwatch?;
|
|
37
|
+
private aborter?;
|
|
38
|
+
private pushTimer?;
|
|
39
|
+
private pulling?;
|
|
40
|
+
private running;
|
|
41
|
+
/** Sessions with local writes not known to be pushed. */
|
|
42
|
+
private readonly dirty;
|
|
43
|
+
/** Deletions waiting to travel, kept because the metadata is already gone. */
|
|
44
|
+
private readonly tombstones;
|
|
45
|
+
private held?;
|
|
46
|
+
constructor(opts: MirrorOptions);
|
|
47
|
+
get active(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Begin mirroring.
|
|
50
|
+
*
|
|
51
|
+
* Subscribing comes before the first pull so a write that lands during the
|
|
52
|
+
* opening round trip is not missed — it would otherwise sit unpushed until
|
|
53
|
+
* something else in that session changed, which for a finished session is
|
|
54
|
+
* never.
|
|
55
|
+
*/
|
|
56
|
+
start(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Stop, and stay stopped.
|
|
59
|
+
*
|
|
60
|
+
* The in-flight long poll is aborted rather than waited out: a user who
|
|
61
|
+
* switches sync off should not have a connection to the server outliving the
|
|
62
|
+
* decision by up to thirty seconds.
|
|
63
|
+
*/
|
|
64
|
+
stop(): void;
|
|
65
|
+
/** Push whatever is pending now, rather than on the debounce. */
|
|
66
|
+
flush(): Promise<void>;
|
|
67
|
+
private onChange;
|
|
68
|
+
private schedulePush;
|
|
69
|
+
/** Offer every session in this project, for a device that has never pushed. */
|
|
70
|
+
private sweep;
|
|
71
|
+
private push;
|
|
72
|
+
/**
|
|
73
|
+
* Read the feed forward, forever.
|
|
74
|
+
*
|
|
75
|
+
* A long poll returns either when something arrives or when the server gives
|
|
76
|
+
* up holding it, so the loop is not a poll with a delay in it — the delay
|
|
77
|
+
* only appears after a failure.
|
|
78
|
+
*/
|
|
79
|
+
private loop;
|
|
80
|
+
private pull;
|
|
81
|
+
private report;
|
|
82
|
+
private wait;
|
|
83
|
+
private read;
|
|
84
|
+
private write;
|
|
85
|
+
}
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { asArtifactRevision } from "../artifacts/store.js";
|
|
2
|
+
import { JsonStore } from "../storage/kv.js";
|
|
3
|
+
import { errorMessage } from "../core/errors.js";
|
|
4
|
+
import { SyncClient, SyncHttpError, chunk } from "./client.js";
|
|
5
|
+
import { MAX_WAIT_SECONDS } from "./protocol.js";
|
|
6
|
+
/**
|
|
7
|
+
* The line between the session store and a sync server.
|
|
8
|
+
*
|
|
9
|
+
* One mirror serves one project, because a feed is scoped to one and a cursor
|
|
10
|
+
* into someone else's is meaningless. It pushes what the store reports and
|
|
11
|
+
* pulls in a loop, and it is allowed to fail at every step: the local store is
|
|
12
|
+
* complete on its own, so a mirror that cannot reach anything must leave the
|
|
13
|
+
* harness working exactly as it would with sync switched off. Nothing here
|
|
14
|
+
* throws outward, and nothing here is awaited by a write path.
|
|
15
|
+
*
|
|
16
|
+
* Two asymmetries worth knowing, both of them the protocol's doing:
|
|
17
|
+
*
|
|
18
|
+
* Pushing again is free. The server deduplicates on record id, so the
|
|
19
|
+
* bookkeeping below only has to be approximately right — it exists to keep
|
|
20
|
+
* pushes small, not to keep them correct. On any doubt it re-sends.
|
|
21
|
+
*
|
|
22
|
+
* Pulling twice is free for the same reason, one layer down: `mergeRecords`
|
|
23
|
+
* drops what the log already holds. So a cursor lost to a crash costs
|
|
24
|
+
* bandwidth and nothing else.
|
|
25
|
+
*/
|
|
26
|
+
/** How long to gather writes before pushing. A turn writes many records. */
|
|
27
|
+
const PUSH_DEBOUNCE_MS = 750;
|
|
28
|
+
/** Backoff after a failure, doubling to the ceiling. */
|
|
29
|
+
const RETRY_FLOOR_MS = 2_000;
|
|
30
|
+
const RETRY_CEILING_MS = 60_000;
|
|
31
|
+
export class SessionMirror {
|
|
32
|
+
store;
|
|
33
|
+
client;
|
|
34
|
+
projectId;
|
|
35
|
+
state;
|
|
36
|
+
onError;
|
|
37
|
+
pollSeconds;
|
|
38
|
+
timers;
|
|
39
|
+
unwatch;
|
|
40
|
+
aborter;
|
|
41
|
+
pushTimer;
|
|
42
|
+
pulling;
|
|
43
|
+
running = false;
|
|
44
|
+
/** Sessions with local writes not known to be pushed. */
|
|
45
|
+
dirty = new Set();
|
|
46
|
+
/** Deletions waiting to travel, kept because the metadata is already gone. */
|
|
47
|
+
tombstones = new Map();
|
|
48
|
+
held;
|
|
49
|
+
constructor(opts) {
|
|
50
|
+
this.store = opts.store;
|
|
51
|
+
this.client = opts.client;
|
|
52
|
+
this.projectId = opts.projectId;
|
|
53
|
+
this.state = opts.state ?? new JsonStore(opts.store.root);
|
|
54
|
+
this.onError = opts.onError ?? (() => { });
|
|
55
|
+
this.pollSeconds = Math.min(opts.pollSeconds ?? MAX_WAIT_SECONDS, MAX_WAIT_SECONDS);
|
|
56
|
+
this.timers = opts.timers ?? {
|
|
57
|
+
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
58
|
+
clearTimeout: (handle) => clearTimeout(handle),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
get active() {
|
|
62
|
+
return this.running;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Begin mirroring.
|
|
66
|
+
*
|
|
67
|
+
* Subscribing comes before the first pull so a write that lands during the
|
|
68
|
+
* opening round trip is not missed — it would otherwise sit unpushed until
|
|
69
|
+
* something else in that session changed, which for a finished session is
|
|
70
|
+
* never.
|
|
71
|
+
*/
|
|
72
|
+
start() {
|
|
73
|
+
if (this.running)
|
|
74
|
+
return;
|
|
75
|
+
this.running = true;
|
|
76
|
+
this.aborter = new AbortController();
|
|
77
|
+
this.unwatch = this.store.watch((change) => this.onChange(change));
|
|
78
|
+
// Everything already on disk may predate this device having a server at
|
|
79
|
+
// all, so the first pass offers the whole project rather than only what
|
|
80
|
+
// changes from here.
|
|
81
|
+
void this.sweep();
|
|
82
|
+
void this.loop();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Stop, and stay stopped.
|
|
86
|
+
*
|
|
87
|
+
* The in-flight long poll is aborted rather than waited out: a user who
|
|
88
|
+
* switches sync off should not have a connection to the server outliving the
|
|
89
|
+
* decision by up to thirty seconds.
|
|
90
|
+
*/
|
|
91
|
+
stop() {
|
|
92
|
+
if (!this.running)
|
|
93
|
+
return;
|
|
94
|
+
this.running = false;
|
|
95
|
+
this.unwatch?.();
|
|
96
|
+
this.unwatch = undefined;
|
|
97
|
+
if (this.pushTimer !== undefined) {
|
|
98
|
+
this.timers.clearTimeout(this.pushTimer);
|
|
99
|
+
this.pushTimer = undefined;
|
|
100
|
+
}
|
|
101
|
+
this.aborter?.abort();
|
|
102
|
+
this.aborter = undefined;
|
|
103
|
+
}
|
|
104
|
+
/** Push whatever is pending now, rather than on the debounce. */
|
|
105
|
+
async flush() {
|
|
106
|
+
if (this.pushTimer !== undefined) {
|
|
107
|
+
this.timers.clearTimeout(this.pushTimer);
|
|
108
|
+
this.pushTimer = undefined;
|
|
109
|
+
}
|
|
110
|
+
await this.push();
|
|
111
|
+
}
|
|
112
|
+
onChange(change) {
|
|
113
|
+
if (change.projectId !== this.projectId)
|
|
114
|
+
return;
|
|
115
|
+
if (change.kind === "delete") {
|
|
116
|
+
this.tombstones.set(change.id, change.meta);
|
|
117
|
+
this.dirty.delete(change.id);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.dirty.add(change.id);
|
|
121
|
+
}
|
|
122
|
+
this.schedulePush();
|
|
123
|
+
}
|
|
124
|
+
schedulePush() {
|
|
125
|
+
if (!this.running || this.pushTimer !== undefined)
|
|
126
|
+
return;
|
|
127
|
+
this.pushTimer = this.timers.setTimeout(() => {
|
|
128
|
+
this.pushTimer = undefined;
|
|
129
|
+
void this.push();
|
|
130
|
+
}, PUSH_DEBOUNCE_MS);
|
|
131
|
+
}
|
|
132
|
+
/** Offer every session in this project, for a device that has never pushed. */
|
|
133
|
+
async sweep() {
|
|
134
|
+
try {
|
|
135
|
+
const sessions = await this.store.list(Number.MAX_SAFE_INTEGER, {
|
|
136
|
+
projectId: this.projectId,
|
|
137
|
+
});
|
|
138
|
+
for (const meta of sessions)
|
|
139
|
+
this.dirty.add(meta.id);
|
|
140
|
+
if (sessions.length > 0)
|
|
141
|
+
this.schedulePush();
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
this.onError(`sync sweep failed: ${errorMessage(err)}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async push() {
|
|
148
|
+
if (!this.running)
|
|
149
|
+
return;
|
|
150
|
+
const ids = [...this.dirty];
|
|
151
|
+
const graves = [...this.tombstones.entries()];
|
|
152
|
+
if (ids.length === 0 && graves.length === 0)
|
|
153
|
+
return;
|
|
154
|
+
// Cleared before the work, not after: a write that lands mid-push marks the
|
|
155
|
+
// session dirty again and earns its own round rather than being folded into
|
|
156
|
+
// one whose records were already read.
|
|
157
|
+
this.dirty.clear();
|
|
158
|
+
this.tombstones.clear();
|
|
159
|
+
const state = await this.read();
|
|
160
|
+
const records = [];
|
|
161
|
+
const sessions = [];
|
|
162
|
+
try {
|
|
163
|
+
for (const id of ids) {
|
|
164
|
+
const meta = await this.store.readMeta(id);
|
|
165
|
+
if (!meta)
|
|
166
|
+
continue;
|
|
167
|
+
const from = state.pushed[id] ?? 0;
|
|
168
|
+
const pending = (await this.store.recordsOf(id)).filter((record) => record.seq > from);
|
|
169
|
+
for (const record of pending)
|
|
170
|
+
records.push(toWire(id, record));
|
|
171
|
+
// Artifact revisions ride the same lane and the same watermark. They
|
|
172
|
+
// are not messages, so they travel in an envelope the reader can tell
|
|
173
|
+
// apart, and a client that predates them skips what it cannot read
|
|
174
|
+
// rather than mistaking a revision for a turn.
|
|
175
|
+
const revisions = (await this.store.artifactRevisions(id)).filter((revision) => (revision.seq ?? 0) > from);
|
|
176
|
+
for (const revision of revisions)
|
|
177
|
+
records.push(artifactToWire(id, revision));
|
|
178
|
+
sessions.push({
|
|
179
|
+
id,
|
|
180
|
+
gen: meta.gen ?? 0,
|
|
181
|
+
updatedAt: meta.updatedAt,
|
|
182
|
+
body: meta,
|
|
183
|
+
});
|
|
184
|
+
state.pushed[id] = Math.max(from, ...pending.map((record) => record.seq), ...revisions.map((revision) => revision.seq ?? 0), from);
|
|
185
|
+
}
|
|
186
|
+
for (const [id, meta] of graves) {
|
|
187
|
+
sessions.push({ id, gen: meta.gen ?? 0, updatedAt: meta.updatedAt, deleted: true });
|
|
188
|
+
delete state.pushed[id];
|
|
189
|
+
}
|
|
190
|
+
// Batched to the protocol's cap. A first sync of a long project is many
|
|
191
|
+
// more records than one push may carry, and the server refuses an
|
|
192
|
+
// oversized batch outright rather than taking half of it.
|
|
193
|
+
const recordBatches = chunk(records);
|
|
194
|
+
const sessionBatches = chunk(sessions);
|
|
195
|
+
const rounds = Math.max(recordBatches.length, sessionBatches.length, 1);
|
|
196
|
+
for (let round = 0; round < rounds; round++) {
|
|
197
|
+
await this.client.push(this.projectId, recordBatches[round] ?? [], sessionBatches[round] ?? [], this.aborter?.signal);
|
|
198
|
+
}
|
|
199
|
+
await this.write(state);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
// Put them back. The next change, or the next loop turn, tries again.
|
|
203
|
+
for (const id of ids)
|
|
204
|
+
this.dirty.add(id);
|
|
205
|
+
for (const [id, meta] of graves)
|
|
206
|
+
this.tombstones.set(id, meta);
|
|
207
|
+
this.report(err, "push");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Read the feed forward, forever.
|
|
212
|
+
*
|
|
213
|
+
* A long poll returns either when something arrives or when the server gives
|
|
214
|
+
* up holding it, so the loop is not a poll with a delay in it — the delay
|
|
215
|
+
* only appears after a failure.
|
|
216
|
+
*/
|
|
217
|
+
async loop() {
|
|
218
|
+
if (this.pulling)
|
|
219
|
+
return this.pulling;
|
|
220
|
+
const run = (async () => {
|
|
221
|
+
let backoff = RETRY_FLOOR_MS;
|
|
222
|
+
while (this.running) {
|
|
223
|
+
try {
|
|
224
|
+
const moved = await this.pull();
|
|
225
|
+
backoff = RETRY_FLOOR_MS;
|
|
226
|
+
// `more` means the page was cut short, so come straight back rather
|
|
227
|
+
// than holding a poll open while the rest is already waiting.
|
|
228
|
+
if (!moved)
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
if (!this.running)
|
|
233
|
+
break;
|
|
234
|
+
this.report(err, "pull");
|
|
235
|
+
await this.wait(backoff);
|
|
236
|
+
backoff = Math.min(backoff * 2, RETRY_CEILING_MS);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
})();
|
|
240
|
+
this.pulling = run.finally(() => {
|
|
241
|
+
this.pulling = undefined;
|
|
242
|
+
// A stop that landed while the poll was in flight leaves `running`
|
|
243
|
+
// false; a stop followed by a start leaves it true and wants the loop
|
|
244
|
+
// back, which the finished promise can no longer provide.
|
|
245
|
+
if (this.running)
|
|
246
|
+
void this.loop();
|
|
247
|
+
});
|
|
248
|
+
return this.pulling;
|
|
249
|
+
}
|
|
250
|
+
async pull() {
|
|
251
|
+
const state = await this.read();
|
|
252
|
+
const answer = await this.client.pull(this.projectId, state.cursor, {
|
|
253
|
+
wait: this.pollSeconds,
|
|
254
|
+
...(this.aborter?.signal ? { signal: this.aborter.signal } : {}),
|
|
255
|
+
});
|
|
256
|
+
for (const wire of answer.sessions) {
|
|
257
|
+
if (wire.deleted) {
|
|
258
|
+
await this.store.delete(wire.id).catch(() => false);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const meta = wire.body;
|
|
262
|
+
if (meta && typeof meta.id === "string") {
|
|
263
|
+
await this.store.mergeMeta({ ...meta, projectId: this.projectId }).catch(() => false);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Grouped as wire records rather than messages, because the two kinds are
|
|
267
|
+
// only told apart once the envelope is opened.
|
|
268
|
+
const bySession = new Map();
|
|
269
|
+
for (const wire of answer.records) {
|
|
270
|
+
const list = bySession.get(wire.session) ?? [];
|
|
271
|
+
list.push(wire);
|
|
272
|
+
bySession.set(wire.session, list);
|
|
273
|
+
}
|
|
274
|
+
for (const [id, incoming] of bySession) {
|
|
275
|
+
const messages = [];
|
|
276
|
+
const revisions = [];
|
|
277
|
+
for (const wire of incoming) {
|
|
278
|
+
const revision = artifactFromWire(wire);
|
|
279
|
+
if (revision)
|
|
280
|
+
revisions.push(revision);
|
|
281
|
+
else
|
|
282
|
+
messages.push(fromWire(wire));
|
|
283
|
+
}
|
|
284
|
+
await this.store.mergeRecords(id, messages).catch(() => 0);
|
|
285
|
+
await this.store.mergeArtifactRevisions(id, revisions).catch(() => 0);
|
|
286
|
+
}
|
|
287
|
+
if (answer.cursor !== state.cursor) {
|
|
288
|
+
state.cursor = answer.cursor;
|
|
289
|
+
await this.write(state);
|
|
290
|
+
}
|
|
291
|
+
return !answer.more;
|
|
292
|
+
}
|
|
293
|
+
report(err, what) {
|
|
294
|
+
// An aborted request is this mirror being stopped, not a problem.
|
|
295
|
+
if (err instanceof Error && err.name === "AbortError")
|
|
296
|
+
return;
|
|
297
|
+
if (!this.running)
|
|
298
|
+
return;
|
|
299
|
+
if (err instanceof SyncHttpError && err.status === 401) {
|
|
300
|
+
this.onError(`sync ${what}: the token was rejected; sign in again to resume`);
|
|
301
|
+
// A bad token will not fix itself, and retrying it every few seconds is
|
|
302
|
+
// how an expired credential becomes a log nobody reads.
|
|
303
|
+
this.stop();
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
this.onError(`sync ${what}: ${errorMessage(err)}`);
|
|
307
|
+
}
|
|
308
|
+
wait(ms) {
|
|
309
|
+
return new Promise((resolve) => {
|
|
310
|
+
this.timers.setTimeout(resolve, ms);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async read() {
|
|
314
|
+
if (this.held)
|
|
315
|
+
return this.held;
|
|
316
|
+
const stored = await this.state.read(["sync", this.projectId]);
|
|
317
|
+
this.held = {
|
|
318
|
+
cursor: typeof stored?.cursor === "number" ? stored.cursor : 0,
|
|
319
|
+
pushed: stored?.pushed && typeof stored.pushed === "object" ? { ...stored.pushed } : {},
|
|
320
|
+
};
|
|
321
|
+
return this.held;
|
|
322
|
+
}
|
|
323
|
+
async write(state) {
|
|
324
|
+
this.held = state;
|
|
325
|
+
await this.state.write(["sync", this.projectId], state).catch(() => { });
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* The envelope an artifact revision travels in.
|
|
330
|
+
*
|
|
331
|
+
* A record body is opaque to the server, so this needs no server change at
|
|
332
|
+
* all — but it does need to be unmistakable to a reader, because the same feed
|
|
333
|
+
* carries turns. `{ artifact: … }` is that mark: `asRecord` returns undefined
|
|
334
|
+
* for it, so a client that has never heard of artifacts skips the line instead
|
|
335
|
+
* of writing a malformed message into a transcript.
|
|
336
|
+
*/
|
|
337
|
+
const ARTIFACT_ENVELOPE = "artifact";
|
|
338
|
+
function artifactToWire(session, revision) {
|
|
339
|
+
return {
|
|
340
|
+
session,
|
|
341
|
+
id: revision.id ?? `art_${revision.artifact}_v${revision.version}`,
|
|
342
|
+
seq: revision.seq ?? 0,
|
|
343
|
+
device: revision.device ?? "unknown",
|
|
344
|
+
at: revision.at,
|
|
345
|
+
body: { [ARTIFACT_ENVELOPE]: revision },
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/** The revision inside an envelope, or undefined for anything else on the feed. */
|
|
349
|
+
function artifactFromWire(wire) {
|
|
350
|
+
const body = wire.body;
|
|
351
|
+
if (!body || typeof body !== "object")
|
|
352
|
+
return undefined;
|
|
353
|
+
const inner = body[ARTIFACT_ENVELOPE];
|
|
354
|
+
if (!inner)
|
|
355
|
+
return undefined;
|
|
356
|
+
const revision = asArtifactRevision(inner);
|
|
357
|
+
if (!revision)
|
|
358
|
+
return undefined;
|
|
359
|
+
// The wire fields win: they are what the other device recorded, and what
|
|
360
|
+
// dedupe on both sides is keyed on.
|
|
361
|
+
return { ...revision, id: wire.id, seq: wire.seq, device: wire.device };
|
|
362
|
+
}
|
|
363
|
+
function toWire(session, record) {
|
|
364
|
+
return {
|
|
365
|
+
session,
|
|
366
|
+
id: record.id,
|
|
367
|
+
seq: record.seq,
|
|
368
|
+
device: record.device,
|
|
369
|
+
at: record.at,
|
|
370
|
+
body: record.message,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* A record as it came back.
|
|
375
|
+
*
|
|
376
|
+
* The three identity fields are taken as given — that is the entire point of
|
|
377
|
+
* sending them — while `body` is trusted only as far as being an object,
|
|
378
|
+
* because the server never looked inside it and neither did anything between.
|
|
379
|
+
*/
|
|
380
|
+
function fromWire(wire) {
|
|
381
|
+
return {
|
|
382
|
+
id: wire.id,
|
|
383
|
+
seq: wire.seq,
|
|
384
|
+
device: wire.device,
|
|
385
|
+
at: wire.at,
|
|
386
|
+
message: wire.body,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=mirror.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/sync/mirror.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire between a harness and a sync server.
|
|
3
|
+
*
|
|
4
|
+
* The server never looks inside `body`. It stores an opaque blob against an
|
|
5
|
+
* id, a sequence and a cursor, and hands it back in order — which is what makes
|
|
6
|
+
* it safe to change the message format without redeploying anything, and what
|
|
7
|
+
* would make an end-to-end encrypted mode a client-side change alone.
|
|
8
|
+
*/
|
|
9
|
+
/** One transcript line, as it crosses the network. */
|
|
10
|
+
export interface WireRecord {
|
|
11
|
+
/** Session it belongs to. */
|
|
12
|
+
session: string;
|
|
13
|
+
/** Stable across devices — the server dedupes on it, so a retry is free. */
|
|
14
|
+
id: string;
|
|
15
|
+
/** Lamport counter within the session. Ordering, not arrival. */
|
|
16
|
+
seq: number;
|
|
17
|
+
device: string;
|
|
18
|
+
at: number;
|
|
19
|
+
/** The message. Opaque to the server. */
|
|
20
|
+
body: unknown;
|
|
21
|
+
}
|
|
22
|
+
/** Session metadata, resolved last-writer-wins rather than merged. */
|
|
23
|
+
export interface WireSession {
|
|
24
|
+
id: string;
|
|
25
|
+
/** Bumped by a rewrite (compaction). Higher generations win outright. */
|
|
26
|
+
gen: number;
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
/** Tombstone: a deletion has to travel, or the other device restores it. */
|
|
29
|
+
deleted?: boolean;
|
|
30
|
+
/** The metadata. Opaque to the server. */
|
|
31
|
+
body?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface PushRequest {
|
|
34
|
+
project: string;
|
|
35
|
+
device: string;
|
|
36
|
+
records?: WireRecord[];
|
|
37
|
+
sessions?: WireSession[];
|
|
38
|
+
/**
|
|
39
|
+
* Push into a team's feed rather than your own.
|
|
40
|
+
*
|
|
41
|
+
* Absent means the person, which is what a single-user install always wants
|
|
42
|
+
* and what every client sent before teams existed. Named, the server checks
|
|
43
|
+
* the token holds that team — a client cannot reach a feed by guessing an
|
|
44
|
+
* id, and there is no scope string that could be pointed at another person.
|
|
45
|
+
*/
|
|
46
|
+
team?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface PushResponse {
|
|
49
|
+
/** Where the caller now stands in this project's feed. */
|
|
50
|
+
cursor: number;
|
|
51
|
+
/** How many were new; the rest were already held. */
|
|
52
|
+
accepted: number;
|
|
53
|
+
}
|
|
54
|
+
export interface PullResponse {
|
|
55
|
+
cursor: number;
|
|
56
|
+
records: WireRecord[];
|
|
57
|
+
sessions: WireSession[];
|
|
58
|
+
/** True when the response was cut short by `limit` and more is waiting. */
|
|
59
|
+
more: boolean;
|
|
60
|
+
}
|
|
61
|
+
/** Refused rather than truncated: a silently dropped record is a lost turn. */
|
|
62
|
+
export declare const MAX_PUSH_RECORDS = 500;
|
|
63
|
+
export declare const MAX_BODY_BYTES: number;
|
|
64
|
+
/** Cap on one pull, so a first sync arrives in pages instead of one gulp. */
|
|
65
|
+
export declare const DEFAULT_PULL_LIMIT = 500;
|
|
66
|
+
/** Longest a long-poll is held open. Below any sensible proxy idle timeout. */
|
|
67
|
+
export declare const MAX_WAIT_SECONDS = 30;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire between a harness and a sync server.
|
|
3
|
+
*
|
|
4
|
+
* The server never looks inside `body`. It stores an opaque blob against an
|
|
5
|
+
* id, a sequence and a cursor, and hands it back in order — which is what makes
|
|
6
|
+
* it safe to change the message format without redeploying anything, and what
|
|
7
|
+
* would make an end-to-end encrypted mode a client-side change alone.
|
|
8
|
+
*/
|
|
9
|
+
/** Refused rather than truncated: a silently dropped record is a lost turn. */
|
|
10
|
+
export const MAX_PUSH_RECORDS = 500;
|
|
11
|
+
export const MAX_BODY_BYTES = 8 * 1024 * 1024;
|
|
12
|
+
/** Cap on one pull, so a first sync arrives in pages instead of one gulp. */
|
|
13
|
+
export const DEFAULT_PULL_LIMIT = 500;
|
|
14
|
+
/** Longest a long-poll is held open. Below any sensible proxy idle timeout. */
|
|
15
|
+
export const MAX_WAIT_SECONDS = 30;
|
|
16
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/sync/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA2DH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { SyncConfig } from "../config.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Whether to mirror, and where to.
|
|
4
|
+
*
|
|
5
|
+
* Sync is on by default, which is a decision about defaults rather than about
|
|
6
|
+
* consent: it cannot do anything until there is a destination and a token, and
|
|
7
|
+
* the token comes from signing in. So the honest reading of "on" is "as soon
|
|
8
|
+
* as you have an account", and a machine that never signs in never sends
|
|
9
|
+
* anything.
|
|
10
|
+
*
|
|
11
|
+
* Three ways to stop it, in the order they are checked. Each exists because
|
|
12
|
+
* the others do not cover its case:
|
|
13
|
+
*
|
|
14
|
+
* `OHARNESS_SYNC=0` one run, or every run in CI, without editing a file.
|
|
15
|
+
* `sync.enabled` this machine, or this repository (off only — see
|
|
16
|
+
* `mergeSync` on why a project cannot switch it on).
|
|
17
|
+
* `sync.exclude` one project, while everything else keeps mirroring.
|
|
18
|
+
*/
|
|
19
|
+
/** The official service. Overridden by `sync.url` for self-hosted servers. */
|
|
20
|
+
export declare const DEFAULT_SYNC_URL = "https://sync.oharness.ai";
|
|
21
|
+
export interface ResolvedSync {
|
|
22
|
+
url: string;
|
|
23
|
+
token: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SyncInputs {
|
|
26
|
+
config: SyncConfig | undefined;
|
|
27
|
+
/** The account credential, when signed in. Used when no token is configured. */
|
|
28
|
+
accountToken?: string | undefined;
|
|
29
|
+
env?: NodeJS.ProcessEnv;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Off, and why.
|
|
33
|
+
*
|
|
34
|
+
* The reason is carried rather than collapsed to a boolean so a UI can tell
|
|
35
|
+
* "you turned this off" from "you are not signed in" — two states that look
|
|
36
|
+
* identical from the outside and need opposite advice.
|
|
37
|
+
*/
|
|
38
|
+
export type SyncDecision = {
|
|
39
|
+
on: true;
|
|
40
|
+
target: ResolvedSync;
|
|
41
|
+
} | {
|
|
42
|
+
on: false;
|
|
43
|
+
reason: "disabled" | "no-credential";
|
|
44
|
+
};
|
|
45
|
+
export declare function resolveSync(inputs: SyncInputs): SyncDecision;
|
|
46
|
+
/**
|
|
47
|
+
* Whether one project is excluded.
|
|
48
|
+
*
|
|
49
|
+
* Matched against both the project id and the worktree path, because neither
|
|
50
|
+
* alone is what a person reaches for: the id is a commit hash nobody has
|
|
51
|
+
* memorised, and the path is what they would type.
|
|
52
|
+
*/
|
|
53
|
+
export declare function isExcluded(config: SyncConfig | undefined, project: {
|
|
54
|
+
id: string;
|
|
55
|
+
cwd?: string;
|
|
56
|
+
}): boolean;
|