@sentropic/h2a-runtime 0.81.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/account-pool.d.ts +168 -0
- package/dist/account-pool.d.ts.map +1 -0
- package/dist/account-pool.js +385 -0
- package/dist/account-pool.js.map +1 -0
- package/dist/agents-projection.d.ts +56 -0
- package/dist/agents-projection.d.ts.map +1 -0
- package/dist/agents-projection.js +82 -0
- package/dist/agents-projection.js.map +1 -0
- package/dist/attach.d.ts +75 -0
- package/dist/attach.d.ts.map +1 -0
- package/dist/attach.js +432 -0
- package/dist/attach.js.map +1 -0
- package/dist/auth-bundle.d.ts +21 -0
- package/dist/auth-bundle.d.ts.map +1 -0
- package/dist/auth-bundle.js +112 -0
- package/dist/auth-bundle.js.map +1 -0
- package/dist/auth-diagnostics.d.ts +18 -0
- package/dist/auth-diagnostics.d.ts.map +1 -0
- package/dist/auth-diagnostics.js +23 -0
- package/dist/auth-diagnostics.js.map +1 -0
- package/dist/auth-login.d.ts +9 -0
- package/dist/auth-login.d.ts.map +1 -0
- package/dist/auth-login.js +21 -0
- package/dist/auth-login.js.map +1 -0
- package/dist/auth-refresh.d.ts +32 -0
- package/dist/auth-refresh.d.ts.map +1 -0
- package/dist/auth-refresh.js +83 -0
- package/dist/auth-refresh.js.map +1 -0
- package/dist/auth-tools.d.ts +55 -0
- package/dist/auth-tools.d.ts.map +1 -0
- package/dist/auth-tools.js +163 -0
- package/dist/auth-tools.js.map +1 -0
- package/dist/browser-bridge-local.d.ts +27 -0
- package/dist/browser-bridge-local.d.ts.map +1 -0
- package/dist/browser-bridge-local.js +51 -0
- package/dist/browser-bridge-local.js.map +1 -0
- package/dist/browser.d.ts +53 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +61 -0
- package/dist/browser.js.map +1 -0
- package/dist/conductor-launch.d.ts +179 -0
- package/dist/conductor-launch.d.ts.map +1 -0
- package/dist/conductor-launch.js +414 -0
- package/dist/conductor-launch.js.map +1 -0
- package/dist/config.d.ts +182 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +334 -0
- package/dist/config.js.map +1 -0
- package/dist/conv-guard.d.ts +76 -0
- package/dist/conv-guard.d.ts.map +1 -0
- package/dist/conv-guard.js +131 -0
- package/dist/conv-guard.js.map +1 -0
- package/dist/convsync.d.ts +24 -0
- package/dist/convsync.d.ts.map +1 -0
- package/dist/convsync.js +108 -0
- package/dist/convsync.js.map +1 -0
- package/dist/cred-health.d.ts +96 -0
- package/dist/cred-health.d.ts.map +1 -0
- package/dist/cred-health.js +170 -0
- package/dist/cred-health.js.map +1 -0
- package/dist/delegate.d.ts +406 -0
- package/dist/delegate.d.ts.map +1 -0
- package/dist/delegate.js +739 -0
- package/dist/delegate.js.map +1 -0
- package/dist/enroll.d.ts +91 -0
- package/dist/enroll.d.ts.map +1 -0
- package/dist/enroll.js +248 -0
- package/dist/enroll.js.map +1 -0
- package/dist/fanout.d.ts +63 -0
- package/dist/fanout.d.ts.map +1 -0
- package/dist/fanout.js +115 -0
- package/dist/fanout.js.map +1 -0
- package/dist/forward.d.ts +66 -0
- package/dist/forward.d.ts.map +1 -0
- package/dist/forward.js +141 -0
- package/dist/forward.js.map +1 -0
- package/dist/gitdiff.d.ts +31 -0
- package/dist/gitdiff.d.ts.map +1 -0
- package/dist/gitdiff.js +133 -0
- package/dist/gitdiff.js.map +1 -0
- package/dist/h2a-bridge.d.ts +102 -0
- package/dist/h2a-bridge.d.ts.map +1 -0
- package/dist/h2a-bridge.js +333 -0
- package/dist/h2a-bridge.js.map +1 -0
- package/dist/h2a-jobs.d.ts +235 -0
- package/dist/h2a-jobs.d.ts.map +1 -0
- package/dist/h2a-jobs.js +388 -0
- package/dist/h2a-jobs.js.map +1 -0
- package/dist/h2a-ping.d.ts +38 -0
- package/dist/h2a-ping.d.ts.map +1 -0
- package/dist/h2a-ping.js +58 -0
- package/dist/h2a-ping.js.map +1 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5887 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive-throttle.d.ts +164 -0
- package/dist/interactive-throttle.d.ts.map +1 -0
- package/dist/interactive-throttle.js +194 -0
- package/dist/interactive-throttle.js.map +1 -0
- package/dist/lineage-client.d.ts +77 -0
- package/dist/lineage-client.d.ts.map +1 -0
- package/dist/lineage-client.js +117 -0
- package/dist/lineage-client.js.map +1 -0
- package/dist/lineage-lease.d.ts +152 -0
- package/dist/lineage-lease.d.ts.map +1 -0
- package/dist/lineage-lease.js +303 -0
- package/dist/lineage-lease.js.map +1 -0
- package/dist/llm-gateway-runtime/accounts.d.ts +48 -0
- package/dist/llm-gateway-runtime/accounts.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/accounts.js +226 -0
- package/dist/llm-gateway-runtime/accounts.js.map +1 -0
- package/dist/llm-gateway-runtime/index.d.ts +4 -0
- package/dist/llm-gateway-runtime/index.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/index.js +58 -0
- package/dist/llm-gateway-runtime/index.js.map +1 -0
- package/dist/llm-gateway-runtime/model-catalog.d.ts +36 -0
- package/dist/llm-gateway-runtime/model-catalog.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/model-catalog.js +146 -0
- package/dist/llm-gateway-runtime/model-catalog.js.map +1 -0
- package/dist/llm-gateway-runtime/proxy-anthropic.d.ts +3 -0
- package/dist/llm-gateway-runtime/proxy-anthropic.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/proxy-anthropic.js +139 -0
- package/dist/llm-gateway-runtime/proxy-anthropic.js.map +1 -0
- package/dist/llm-gateway-runtime/proxy-openai.d.ts +117 -0
- package/dist/llm-gateway-runtime/proxy-openai.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/proxy-openai.js +1132 -0
- package/dist/llm-gateway-runtime/proxy-openai.js.map +1 -0
- package/dist/llm-gateway-runtime/session-ledger.d.ts +32 -0
- package/dist/llm-gateway-runtime/session-ledger.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/session-ledger.js +62 -0
- package/dist/llm-gateway-runtime/session-ledger.js.map +1 -0
- package/dist/llm-gateway-runtime/sticky.d.ts +40 -0
- package/dist/llm-gateway-runtime/sticky.d.ts.map +1 -0
- package/dist/llm-gateway-runtime/sticky.js +254 -0
- package/dist/llm-gateway-runtime/sticky.js.map +1 -0
- package/dist/llm-mesh.d.ts +102 -0
- package/dist/llm-mesh.d.ts.map +1 -0
- package/dist/llm-mesh.js +433 -0
- package/dist/llm-mesh.js.map +1 -0
- package/dist/migrate-candidates.d.ts +35 -0
- package/dist/migrate-candidates.d.ts.map +1 -0
- package/dist/migrate-candidates.js +128 -0
- package/dist/migrate-candidates.js.map +1 -0
- package/dist/migrate.d.ts +125 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +561 -0
- package/dist/migrate.js.map +1 -0
- package/dist/plugin-manifest.d.ts +143 -0
- package/dist/plugin-manifest.d.ts.map +1 -0
- package/dist/plugin-manifest.js +233 -0
- package/dist/plugin-manifest.js.map +1 -0
- package/dist/plugin.d.ts +274 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +919 -0
- package/dist/plugin.js.map +1 -0
- package/dist/pod-liveness.d.ts +51 -0
- package/dist/pod-liveness.d.ts.map +1 -0
- package/dist/pod-liveness.js +80 -0
- package/dist/pod-liveness.js.map +1 -0
- package/dist/profile-menu.d.ts +7 -0
- package/dist/profile-menu.d.ts.map +1 -0
- package/dist/profile-menu.js +52 -0
- package/dist/profile-menu.js.map +1 -0
- package/dist/profiles.d.ts +23 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +66 -0
- package/dist/profiles.js.map +1 -0
- package/dist/protocol-local.d.ts +27 -0
- package/dist/protocol-local.d.ts.map +1 -0
- package/dist/protocol-local.js +12 -0
- package/dist/protocol-local.js.map +1 -0
- package/dist/pty.d.ts +26 -0
- package/dist/pty.d.ts.map +1 -0
- package/dist/pty.js +45 -0
- package/dist/pty.js.map +1 -0
- package/dist/readiness.d.ts +38 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +169 -0
- package/dist/readiness.js.map +1 -0
- package/dist/registry.d.ts +258 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +570 -0
- package/dist/registry.js.map +1 -0
- package/dist/relaunch.d.ts +52 -0
- package/dist/relaunch.d.ts.map +1 -0
- package/dist/relaunch.js +76 -0
- package/dist/relaunch.js.map +1 -0
- package/dist/restore.d.ts +165 -0
- package/dist/restore.d.ts.map +1 -0
- package/dist/restore.js +530 -0
- package/dist/restore.js.map +1 -0
- package/dist/run.d.ts +29 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +206 -0
- package/dist/run.js.map +1 -0
- package/dist/secrets.d.ts +25 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +98 -0
- package/dist/secrets.js.map +1 -0
- package/dist/session-restore.d.ts +26 -0
- package/dist/session-restore.d.ts.map +1 -0
- package/dist/session-restore.js +122 -0
- package/dist/session-restore.js.map +1 -0
- package/dist/skills-sync.d.ts +126 -0
- package/dist/skills-sync.d.ts.map +1 -0
- package/dist/skills-sync.js +255 -0
- package/dist/skills-sync.js.map +1 -0
- package/dist/smoke.d.ts +23 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +138 -0
- package/dist/smoke.js.map +1 -0
- package/dist/soft-refresh.d.ts +107 -0
- package/dist/soft-refresh.d.ts.map +1 -0
- package/dist/soft-refresh.js +426 -0
- package/dist/soft-refresh.js.map +1 -0
- package/dist/sync-status.d.ts +22 -0
- package/dist/sync-status.d.ts.map +1 -0
- package/dist/sync-status.js +41 -0
- package/dist/sync-status.js.map +1 -0
- package/dist/sync.d.ts +77 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +302 -0
- package/dist/sync.js.map +1 -0
- package/dist/throttle-signatures.d.ts +43 -0
- package/dist/throttle-signatures.d.ts.map +1 -0
- package/dist/throttle-signatures.js +116 -0
- package/dist/throttle-signatures.js.map +1 -0
- package/dist/tmux.d.ts +286 -0
- package/dist/tmux.d.ts.map +1 -0
- package/dist/tmux.js +970 -0
- package/dist/tmux.js.map +1 -0
- package/dist/tunnel.d.ts +25 -0
- package/dist/tunnel.d.ts.map +1 -0
- package/dist/tunnel.js +127 -0
- package/dist/tunnel.js.map +1 -0
- package/dist/workspace-merge.d.ts +17 -0
- package/dist/workspace-merge.d.ts.map +1 -0
- package/dist/workspace-merge.js +153 -0
- package/dist/workspace-merge.js.map +1 -0
- package/dist/workspace-sync-incremental.d.ts +64 -0
- package/dist/workspace-sync-incremental.d.ts.map +1 -0
- package/dist/workspace-sync-incremental.js +199 -0
- package/dist/workspace-sync-incremental.js.map +1 -0
- package/dist/workspace-sync.d.ts +3 -0
- package/dist/workspace-sync.d.ts.map +1 -0
- package/dist/workspace-sync.js +187 -0
- package/dist/workspace-sync.js.map +1 -0
- package/dist/workspace.d.ts +70 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +173 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `remote forward` — expose a port of a session Pod on the local machine via
|
|
3
|
+
* `kubectl port-forward`. This is the low-level transport that serves the
|
|
4
|
+
* `uat-expose` capability (see protocol `uat-exposure-policy`): it lets you reach
|
|
5
|
+
* any web UI running inside a session Pod (a mail/UAT control UI, a dev server…)
|
|
6
|
+
* at http://localhost:<localPort>.
|
|
7
|
+
*
|
|
8
|
+
* The forward runs in the FOREGROUND until Ctrl-C (unlike the control-plane
|
|
9
|
+
* tunnel in tunnel.ts, which is a detached, pidfile-managed background child):
|
|
10
|
+
* here the user explicitly wants a live, visible session they tear down by hand.
|
|
11
|
+
*
|
|
12
|
+
* Pure, unit-tested helpers (no I/O) build the kubectl argv and the local URL;
|
|
13
|
+
* the impure runner wires them to a child process + SIGINT.
|
|
14
|
+
*/
|
|
15
|
+
import { listRemoteSessions } from "./attach.js";
|
|
16
|
+
/** A leading ~ is expanded to the user's home dir (matches tunnel.ts/sync.ts). */
|
|
17
|
+
export declare function expandHome(p: string): string;
|
|
18
|
+
/** Pod name for a session id (matches the orchestrator: `session-<id>`). */
|
|
19
|
+
export declare function sessionPodName(sessionId: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* `localPort:podPort` when a local port is given, else just `podPort` — kubectl
|
|
22
|
+
* then picks a free local port equal to (or, if taken, near) the pod port.
|
|
23
|
+
*/
|
|
24
|
+
export declare function portMapping(podPort: number, localPort?: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Build the `kubectl port-forward` argv (without the leading "kubectl").
|
|
27
|
+
* Pure so it can be asserted in tests without touching the cluster.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildPortForwardArgs(args: {
|
|
30
|
+
namespace: string;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
podPort: number;
|
|
33
|
+
localPort?: number;
|
|
34
|
+
address?: string;
|
|
35
|
+
}): string[];
|
|
36
|
+
/** Local URL the user can open once the forward is up. */
|
|
37
|
+
export declare function localForwardUrl(podPort: number, localPort?: number): string;
|
|
38
|
+
export type ForwardOptions = {
|
|
39
|
+
sessionId: string;
|
|
40
|
+
podPort: number;
|
|
41
|
+
localPort?: number;
|
|
42
|
+
address?: string;
|
|
43
|
+
/** Injectable for tests; defaults to the real listRemoteSessions. */
|
|
44
|
+
listSessions?: typeof listRemoteSessions;
|
|
45
|
+
/** Control-plane URL (needed to list sessions). */
|
|
46
|
+
remoteUrl: string;
|
|
47
|
+
stderr?: NodeJS.WriteStream;
|
|
48
|
+
stdout?: NodeJS.WriteStream;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Verify the session exists on the control-plane. Returns an error message
|
|
52
|
+
* (string) when it does NOT, or undefined when it does. Pure aside from the
|
|
53
|
+
* injected lister, so the "unknown session" path is unit-testable with a mock.
|
|
54
|
+
*/
|
|
55
|
+
export declare function ensureSessionExists(opts: {
|
|
56
|
+
sessionId: string;
|
|
57
|
+
remoteUrl: string;
|
|
58
|
+
listSessions: typeof listRemoteSessions;
|
|
59
|
+
}): Promise<string | undefined>;
|
|
60
|
+
/**
|
|
61
|
+
* Run `kubectl port-forward` in the FOREGROUND until Ctrl-C. Returns the process
|
|
62
|
+
* exit code: 0 on a clean SIGINT teardown, non-zero if kubectl itself failed.
|
|
63
|
+
* Verifies the session exists first; resolves with 1 (after printing) if not.
|
|
64
|
+
*/
|
|
65
|
+
export declare function forwardSessionPort(opts: ForwardOptions): Promise<number>;
|
|
66
|
+
//# sourceMappingURL=forward.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward.d.ts","sourceRoot":"","sources":["../src/forward.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,EAAE,CAUX;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,kBAAkB,CAAC;IACzC,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,kBAAkB,CAAC;CACzC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS9B;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAqC9E"}
|
package/dist/forward.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `remote forward` — expose a port of a session Pod on the local machine via
|
|
3
|
+
* `kubectl port-forward`. This is the low-level transport that serves the
|
|
4
|
+
* `uat-expose` capability (see protocol `uat-exposure-policy`): it lets you reach
|
|
5
|
+
* any web UI running inside a session Pod (a mail/UAT control UI, a dev server…)
|
|
6
|
+
* at http://localhost:<localPort>.
|
|
7
|
+
*
|
|
8
|
+
* The forward runs in the FOREGROUND until Ctrl-C (unlike the control-plane
|
|
9
|
+
* tunnel in tunnel.ts, which is a detached, pidfile-managed background child):
|
|
10
|
+
* here the user explicitly wants a live, visible session they tear down by hand.
|
|
11
|
+
*
|
|
12
|
+
* Pure, unit-tested helpers (no I/O) build the kubectl argv and the local URL;
|
|
13
|
+
* the impure runner wires them to a child process + SIGINT.
|
|
14
|
+
*/
|
|
15
|
+
import { spawn } from "node:child_process";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { getTunnel } from "./config.js";
|
|
19
|
+
import { listRemoteSessions } from "./attach.js";
|
|
20
|
+
/** A leading ~ is expanded to the user's home dir (matches tunnel.ts/sync.ts). */
|
|
21
|
+
export function expandHome(p) {
|
|
22
|
+
return p.startsWith("~") ? join(homedir(), p.slice(1)) : p;
|
|
23
|
+
}
|
|
24
|
+
/** Pod name for a session id (matches the orchestrator: `session-<id>`). */
|
|
25
|
+
export function sessionPodName(sessionId) {
|
|
26
|
+
return `session-${sessionId}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `localPort:podPort` when a local port is given, else just `podPort` — kubectl
|
|
30
|
+
* then picks a free local port equal to (or, if taken, near) the pod port.
|
|
31
|
+
*/
|
|
32
|
+
export function portMapping(podPort, localPort) {
|
|
33
|
+
return localPort === undefined ? String(podPort) : `${localPort}:${podPort}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the `kubectl port-forward` argv (without the leading "kubectl").
|
|
37
|
+
* Pure so it can be asserted in tests without touching the cluster.
|
|
38
|
+
*/
|
|
39
|
+
export function buildPortForwardArgs(args) {
|
|
40
|
+
const { namespace, sessionId, podPort, localPort, address } = args;
|
|
41
|
+
return [
|
|
42
|
+
"-n",
|
|
43
|
+
namespace,
|
|
44
|
+
"port-forward",
|
|
45
|
+
`--address=${address ?? "127.0.0.1"}`,
|
|
46
|
+
`pod/${sessionPodName(sessionId)}`,
|
|
47
|
+
portMapping(podPort, localPort),
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
/** Local URL the user can open once the forward is up. */
|
|
51
|
+
export function localForwardUrl(podPort, localPort) {
|
|
52
|
+
return `http://localhost:${localPort ?? podPort}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Verify the session exists on the control-plane. Returns an error message
|
|
56
|
+
* (string) when it does NOT, or undefined when it does. Pure aside from the
|
|
57
|
+
* injected lister, so the "unknown session" path is unit-testable with a mock.
|
|
58
|
+
*/
|
|
59
|
+
export async function ensureSessionExists(opts) {
|
|
60
|
+
const sessions = await opts.listSessions(opts.remoteUrl);
|
|
61
|
+
const found = sessions.some((s) => s.id === opts.sessionId);
|
|
62
|
+
if (found)
|
|
63
|
+
return undefined;
|
|
64
|
+
const known = sessions.map((s) => s.id);
|
|
65
|
+
return (`no remote session "${opts.sessionId}"` +
|
|
66
|
+
(known.length > 0 ? ` (live: ${known.join(", ")})` : " (no live sessions)"));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Run `kubectl port-forward` in the FOREGROUND until Ctrl-C. Returns the process
|
|
70
|
+
* exit code: 0 on a clean SIGINT teardown, non-zero if kubectl itself failed.
|
|
71
|
+
* Verifies the session exists first; resolves with 1 (after printing) if not.
|
|
72
|
+
*/
|
|
73
|
+
export async function forwardSessionPort(opts) {
|
|
74
|
+
const stderr = opts.stderr ?? process.stderr;
|
|
75
|
+
const stdout = opts.stdout ?? process.stdout;
|
|
76
|
+
const tunnel = getTunnel();
|
|
77
|
+
if (!tunnel) {
|
|
78
|
+
stderr.write("[remote] forward needs a tunnel configured (remote config tunnel …)\n");
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
const listSessions = opts.listSessions ?? listRemoteSessions;
|
|
82
|
+
const missing = await ensureSessionExists({
|
|
83
|
+
sessionId: opts.sessionId,
|
|
84
|
+
remoteUrl: opts.remoteUrl,
|
|
85
|
+
listSessions,
|
|
86
|
+
});
|
|
87
|
+
if (missing) {
|
|
88
|
+
stderr.write(`[remote] ${missing}\n`);
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
91
|
+
const args = buildPortForwardArgs({
|
|
92
|
+
namespace: tunnel.namespace,
|
|
93
|
+
sessionId: opts.sessionId,
|
|
94
|
+
podPort: opts.podPort,
|
|
95
|
+
...(opts.localPort !== undefined ? { localPort: opts.localPort } : {}),
|
|
96
|
+
...(opts.address !== undefined ? { address: opts.address } : {}),
|
|
97
|
+
});
|
|
98
|
+
const url = localForwardUrl(opts.podPort, opts.localPort);
|
|
99
|
+
stderr.write(`[remote] forwarding ${sessionPodName(opts.sessionId)} :${opts.podPort} → ${url}\n` +
|
|
100
|
+
`[remote] open ${url} — Ctrl-C to stop\n`);
|
|
101
|
+
return runPortForward(tunnel, args, stdout, stderr);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Spawn kubectl, pipe its output through, and turn Ctrl-C into a clean teardown
|
|
105
|
+
* (SIGINT → kill the child → resolve 0). Kept separate so forwardSessionPort
|
|
106
|
+
* stays readable; the env/KUBECONFIG wiring mirrors tunnel.ts.
|
|
107
|
+
*/
|
|
108
|
+
function runPortForward(tunnel, args, stdout, stderr) {
|
|
109
|
+
const env = { ...process.env };
|
|
110
|
+
if (tunnel.kubeconfig)
|
|
111
|
+
env.KUBECONFIG = expandHome(tunnel.kubeconfig);
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
const child = spawn("kubectl", [...args], {
|
|
114
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
115
|
+
env,
|
|
116
|
+
});
|
|
117
|
+
child.stdout?.pipe(stdout);
|
|
118
|
+
child.stderr?.pipe(stderr);
|
|
119
|
+
let interrupted = false;
|
|
120
|
+
const onSigint = () => {
|
|
121
|
+
interrupted = true;
|
|
122
|
+
child.kill("SIGINT");
|
|
123
|
+
};
|
|
124
|
+
process.on("SIGINT", onSigint);
|
|
125
|
+
const cleanup = () => {
|
|
126
|
+
process.removeListener("SIGINT", onSigint);
|
|
127
|
+
};
|
|
128
|
+
child.on("error", (err) => {
|
|
129
|
+
cleanup();
|
|
130
|
+
stderr.write(`[remote] kubectl port-forward failed: ${err.message}\n`);
|
|
131
|
+
resolve(1);
|
|
132
|
+
});
|
|
133
|
+
child.on("close", (code) => {
|
|
134
|
+
cleanup();
|
|
135
|
+
// A SIGINT teardown is the expected, successful end of a foreground
|
|
136
|
+
// forward — report 0 even though kubectl exits non-zero on the signal.
|
|
137
|
+
resolve(interrupted ? 0 : code ?? 0);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=forward.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward.js","sourceRoot":"","sources":["../src/forward.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAqB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,kFAAkF;AAClF,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,WAAW,SAAS,EAAE,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,SAAkB;IAC7D,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAMpC;IACC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACnE,OAAO;QACL,IAAI;QACJ,SAAS;QACT,cAAc;QACd,aAAa,OAAO,IAAI,WAAW,EAAE;QACrC,OAAO,cAAc,CAAC,SAAS,CAAC,EAAE;QAClC,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,SAAkB;IACjE,OAAO,oBAAoB,SAAS,IAAI,OAAO,EAAE,CAAC;AACpD,CAAC;AAeD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAIzC;IACC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5D,IAAI,KAAK;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxC,OAAO,CACL,sBAAsB,IAAI,CAAC,SAAS,GAAG;QACvC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAoB;IAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAC7C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,CAAC,KAAK,CACV,uEAAuE,CACxE,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,kBAAkB,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACxC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY;KACb,CAAC,CAAC;IACH,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,IAAI,GAAG,oBAAoB,CAAC;QAChC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,CACV,uBAAuB,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,OAAO,MAAM,GAAG,IAAI;QACjF,iBAAiB,GAAG,qBAAqB,CAC5C,CAAC;IAEF,OAAO,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACrB,MAAoB,EACpB,IAA2B,EAC3B,MAA0B,EAC1B,MAA0B;IAE1B,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/B,IAAI,MAAM,CAAC,UAAU;QAAE,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEtE,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YACxC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,GAAG;SACJ,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAE3B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC1B,WAAW,GAAG,IAAI,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE/B,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC,CAAC;QAEF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,OAAO,EAAE,CAAC;YACV,MAAM,CAAC,KAAK,CAAC,yCAAyC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YACvE,OAAO,CAAC,CAAC,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,OAAO,EAAE,CAAC;YACV,oEAAoE;YACpE,uEAAuE;YACvE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git workspace alignment check for `remote diff --files`: compare the LOCAL
|
|
3
|
+
* workspace's git state with the session Pod's ($WORKSPACE_PATH), via kubectl
|
|
4
|
+
* exec. Only HEAD shas, branch names and modified file NAMES cross the wire —
|
|
5
|
+
* never any file content.
|
|
6
|
+
*/
|
|
7
|
+
export type GitStat = {
|
|
8
|
+
head: string;
|
|
9
|
+
branch: string;
|
|
10
|
+
/** Modified/untracked file names from `git status --porcelain` (names only). */
|
|
11
|
+
dirty: string[];
|
|
12
|
+
};
|
|
13
|
+
/** File names (only) out of `git status --porcelain` output. */
|
|
14
|
+
export declare function parsePorcelain(out: string): string[];
|
|
15
|
+
/** Git state of the LOCAL workspace directory (or undefined if not a repo). */
|
|
16
|
+
export declare function localGitStat(workspacePath: string): GitStat | undefined;
|
|
17
|
+
/** Git state of the Pod's $WORKSPACE_PATH (computed in-Pod, names only). */
|
|
18
|
+
export declare function remoteGitStat(sessionId: string): GitStat | undefined;
|
|
19
|
+
export type Ancestry = "local-ahead" | "remote-ahead" | "unknown";
|
|
20
|
+
/**
|
|
21
|
+
* Which HEAD descends from the other, resolved with LOCAL git objects only
|
|
22
|
+
* (the remote HEAD is usually known locally after a fetch; otherwise unknown).
|
|
23
|
+
*/
|
|
24
|
+
export declare function localAncestry(workspacePath: string, localHead: string, remoteHead: string): Ancestry;
|
|
25
|
+
export type GitVerdict = {
|
|
26
|
+
state: "in-sync" | "local-ahead" | "remote-ahead" | "diverged" | "missing";
|
|
27
|
+
detail: string;
|
|
28
|
+
};
|
|
29
|
+
/** Pure verdict from both git states (+ HEAD ancestry when heads differ). */
|
|
30
|
+
export declare function gitAlignment(local: GitStat | undefined, remote: GitStat | undefined, ancestry?: Ancestry): GitVerdict;
|
|
31
|
+
//# sourceMappingURL=gitdiff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitdiff.d.ts","sourceRoot":"","sources":["../src/gitdiff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAMF,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAUpD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAUvE;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAmCpE;AAED,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,cAAc,GAAG,SAAS,CAAC;AAElE;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,QAAQ,CAQV;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3E,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAQF,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,GAAG,SAAS,EAC1B,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,QAAQ,GAAE,QAAoB,GAC7B,UAAU,CAmCZ"}
|
package/dist/gitdiff.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git workspace alignment check for `remote diff --files`: compare the LOCAL
|
|
3
|
+
* workspace's git state with the session Pod's ($WORKSPACE_PATH), via kubectl
|
|
4
|
+
* exec. Only HEAD shas, branch names and modified file NAMES cross the wire —
|
|
5
|
+
* never any file content.
|
|
6
|
+
*/
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { getTunnel } from "./config.js";
|
|
11
|
+
function expandHome(p) {
|
|
12
|
+
return p.startsWith("~") ? join(homedir(), p.slice(1)) : p;
|
|
13
|
+
}
|
|
14
|
+
/** File names (only) out of `git status --porcelain` output. */
|
|
15
|
+
export function parsePorcelain(out) {
|
|
16
|
+
const files = [];
|
|
17
|
+
for (const line of out.split("\n")) {
|
|
18
|
+
if (line.trim() === "")
|
|
19
|
+
continue;
|
|
20
|
+
let p = line.slice(3); // "XY <path>"
|
|
21
|
+
const arrow = p.indexOf(" -> "); // rename: "old -> new" — keep the new name
|
|
22
|
+
if (arrow !== -1)
|
|
23
|
+
p = p.slice(arrow + 4);
|
|
24
|
+
files.push(p.replace(/^"(.*)"$/, "$1"));
|
|
25
|
+
}
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
28
|
+
/** Git state of the LOCAL workspace directory (or undefined if not a repo). */
|
|
29
|
+
export function localGitStat(workspacePath) {
|
|
30
|
+
const run = (args) => spawnSync("git", ["-C", workspacePath, ...args], { encoding: "utf8" });
|
|
31
|
+
const head = run(["rev-parse", "HEAD"]);
|
|
32
|
+
if (head.status !== 0)
|
|
33
|
+
return undefined;
|
|
34
|
+
return {
|
|
35
|
+
head: head.stdout.trim(),
|
|
36
|
+
branch: run(["rev-parse", "--abbrev-ref", "HEAD"]).stdout.trim(),
|
|
37
|
+
dirty: parsePorcelain(run(["status", "--porcelain"]).stdout),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Git state of the Pod's $WORKSPACE_PATH (computed in-Pod, names only). */
|
|
41
|
+
export function remoteGitStat(sessionId) {
|
|
42
|
+
const tunnel = getTunnel();
|
|
43
|
+
if (!tunnel)
|
|
44
|
+
return undefined;
|
|
45
|
+
const env = { ...process.env };
|
|
46
|
+
if (tunnel.kubeconfig)
|
|
47
|
+
env.KUBECONFIG = expandHome(tunnel.kubeconfig);
|
|
48
|
+
const script = `cd "$WORKSPACE_PATH" || exit 1; ` +
|
|
49
|
+
`git rev-parse HEAD 2>/dev/null || exit 1; ` +
|
|
50
|
+
`git rev-parse --abbrev-ref HEAD 2>/dev/null; ` +
|
|
51
|
+
`git status --porcelain 2>/dev/null`;
|
|
52
|
+
const r = spawnSync("kubectl", [
|
|
53
|
+
"-n",
|
|
54
|
+
tunnel.namespace,
|
|
55
|
+
"exec",
|
|
56
|
+
`session-${sessionId}`,
|
|
57
|
+
"-c",
|
|
58
|
+
"session-agent",
|
|
59
|
+
"--",
|
|
60
|
+
"bash",
|
|
61
|
+
"-lc",
|
|
62
|
+
script,
|
|
63
|
+
], { encoding: "utf8", env });
|
|
64
|
+
if (r.status !== 0)
|
|
65
|
+
return undefined;
|
|
66
|
+
const lines = r.stdout.split("\n");
|
|
67
|
+
const head = (lines[0] ?? "").trim();
|
|
68
|
+
if (!head)
|
|
69
|
+
return undefined;
|
|
70
|
+
return {
|
|
71
|
+
head,
|
|
72
|
+
branch: (lines[1] ?? "").trim(),
|
|
73
|
+
dirty: parsePorcelain(lines.slice(2).join("\n")),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Which HEAD descends from the other, resolved with LOCAL git objects only
|
|
78
|
+
* (the remote HEAD is usually known locally after a fetch; otherwise unknown).
|
|
79
|
+
*/
|
|
80
|
+
export function localAncestry(workspacePath, localHead, remoteHead) {
|
|
81
|
+
const isAncestor = (a, b) => spawnSync("git", ["-C", workspacePath, "merge-base", "--is-ancestor", a, b], {
|
|
82
|
+
encoding: "utf8",
|
|
83
|
+
}).status === 0;
|
|
84
|
+
if (isAncestor(remoteHead, localHead))
|
|
85
|
+
return "local-ahead";
|
|
86
|
+
if (isAncestor(localHead, remoteHead))
|
|
87
|
+
return "remote-ahead";
|
|
88
|
+
return "unknown";
|
|
89
|
+
}
|
|
90
|
+
function names(files) {
|
|
91
|
+
return files.length <= 4
|
|
92
|
+
? files.join(", ")
|
|
93
|
+
: `${files.slice(0, 4).join(", ")}, +${files.length - 4} more`;
|
|
94
|
+
}
|
|
95
|
+
/** Pure verdict from both git states (+ HEAD ancestry when heads differ). */
|
|
96
|
+
export function gitAlignment(local, remote, ancestry = "unknown") {
|
|
97
|
+
if (!local && !remote)
|
|
98
|
+
return { state: "missing", detail: "no git repo either side" };
|
|
99
|
+
if (!remote) {
|
|
100
|
+
return { state: "missing", detail: "Pod workspace is not a git repo (or unreachable)" };
|
|
101
|
+
}
|
|
102
|
+
if (!local)
|
|
103
|
+
return { state: "missing", detail: "local workspace is not a git repo" };
|
|
104
|
+
const sameHead = local.head === remote.head;
|
|
105
|
+
const branchTxt = local.branch === remote.branch
|
|
106
|
+
? `branch ${local.branch}`
|
|
107
|
+
: `branch ${local.branch} (local) vs ${remote.branch} (remote)`;
|
|
108
|
+
const headTxt = sameHead
|
|
109
|
+
? `HEAD ${local.head.slice(0, 7)} identical`
|
|
110
|
+
: `HEAD differs: ${local.head.slice(0, 7)} (local) vs ${remote.head.slice(0, 7)} (remote)`;
|
|
111
|
+
const dirtyTxt = [
|
|
112
|
+
local.dirty.length > 0 ? `local modified: ${names(local.dirty)}` : "local clean",
|
|
113
|
+
remote.dirty.length > 0 ? `remote modified: ${names(remote.dirty)}` : "remote clean",
|
|
114
|
+
].join("; ");
|
|
115
|
+
const detail = `${headTxt} [${branchTxt}] — ${dirtyTxt}`;
|
|
116
|
+
if (sameHead) {
|
|
117
|
+
if (local.dirty.length === 0 && remote.dirty.length === 0)
|
|
118
|
+
return { state: "in-sync", detail };
|
|
119
|
+
if (remote.dirty.length === 0)
|
|
120
|
+
return { state: "local-ahead", detail };
|
|
121
|
+
if (local.dirty.length === 0)
|
|
122
|
+
return { state: "remote-ahead", detail };
|
|
123
|
+
return { state: "diverged", detail: `${detail} (both sides modified)` };
|
|
124
|
+
}
|
|
125
|
+
if (ancestry === "local-ahead" && remote.dirty.length === 0) {
|
|
126
|
+
return { state: "local-ahead", detail: `${detail} (remote HEAD is an ancestor of local)` };
|
|
127
|
+
}
|
|
128
|
+
if (ancestry === "remote-ahead" && local.dirty.length === 0) {
|
|
129
|
+
return { state: "remote-ahead", detail: `${detail} (local HEAD is an ancestor of remote)` };
|
|
130
|
+
}
|
|
131
|
+
return { state: "diverged", detail };
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=gitdiff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitdiff.js","sourceRoot":"","sources":["../src/gitdiff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* h2a bridge (`remote h2a bridge`): connect the LOCAL h2a agent network — a
|
|
3
|
+
* file store under ~/h2a-workspace/.h2a where agents exchange JSON envelopes
|
|
4
|
+
* by dropping them into inbox/<instance-dir>/ — with a remote session Pod, so
|
|
5
|
+
* the Pod's agent is reachable/wakeable from the local bus and vice versa.
|
|
6
|
+
*
|
|
7
|
+
* Everything rides `kubectl exec` against the configured tunnel (same pattern
|
|
8
|
+
* as soft-refresh/sync), base64 on the wire — encoded exactly ONCE per
|
|
9
|
+
* direction, never double-encoded. Two flows per pass:
|
|
10
|
+
*
|
|
11
|
+
* PULL Pod → local: envelopes the Pod's agent EMITTED toward non-Pod
|
|
12
|
+
* instances (every Pod inbox/<dir>/ except the Pod's own instances')
|
|
13
|
+
* land in the same-named local inbox dir.
|
|
14
|
+
* PUSH local → Pod: envelopes locally addressed TO the Pod's instances
|
|
15
|
+
* (local inbox/<pod-instance-dir>/) land in the Pod's inbox.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent by FILE NAME: a file that already exists on the destination is
|
|
18
|
+
* skipped — never overwritten. The bridge NEVER deletes anything on either
|
|
19
|
+
* side: acks/cleanup belong to h2a itself, the bridge is transport only.
|
|
20
|
+
*
|
|
21
|
+
* The Pod's instances are the union of a default mapping
|
|
22
|
+
* `<tool>:remote:<sessionId>` (tool from the session profile) and whatever is
|
|
23
|
+
* registered in the Pod's own registry/instances.jsonl. Instance ids map to
|
|
24
|
+
* inbox dir names by encoding ":" as "__" (h2a convention, e.g.
|
|
25
|
+
* `claude:remote:abc123` → `claude__remote__abc123`).
|
|
26
|
+
*
|
|
27
|
+
* A Pod without ~/h2a-workspace/.h2a gets the skeleton (inbox/) plus a
|
|
28
|
+
* README.md documenting the envelope-drop convention, so agents in the Pod
|
|
29
|
+
* can participate by writing plain JSON files — no h2a binary required.
|
|
30
|
+
*/
|
|
31
|
+
/** h2a store root in the Pod, relative to $HOME (used as "$HOME/<this>"). */
|
|
32
|
+
export declare const H2A_POD_ROOT = "h2a-workspace/.h2a";
|
|
33
|
+
/** Local h2a store root (the agent network's shared filesystem). */
|
|
34
|
+
export declare function defaultLocalH2aRoot(): string;
|
|
35
|
+
/** Inbox dir name for an instance id — h2a encodes ":" as "__" on disk. */
|
|
36
|
+
export declare function instanceInboxDir(instance: string): string;
|
|
37
|
+
/** Default h2a instance id for a session Pod's agent: <tool>:remote:<sessionId>. */
|
|
38
|
+
export declare function defaultPodInstance(sessionId: string, profile?: string): string;
|
|
39
|
+
export type BridgeFile = {
|
|
40
|
+
dir: string;
|
|
41
|
+
file: string;
|
|
42
|
+
};
|
|
43
|
+
export type BridgePlan = {
|
|
44
|
+
/** Pod → local: new envelopes the Pod's agent emitted toward non-Pod instances. */
|
|
45
|
+
pull: BridgeFile[];
|
|
46
|
+
/** local → Pod: new envelopes locally addressed to the Pod's instances. */
|
|
47
|
+
push: BridgeFile[];
|
|
48
|
+
/** Files already present on their destination — skipped, NEVER overwritten. */
|
|
49
|
+
skipped: number;
|
|
50
|
+
/** Entries with unsafe/malformed names, ignored entirely. */
|
|
51
|
+
ignored: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Pure sync plan: given the two inbox listings ("dir/file" entries) and the
|
|
55
|
+
* set of inbox dirs owned by the Pod's instances, decide what moves where.
|
|
56
|
+
* No deletion exists in the model — the plan can only copy or skip.
|
|
57
|
+
*/
|
|
58
|
+
export declare function planBridge(args: {
|
|
59
|
+
podFiles: ReadonlyArray<string>;
|
|
60
|
+
localFiles: ReadonlyArray<string>;
|
|
61
|
+
podInstanceDirs: ReadonlySet<string>;
|
|
62
|
+
}): BridgePlan;
|
|
63
|
+
/**
|
|
64
|
+
* Parse the single listing exec's output: an `==INSTANCES==` section (one
|
|
65
|
+
* registered instance id per line, from the Pod's registry/instances.jsonl)
|
|
66
|
+
* then a `==FILES==` section ("dir/file" per line, relative to the Pod's
|
|
67
|
+
* inbox/). Anything before the first marker (login-shell noise) is ignored.
|
|
68
|
+
*/
|
|
69
|
+
export declare function parsePodListing(out: string): {
|
|
70
|
+
instances: string[];
|
|
71
|
+
files: string[];
|
|
72
|
+
};
|
|
73
|
+
export type H2aBridgeOptions = {
|
|
74
|
+
/** Session profile (claude/codex/…) for the default Pod instance mapping. */
|
|
75
|
+
profile?: string;
|
|
76
|
+
/** Local h2a store root (default ~/h2a-workspace/.h2a; tests: a scratch dir). */
|
|
77
|
+
localRoot?: string;
|
|
78
|
+
stderr?: NodeJS.WriteStream;
|
|
79
|
+
};
|
|
80
|
+
export type H2aBridgeResult = {
|
|
81
|
+
sessionId: string;
|
|
82
|
+
/** New envelopes copied Pod → local. */
|
|
83
|
+
pulled: number;
|
|
84
|
+
/** New envelopes copied local → Pod. */
|
|
85
|
+
pushed: number;
|
|
86
|
+
/** Already-present (or destination-existing) files left untouched. */
|
|
87
|
+
skipped: number;
|
|
88
|
+
/** Per-file transfer errors (the pass continues; details on stderr). */
|
|
89
|
+
failed: number;
|
|
90
|
+
/** true when the Pod's ~/h2a-workspace/.h2a skeleton was created this pass. */
|
|
91
|
+
scaffolded: boolean;
|
|
92
|
+
/** Inbox dirs treated as the Pod's own (push targets, excluded from pull). */
|
|
93
|
+
podInstanceDirs: string[];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* One bridge pass for a session Pod: scaffold the Pod store if missing, list
|
|
97
|
+
* both sides, then PULL new Pod-emitted envelopes and PUSH new locally
|
|
98
|
+
* addressed ones. Returns counters only — envelope content is transferred
|
|
99
|
+
* verbatim but never printed.
|
|
100
|
+
*/
|
|
101
|
+
export declare function bridgeSession(sessionId: string, options?: H2aBridgeOptions): Promise<H2aBridgeResult>;
|
|
102
|
+
//# sourceMappingURL=h2a-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"h2a-bridge.d.ts","sourceRoot":"","sources":["../src/h2a-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAeH,6EAA6E;AAC7E,eAAO,MAAM,YAAY,uBAAuB,CAAC;AAEjD,oEAAoE;AACpE,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAyBD,oFAAoF;AACpF,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAER;AAUD,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,UAAU,GAAG;IACvB,mFAAmF;IACnF,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,2EAA2E;IAC3E,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAC/B,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACtC,GAAG,UAAU,CA8Cb;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAmBA;AA4DD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,EAAE,OAAO,CAAC;IACpB,8EAA8E;IAC9E,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAmBF;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAuI1B"}
|