@onepointfour-packs/flaredeck-agent 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.
Files changed (148) hide show
  1. package/LICENSE.md +14 -0
  2. package/README.md +102 -0
  3. package/dist/agent.d.ts +104 -0
  4. package/dist/agent.js +329 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/approval.d.ts +72 -0
  7. package/dist/approval.js +161 -0
  8. package/dist/approval.js.map +1 -0
  9. package/dist/approvals.d.ts +2 -0
  10. package/dist/approvals.js +148 -0
  11. package/dist/approvals.js.map +1 -0
  12. package/dist/auth.d.ts +79 -0
  13. package/dist/auth.js +181 -0
  14. package/dist/auth.js.map +1 -0
  15. package/dist/automode.d.ts +33 -0
  16. package/dist/automode.js +69 -0
  17. package/dist/automode.js.map +1 -0
  18. package/dist/branches.d.ts +25 -0
  19. package/dist/branches.js +81 -0
  20. package/dist/branches.js.map +1 -0
  21. package/dist/cli.d.ts +2 -0
  22. package/dist/cli.js +12 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/codesearch.d.ts +27 -0
  25. package/dist/codesearch.js +111 -0
  26. package/dist/codesearch.js.map +1 -0
  27. package/dist/concurrency.d.ts +14 -0
  28. package/dist/concurrency.js +52 -0
  29. package/dist/concurrency.js.map +1 -0
  30. package/dist/config.d.ts +106 -0
  31. package/dist/config.js +119 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/engine-antigravity.d.ts +23 -0
  34. package/dist/engine-antigravity.js +357 -0
  35. package/dist/engine-antigravity.js.map +1 -0
  36. package/dist/engine-claude.d.ts +18 -0
  37. package/dist/engine-claude.js +64 -0
  38. package/dist/engine-claude.js.map +1 -0
  39. package/dist/engine.d.ts +122 -0
  40. package/dist/engine.js +36 -0
  41. package/dist/engine.js.map +1 -0
  42. package/dist/env.d.ts +1 -0
  43. package/dist/env.js +10 -0
  44. package/dist/env.js.map +1 -0
  45. package/dist/environment.d.ts +39 -0
  46. package/dist/environment.js +100 -0
  47. package/dist/environment.js.map +1 -0
  48. package/dist/flaredeck-check.d.ts +21 -0
  49. package/dist/flaredeck-check.js +12 -0
  50. package/dist/flaredeck-check.js.map +1 -0
  51. package/dist/flaredeck-proxy.d.ts +60 -0
  52. package/dist/flaredeck-proxy.js +186 -0
  53. package/dist/flaredeck-proxy.js.map +1 -0
  54. package/dist/flaredeck.d.ts +132 -0
  55. package/dist/flaredeck.js +106 -0
  56. package/dist/flaredeck.js.map +1 -0
  57. package/dist/gemini.d.ts +21 -0
  58. package/dist/gemini.js +59 -0
  59. package/dist/gemini.js.map +1 -0
  60. package/dist/gitguard.d.ts +2 -0
  61. package/dist/gitguard.js +90 -0
  62. package/dist/gitguard.js.map +1 -0
  63. package/dist/github.d.ts +38 -0
  64. package/dist/github.js +153 -0
  65. package/dist/github.js.map +1 -0
  66. package/dist/githubauth.d.ts +21 -0
  67. package/dist/githubauth.js +90 -0
  68. package/dist/githubauth.js.map +1 -0
  69. package/dist/intake.d.ts +124 -0
  70. package/dist/intake.js +383 -0
  71. package/dist/intake.js.map +1 -0
  72. package/dist/jam.d.ts +45 -0
  73. package/dist/jam.js +385 -0
  74. package/dist/jam.js.map +1 -0
  75. package/dist/jev.d.ts +31 -0
  76. package/dist/jev.js +75 -0
  77. package/dist/jev.js.map +1 -0
  78. package/dist/jevguard.d.ts +28 -0
  79. package/dist/jevguard.js +213 -0
  80. package/dist/jevguard.js.map +1 -0
  81. package/dist/mailbox.d.ts +22 -0
  82. package/dist/mailbox.js +51 -0
  83. package/dist/mailbox.js.map +1 -0
  84. package/dist/main.d.ts +2 -0
  85. package/dist/main.js +764 -0
  86. package/dist/main.js.map +1 -0
  87. package/dist/markdown.d.ts +5 -0
  88. package/dist/markdown.js +81 -0
  89. package/dist/markdown.js.map +1 -0
  90. package/dist/oauth.d.ts +30 -0
  91. package/dist/oauth.js +216 -0
  92. package/dist/oauth.js.map +1 -0
  93. package/dist/permissions.d.ts +43 -0
  94. package/dist/permissions.js +57 -0
  95. package/dist/permissions.js.map +1 -0
  96. package/dist/preflight.d.ts +71 -0
  97. package/dist/preflight.js +116 -0
  98. package/dist/preflight.js.map +1 -0
  99. package/dist/providers.d.ts +26 -0
  100. package/dist/providers.js +27 -0
  101. package/dist/providers.js.map +1 -0
  102. package/dist/repopicker.d.ts +3 -0
  103. package/dist/repopicker.js +111 -0
  104. package/dist/repopicker.js.map +1 -0
  105. package/dist/runs.d.ts +59 -0
  106. package/dist/runs.js +211 -0
  107. package/dist/runs.js.map +1 -0
  108. package/dist/sandbox.d.ts +13 -0
  109. package/dist/sandbox.js +110 -0
  110. package/dist/sandbox.js.map +1 -0
  111. package/dist/schedules.d.ts +11 -0
  112. package/dist/schedules.js +85 -0
  113. package/dist/schedules.js.map +1 -0
  114. package/dist/secretguard.d.ts +4 -0
  115. package/dist/secretguard.js +115 -0
  116. package/dist/secretguard.js.map +1 -0
  117. package/dist/secrets.d.ts +27 -0
  118. package/dist/secrets.js +51 -0
  119. package/dist/secrets.js.map +1 -0
  120. package/dist/serve.d.ts +17 -0
  121. package/dist/serve.js +1206 -0
  122. package/dist/serve.js.map +1 -0
  123. package/dist/status.d.ts +73 -0
  124. package/dist/status.js +98 -0
  125. package/dist/status.js.map +1 -0
  126. package/dist/stream.d.ts +91 -0
  127. package/dist/stream.js +103 -0
  128. package/dist/stream.js.map +1 -0
  129. package/dist/streamtoken.d.ts +2 -0
  130. package/dist/streamtoken.js +30 -0
  131. package/dist/streamtoken.js.map +1 -0
  132. package/dist/team.d.ts +61 -0
  133. package/dist/team.js +136 -0
  134. package/dist/team.js.map +1 -0
  135. package/dist/ui.d.ts +110 -0
  136. package/dist/ui.js +348 -0
  137. package/dist/ui.js.map +1 -0
  138. package/dist/updater.d.ts +15 -0
  139. package/dist/updater.js +178 -0
  140. package/dist/updater.js.map +1 -0
  141. package/dist/workspace.d.ts +115 -0
  142. package/dist/workspace.js +247 -0
  143. package/dist/workspace.js.map +1 -0
  144. package/dist/worktree.d.ts +42 -0
  145. package/dist/worktree.js +140 -0
  146. package/dist/worktree.js.map +1 -0
  147. package/package.json +52 -0
  148. package/python/sidecar.py +178 -0
@@ -0,0 +1,122 @@
1
+ import type { AgentEvent } from './agent.js';
2
+ import type { Config } from './config.js';
3
+ import type { Decider } from './permissions.js';
4
+ /**
5
+ * The seam between the harness and whatever model actually runs a card.
6
+ *
7
+ * Almost none of this harness cares which model it is driving. `serve.ts` is a thousand lines of
8
+ * queue, sweep, approvals, worktrees, status and FlareDeck, and not one of them names a vendor —
9
+ * the vendor lives in `agent.ts` alone. Naming that boundary is what lets a second engine exist
10
+ * without a second harness, which is the only version of this worth maintaining: the alternative
11
+ * is keeping the sweep and the team panel and the approval flow working twice.
12
+ *
13
+ * `AgentEvent` is deliberately reused rather than redefined. It was already vendor-neutral —
14
+ * text, tool, todo, usage, done — because it was written for consumers rather than for the SDK
15
+ * that produces it. A parallel vocabulary here would be two names for one thing.
16
+ */
17
+ /**
18
+ * What an engine can actually do, declared rather than assumed.
19
+ *
20
+ * Engines differ, and the differences matter at exactly the points this harness relies on. The
21
+ * Antigravity SDK's PreToolCallDecideHook can deny a call and rewrite its arguments, but its
22
+ * PostToolCallHook is an InspectHook — it can SEE a tool result and not change it. So a secret
23
+ * that comes back in output can be noticed there and never redacted, which is the half that
24
+ * matters. An engine that cannot redact must say so, so the harness can refuse to hand it a
25
+ * secret instead of handing one over and hoping. A capability that is checked beats a difference
26
+ * that is discovered.
27
+ */
28
+ export type EngineCapabilities = {
29
+ /** Can a tool call be blocked before it runs, with a reason the model reads? */
30
+ denyToolCall: boolean;
31
+ /** Can a tool call's arguments be rewritten on the way out? ({{secret:NAME}} substitution) */
32
+ rewriteToolInput: boolean;
33
+ /** Can a tool's OUTPUT be rewritten before the model sees it? (the secret scrubber) */
34
+ redactToolOutput: boolean;
35
+ /** Can text be typed into a turn already in progress, rather than interrupting it? */
36
+ steerMidTurn: boolean;
37
+ /** Can a session be resumed, so a card picked back up remembers the last one? */
38
+ resumeSession: boolean;
39
+ };
40
+ /** Everything an engine needs to start a turn. Vendor-free on purpose. */
41
+ export type RunContext = {
42
+ /**
43
+ * The ONE directory this card may change: its worktree. Absent when there is no worktree, and
44
+ * absent means nothing is confined — a turn with no checkout is told it may change nothing, and
45
+ * the publishing tools refuse it anyway.
46
+ */
47
+ sandbox?: string;
48
+ config: Config;
49
+ /** Who answers a tool call the agent is not already allowed to make. */
50
+ decider: Decider;
51
+ /** The harness's own FlareDeck token, so the model's tools act as the account the harness is. */
52
+ token: string;
53
+ /** Resume this session rather than starting a new one. */
54
+ resume?: string;
55
+ /** The model to use for this turn, when intake sized the work and chose one. */
56
+ model?: string;
57
+ /**
58
+ * How big the work is. The engine maps this to a model of its OWN — `model` above is one
59
+ * engine's reading of the same decision, and handing it to another is a 404.
60
+ */
61
+ size?: 'small' | 'medium' | 'large';
62
+ /**
63
+ * Tool sets to put in front of the model. Served in-process today; an out-of-process engine
64
+ * serves the same objects over local MCP rather than reimplementing them in its own language,
65
+ * which is the difference between one tool layer and two.
66
+ */
67
+ tools: {
68
+ git?: ToolSet;
69
+ team?: ToolSet;
70
+ runs?: ToolSet;
71
+ schedules?: ToolSet;
72
+ flaredeck?: ToolSet;
73
+ };
74
+ /** Hooks the harness insists on, whatever the engine: the guards. */
75
+ guard?: unknown;
76
+ };
77
+ export type ToolSet = {
78
+ server: unknown;
79
+ toolNames: string[];
80
+ };
81
+ /** One turn in flight. */
82
+ export type EngineRun = {
83
+ events: AsyncGenerator<AgentEvent>;
84
+ /**
85
+ * Type into a turn already running. Resolves false when the engine cannot — a caller that
86
+ * checks gets to say "this engine can't be steered" rather than silently dropping what was
87
+ * typed, which is the sort of thing nobody notices until it matters.
88
+ */
89
+ steer(text: string): Promise<boolean>;
90
+ /** Stop this turn. */
91
+ stop(): Promise<void>;
92
+ };
93
+ export interface Engine {
94
+ /** For the pane and the logs: 'claude', 'antigravity'. */
95
+ readonly name: string;
96
+ readonly capabilities: EngineCapabilities;
97
+ run(brief: string, context: RunContext): EngineRun;
98
+ }
99
+ /**
100
+ * The engine this run uses, loaded ON DEMAND.
101
+ *
102
+ * Dynamic import rather than a top-level one, so selecting Gemini does not also load the Claude
103
+ * SDK and vice versa — the vendor an agent is not using should not be in its process at all. It
104
+ * is also what keeps the Antigravity engine from making its Python sidecar a hard dependency of
105
+ * every agent on the machine.
106
+ *
107
+ * The environment wins over the repo's config: trying the other engine on one card should not
108
+ * mean editing a file and remembering to put it back.
109
+ */
110
+ export declare function engineFor(config: {
111
+ engine?: 'claude' | 'antigravity';
112
+ }): Promise<Engine>;
113
+ /**
114
+ * Thrown when a turn could not meaningfully run, so its event must NOT be acknowledged.
115
+ *
116
+ * The distinction the whole retry story rests on: a turn that ran and went wrong has used its
117
+ * event — the card has a comment, or at least the thread moved — and acknowledging it is right. A
118
+ * turn that never started has not, and acknowledging it silently drops the card. An engine that
119
+ * cannot start is firmly the second: no model saw the brief.
120
+ */
121
+ export declare class CouldNotWork extends Error {
122
+ }
package/dist/engine.js ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The engine this run uses, loaded ON DEMAND.
3
+ *
4
+ * Dynamic import rather than a top-level one, so selecting Gemini does not also load the Claude
5
+ * SDK and vice versa — the vendor an agent is not using should not be in its process at all. It
6
+ * is also what keeps the Antigravity engine from making its Python sidecar a hard dependency of
7
+ * every agent on the machine.
8
+ *
9
+ * The environment wins over the repo's config: trying the other engine on one card should not
10
+ * mean editing a file and remembering to put it back.
11
+ */
12
+ export async function engineFor(config) {
13
+ const asked = (process.env['FLAREDECK_AGENT_ENGINE'] || config.engine || 'claude').toLowerCase();
14
+ if (asked === 'claude') {
15
+ const { ClaudeEngine } = await import('./engine-claude.js');
16
+ return new ClaudeEngine();
17
+ }
18
+ if (asked === 'antigravity') {
19
+ const { AntigravityEngine } = await import('./engine-antigravity.js');
20
+ return new AntigravityEngine();
21
+ }
22
+ // Naming an engine that does not exist must not quietly fall back to the other one: an agent
23
+ // silently running the wrong model is worse than one that refuses to start.
24
+ throw new Error(`Unknown engine "${asked}" — use "claude" or "antigravity".`);
25
+ }
26
+ /**
27
+ * Thrown when a turn could not meaningfully run, so its event must NOT be acknowledged.
28
+ *
29
+ * The distinction the whole retry story rests on: a turn that ran and went wrong has used its
30
+ * event — the card has a comment, or at least the thread moved — and acknowledging it is right. A
31
+ * turn that never started has not, and acknowledging it silently drops the card. An engine that
32
+ * cannot start is firmly the second: no model saw the brief.
33
+ */
34
+ export class CouldNotWork extends Error {
35
+ }
36
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAsGA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAA6C;IAC3E,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjG,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC5D,OAAO,IAAI,YAAY,EAAE,CAAC;IAC5B,CAAC;IACD,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACtE,OAAO,IAAI,iBAAiB,EAAE,CAAC;IACjC,CAAC;IACD,6FAA6F;IAC7F,4EAA4E;IAC5E,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,oCAAoC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;CAAG"}
package/dist/env.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/env.js ADDED
@@ -0,0 +1,10 @@
1
+ // Imported first from the entry point so it runs before anything else is evaluated.
2
+ //
3
+ // Ink renders through react-reconciler, which picks its DEVELOPMENT build whenever NODE_ENV
4
+ // is unset. That build records a performance.measure() for every render and never clears
5
+ // them, so a daemon that repaints a status line all day accumulates a million entries
6
+ // ("MaxPerformanceEntryBufferExceededWarning") and grows without bound. Nothing else in the
7
+ // harness reads NODE_ENV, so defaulting it costs nothing and an explicit value still wins.
8
+ process.env['NODE_ENV'] ??= 'production';
9
+ export {};
10
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,EAAE;AACF,4FAA4F;AAC5F,yFAAyF;AACzF,sFAAsF;AACtF,4FAA4F;AAC5F,2FAA2F;AAC3F,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Get the project running, if it has told us how.
3
+ *
4
+ * The contract is deliberately thin: `.flaredeck/start.sh` exits 0 when the environment is ready,
5
+ * and prints what it started as `name=value` lines. Nothing else is prescribed.
6
+ *
7
+ * It is an ADAPTER, not a replacement. Most repos already know how to start themselves — an npm
8
+ * script, docker compose, a Makefile, something in scripts/ — and reimplementing that would mean
9
+ * two ways to start the project, drifting apart. The file exists so there is one KNOWN name the
10
+ * harness can call without guessing; what it contains should usually be a couple of lines
11
+ * delegating to whatever the repo already does.
12
+ *
13
+ * The printed endpoints matter more than they look. A script that takes a free port so parallel
14
+ * worktrees do not collide leaves the agent unable to guess where anything is — so the script
15
+ * says, and the agent is told.
16
+ */
17
+ export declare const START_SCRIPT: string;
18
+ export type Started = {
19
+ ran: boolean;
20
+ ok: boolean;
21
+ /** Whatever the script announced: api, ui, db… */
22
+ endpoints: Record<string, string>;
23
+ detail: string;
24
+ };
25
+ export declare function hasStartScript(repo: string): boolean;
26
+ export declare function startEnvironment(repo: string, onStep: (text: string) => void): Promise<Started>;
27
+ /** What the agent is told about where things are, or why it cannot start. */
28
+ /**
29
+ * `needsRunning` is Jev's answer to whether this card can be done without the project running —
30
+ * asked in the intake call it already makes, so it costs nothing.
31
+ *
32
+ * It matters because this paragraph used to appear on EVERY card in a repo with no start script,
33
+ * and it told the agent to write the script "and commit it". An agent working a read-only card
34
+ * did exactly that: created `.flaredeck/start.sh`, committed it straight to a shared branch, and
35
+ * reported it as an accomplishment. It was not disobeying the card — the harness spoke last, and
36
+ * spoke in imperatives. Most cards never need anything running, so most cards should hear nothing
37
+ * about it.
38
+ */
39
+ export declare function environmentBrief(started: Started, repo: string, needsRunning?: boolean): string;
@@ -0,0 +1,100 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ /**
5
+ * Get the project running, if it has told us how.
6
+ *
7
+ * The contract is deliberately thin: `.flaredeck/start.sh` exits 0 when the environment is ready,
8
+ * and prints what it started as `name=value` lines. Nothing else is prescribed.
9
+ *
10
+ * It is an ADAPTER, not a replacement. Most repos already know how to start themselves — an npm
11
+ * script, docker compose, a Makefile, something in scripts/ — and reimplementing that would mean
12
+ * two ways to start the project, drifting apart. The file exists so there is one KNOWN name the
13
+ * harness can call without guessing; what it contains should usually be a couple of lines
14
+ * delegating to whatever the repo already does.
15
+ *
16
+ * The printed endpoints matter more than they look. A script that takes a free port so parallel
17
+ * worktrees do not collide leaves the agent unable to guess where anything is — so the script
18
+ * says, and the agent is told.
19
+ */
20
+ export const START_SCRIPT = join('.flaredeck', 'start.sh');
21
+ const TIMEOUT_MS = 5 * 60 * 1000;
22
+ export function hasStartScript(repo) {
23
+ return existsSync(join(repo, START_SCRIPT));
24
+ }
25
+ export async function startEnvironment(repo, onStep) {
26
+ if (!hasStartScript(repo))
27
+ return { ran: false, ok: true, endpoints: {}, detail: '' };
28
+ onStep('starting the environment');
29
+ const { code, out } = await run(`bash ${START_SCRIPT}`, repo);
30
+ const endpoints = {};
31
+ for (const line of out.split('\n')) {
32
+ // `name=value`, one per line, value running to the end. Tolerant of surrounding noise, since
33
+ // a start script legitimately logs; and values may contain spaces, because what a project
34
+ // wants to announce is not always a URL — `tests=npm test` is just as useful.
35
+ const m = /^\s*([A-Za-z][\w.-]*)\s*=\s*(\S.*?)\s*$/.exec(line);
36
+ if (m?.[1] && m[2])
37
+ endpoints[m[1]] = m[2];
38
+ }
39
+ const names = Object.keys(endpoints);
40
+ onStep(code === 0
41
+ ? `environment ready${names.length ? ` — ${names.join(', ')}` : ''}`
42
+ : 'environment failed to start');
43
+ return {
44
+ ran: true,
45
+ ok: code === 0,
46
+ endpoints,
47
+ detail: out.trim().split('\n').slice(-5).join('\n').slice(0, 600),
48
+ };
49
+ }
50
+ /** What the agent is told about where things are, or why it cannot start. */
51
+ /**
52
+ * `needsRunning` is Jev's answer to whether this card can be done without the project running —
53
+ * asked in the intake call it already makes, so it costs nothing.
54
+ *
55
+ * It matters because this paragraph used to appear on EVERY card in a repo with no start script,
56
+ * and it told the agent to write the script "and commit it". An agent working a read-only card
57
+ * did exactly that: created `.flaredeck/start.sh`, committed it straight to a shared branch, and
58
+ * reported it as an accomplishment. It was not disobeying the card — the harness spoke last, and
59
+ * spoke in imperatives. Most cards never need anything running, so most cards should hear nothing
60
+ * about it.
61
+ */
62
+ export function environmentBrief(started, repo, needsRunning = false) {
63
+ if (!started.ran) {
64
+ if (!needsRunning)
65
+ return '';
66
+ return (`\n\nThis repo has no ${START_SCRIPT}, so nothing was started for you, and this card looks ` +
67
+ `like one that needs the project running. Find how the project already does it — an npm ` +
68
+ `script, docker compose, a Makefile, something in scripts/, or the README — and use that; ` +
69
+ `do not invent your own way. If you work it out and the card you are on permits changes, ` +
70
+ `you may leave ${START_SCRIPT} behind as a few lines calling it, ending with one ` +
71
+ `\`name=url\` line per thing it started (for example \`api=http://localhost:5000\`), so the ` +
72
+ `next session does not repeat the work. Leave it in your own branch with the rest of your ` +
73
+ `change — never commit it straight to a shared branch, and never on a card that asked you ` +
74
+ `to change nothing.`);
75
+ }
76
+ if (!started.ok) {
77
+ return (`\n\nSTOP — ${START_SCRIPT} failed, so the environment is not up:\n${started.detail}\n\n` +
78
+ `Do not diagnose the code: nothing is running, so anything you conclude would be wrong. If ` +
79
+ `the fix is obviously in the start script itself, fix that. Otherwise say on the card what ` +
80
+ `failed, call set-needs-human, and stop.`);
81
+ }
82
+ const listed = Object.entries(started.endpoints).map(([k, v]) => ` · ${k}: ${v}`).join('\n');
83
+ return listed
84
+ ? `\n\nThe environment is up and these are its addresses — use them rather than assuming ports:\n${listed}`
85
+ : `\n\nThe environment started cleanly (${repo}/${START_SCRIPT}).`;
86
+ }
87
+ function run(command, cwd) {
88
+ return new Promise((resolve) => {
89
+ const child = spawn(command, { cwd, shell: true, stdio: ['ignore', 'pipe', 'pipe'] });
90
+ let out = '';
91
+ const cap = (d) => { if (out.length < 8000)
92
+ out += String(d); };
93
+ child.stdout.on('data', cap);
94
+ child.stderr.on('data', cap);
95
+ const timer = setTimeout(() => { child.kill('SIGKILL'); resolve({ code: 124, out: `${out}\n(timed out)` }); }, TIMEOUT_MS);
96
+ child.on('close', (c) => { clearTimeout(timer); resolve({ code: c ?? 1, out }); });
97
+ child.on('error', (e) => { clearTimeout(timer); resolve({ code: 1, out: String(e) }); });
98
+ });
99
+ }
100
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type Discovered } from './flaredeck-proxy.js';
2
+ /**
3
+ * Is FlareDeck actually there, for this token, right now — and what does it offer?
4
+ *
5
+ * Asked before every turn, because an agent without FlareDeck is not an agent: it cannot read
6
+ * the card it was sent, comment on it, or ask for help. It will still produce a fluent answer —
7
+ * one explaining that it could not do the work — and a harness that then acknowledges the event
8
+ * has lost the card for good. That happened. This is the check that makes it impossible.
9
+ *
10
+ * What comes back is also what the session is given: the tool list becomes the in-process
11
+ * proxy for this turn, so the model can never see a tool the server did not just confirm.
12
+ */
13
+ export type Preflight = {
14
+ ok: true;
15
+ discovered: Discovered;
16
+ } | {
17
+ ok: false;
18
+ reason: string;
19
+ retryable: boolean;
20
+ };
21
+ export declare function preflightFlaredeck(mcpUrl: string, token: string): Promise<Preflight>;
@@ -0,0 +1,12 @@
1
+ import { discoverFlaredeck, FlaredeckUnavailable } from './flaredeck-proxy.js';
2
+ export async function preflightFlaredeck(mcpUrl, token) {
3
+ try {
4
+ return { ok: true, discovered: await discoverFlaredeck(mcpUrl, token) };
5
+ }
6
+ catch (e) {
7
+ if (e instanceof FlaredeckUnavailable)
8
+ return { ok: false, reason: e.message, retryable: e.retryable };
9
+ return { ok: false, reason: e instanceof Error ? e.message : String(e), retryable: true };
10
+ }
11
+ }
12
+ //# sourceMappingURL=flaredeck-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flaredeck-check.js","sourceRoot":"","sources":["../src/flaredeck-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAmB,MAAM,sBAAsB,CAAC;AAiBhG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,KAAa;IACpE,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;IAC1E,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,oBAAoB;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;QACvG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC5F,CAAC;AACH,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { type ZodTypeAny } from 'zod';
2
+ /**
3
+ * FlareDeck's tools, served to the session from inside this process.
4
+ *
5
+ * The CLI's own MCP client was the weak link. Its connection could sit 'pending' past the
6
+ * model's start, it held the bearer it was given at session start and never refreshed it — so a
7
+ * card that ran past the token's hour lost FlareDeck mid-turn — and a repo's own MCP config
8
+ * could shadow the server by name. Every one of those ended the same way: an agent explaining,
9
+ * fluently, that it could not read its card.
10
+ *
11
+ * So the harness is the client now. It asks FlareDeck for its tools, offers each one to the
12
+ * session under the same name, and forwards every call itself: a fresh token per call, a retry
13
+ * on a blip, and an error the model can act on when there is really nothing to be done. The
14
+ * session sees a server called `flaredeck` with the same tools it always had; what changed is
15
+ * who holds the connection.
16
+ */
17
+ export type FlaredeckTool = {
18
+ name: string;
19
+ description?: string;
20
+ inputSchema: JsonSchema;
21
+ };
22
+ export type Discovered = {
23
+ instructions: string;
24
+ tools: FlaredeckTool[];
25
+ };
26
+ type JsonSchema = {
27
+ type?: string | string[];
28
+ description?: string;
29
+ properties?: Record<string, JsonSchema>;
30
+ required?: string[];
31
+ items?: JsonSchema;
32
+ enum?: (string | number)[];
33
+ oneOf?: JsonSchema[];
34
+ anyOf?: JsonSchema[];
35
+ [k: string]: unknown;
36
+ };
37
+ /**
38
+ * One FlareDeck tool call made by the HARNESS, not the model — for the few things the supervisor
39
+ * has to be able to do on its own, like flagging a card it decided not to start.
40
+ */
41
+ export declare function callFlaredeckTool(mcpUrl: string, token: string, name: string, args: Record<string, unknown>): Promise<string>;
42
+ export declare class FlaredeckUnavailable extends Error {
43
+ readonly retryable: boolean;
44
+ constructor(message: string, retryable: boolean);
45
+ }
46
+ /** What FlareDeck offers this token: its instructions and its tools. Throws when it cannot say. */
47
+ export declare function discoverFlaredeck(mcpUrl: string, token: string): Promise<Discovered>;
48
+ /**
49
+ * JSON Schema → Zod, for the shapes FlareDeck actually uses: objects of strings, numbers,
50
+ * booleans, enums, arrays, nested objects, and the odd oneOf of those. Anything else becomes
51
+ * `any` with a note, rather than a startup failure over one exotic field — the tool still
52
+ * works; only the argument check is looser.
53
+ */
54
+ export declare function zodFor(schema: JsonSchema | undefined, notes: string[], path?: string): ZodTypeAny;
55
+ /** The in-process server: FlareDeck's tools, forwarded with a fresh token each time. */
56
+ export declare function flaredeckProxy(serverName: string, mcpUrl: string, token: () => Promise<string>, discovered: Discovered, warn?: (s: string) => void): {
57
+ server: unknown;
58
+ toolNames: string[];
59
+ };
60
+ export {};
@@ -0,0 +1,186 @@
1
+ import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
2
+ import { z } from 'zod';
3
+ const TIMEOUT_MS = 25_000;
4
+ async function rpc(mcpUrl, token, method, params) {
5
+ const res = await fetch(mcpUrl, {
6
+ method: 'POST',
7
+ headers: {
8
+ Authorization: `Bearer ${token}`,
9
+ 'Content-Type': 'application/json',
10
+ Accept: 'application/json, text/event-stream',
11
+ },
12
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, ...(params !== undefined ? { params } : {}) }),
13
+ signal: AbortSignal.timeout(TIMEOUT_MS),
14
+ });
15
+ const text = await res.text();
16
+ let body = null;
17
+ // Plain JSON today; SSE-framed if the server ever switches. Take the first JSON object either way.
18
+ const start = text.indexOf('{');
19
+ if (start >= 0) {
20
+ try {
21
+ body = JSON.parse(text.slice(start).split('\n').find((l) => l.trim().startsWith('{')) ?? '');
22
+ }
23
+ catch {
24
+ body = null;
25
+ }
26
+ }
27
+ return { status: res.status, body };
28
+ }
29
+ /**
30
+ * One FlareDeck tool call made by the HARNESS, not the model — for the few things the supervisor
31
+ * has to be able to do on its own, like flagging a card it decided not to start.
32
+ */
33
+ export async function callFlaredeckTool(mcpUrl, token, name, args) {
34
+ const res = await rpc(mcpUrl, token, 'tools/call', { name, arguments: args });
35
+ const result = res.body?.result;
36
+ const text = (result?.content ?? []).filter((c) => c?.type === 'text').map((c) => c.text).join('\n');
37
+ if (res.status >= 400 || res.body?.error || result?.isError)
38
+ throw new Error(text || res.body?.error?.message || `${name} failed (${res.status})`);
39
+ return text;
40
+ }
41
+ export class FlaredeckUnavailable extends Error {
42
+ retryable;
43
+ constructor(message, retryable) {
44
+ super(message);
45
+ this.retryable = retryable;
46
+ }
47
+ }
48
+ /** What FlareDeck offers this token: its instructions and its tools. Throws when it cannot say. */
49
+ export async function discoverFlaredeck(mcpUrl, token) {
50
+ const once = async () => {
51
+ let init;
52
+ try {
53
+ init = await rpc(mcpUrl, token, 'initialize', {
54
+ protocolVersion: '2025-03-26',
55
+ capabilities: {},
56
+ clientInfo: { name: 'flaredeck-agent', version: '1' },
57
+ });
58
+ }
59
+ catch (e) {
60
+ throw new FlaredeckUnavailable(`FlareDeck unreachable: ${e instanceof Error ? e.message : String(e)}`, true);
61
+ }
62
+ if (init.status === 401 || init.status === 403) {
63
+ throw new FlaredeckUnavailable(`FlareDeck rejected this token (${init.status}) — run \`flaredeck-agent login\``, false);
64
+ }
65
+ if (init.status >= 400)
66
+ throw new FlaredeckUnavailable(`FlareDeck answered ${init.status}`, true);
67
+ const instructions = String(init.body?.result?.instructions ?? '');
68
+ const list = await rpc(mcpUrl, token, 'tools/list');
69
+ if (list.status >= 400)
70
+ throw new FlaredeckUnavailable(`FlareDeck answered ${list.status} to tools/list`, true);
71
+ const tools = (list.body?.result?.tools ?? []);
72
+ if (!tools.length)
73
+ throw new FlaredeckUnavailable('FlareDeck listed no tools', true);
74
+ return { instructions, tools };
75
+ };
76
+ try {
77
+ return await once();
78
+ }
79
+ catch (e) {
80
+ if (!(e instanceof FlaredeckUnavailable) || !e.retryable)
81
+ throw e;
82
+ // One more try after a breath: a cold start should not cost a card a minute.
83
+ await new Promise((r) => setTimeout(r, 3000));
84
+ return once();
85
+ }
86
+ }
87
+ /**
88
+ * JSON Schema → Zod, for the shapes FlareDeck actually uses: objects of strings, numbers,
89
+ * booleans, enums, arrays, nested objects, and the odd oneOf of those. Anything else becomes
90
+ * `any` with a note, rather than a startup failure over one exotic field — the tool still
91
+ * works; only the argument check is looser.
92
+ */
93
+ export function zodFor(schema, notes, path = '') {
94
+ if (!schema)
95
+ return z.any();
96
+ const alts = schema.oneOf ?? schema.anyOf;
97
+ if (alts?.length) {
98
+ const members = alts.map((a, i) => zodFor(a, notes, `${path}|${i}`));
99
+ const out = members.length === 1 ? members[0] : z.union([members[0], members[1], ...members.slice(2)]);
100
+ return schema.description ? out.describe(schema.description) : out;
101
+ }
102
+ const type = Array.isArray(schema.type) ? schema.type.find((t) => t !== 'null') : schema.type;
103
+ let out;
104
+ if (schema.enum?.length) {
105
+ const strs = schema.enum.filter((v) => typeof v === 'string');
106
+ out = strs.length === schema.enum.length && strs.length > 0
107
+ ? z.enum(strs)
108
+ : z.union(schema.enum.map((v) => z.literal(v)));
109
+ }
110
+ else if (type === 'string')
111
+ out = z.string();
112
+ else if (type === 'number' || type === 'integer')
113
+ out = z.number();
114
+ else if (type === 'boolean')
115
+ out = z.boolean();
116
+ else if (type === 'array')
117
+ out = z.array(zodFor(schema.items, notes, `${path}[]`));
118
+ else if (type === 'object' || schema.properties) {
119
+ const shape = {};
120
+ const required = new Set(schema.required ?? []);
121
+ for (const [k, v] of Object.entries(schema.properties ?? {})) {
122
+ const inner = zodFor(v, notes, `${path}.${k}`);
123
+ shape[k] = required.has(k) ? inner : inner.optional();
124
+ }
125
+ out = z.object(shape).passthrough();
126
+ }
127
+ else {
128
+ notes.push(`${path || '(root)'}: no usable type, accepting anything`);
129
+ out = z.any();
130
+ }
131
+ return schema.description ? out.describe(schema.description) : out;
132
+ }
133
+ /** The in-process server: FlareDeck's tools, forwarded with a fresh token each time. */
134
+ export function flaredeckProxy(serverName, mcpUrl, token, discovered, warn = () => { }) {
135
+ const notes = [];
136
+ const tools = discovered.tools.map((t) => {
137
+ const shape = zodFor(t.inputSchema, notes, t.name).shape ?? {};
138
+ return tool(t.name, t.description ?? '', shape, async (args) => {
139
+ const sending = (args ?? {});
140
+ // Two retries on a blip; none on a rejection, which a retry will not change.
141
+ let last = '';
142
+ for (let attempt = 0; attempt < 3; attempt++) {
143
+ if (attempt)
144
+ await new Promise((r) => setTimeout(r, attempt * 1500));
145
+ let res;
146
+ try {
147
+ res = await rpc(mcpUrl, await token(), 'tools/call', { name: t.name, arguments: sending });
148
+ }
149
+ catch (e) {
150
+ last = `FlareDeck unreachable: ${e instanceof Error ? e.message : String(e)}`;
151
+ continue;
152
+ }
153
+ if (res.status === 401 || res.status === 403) {
154
+ return { content: [{ type: 'text', text: `❌ FlareDeck rejected the agent's token (${res.status}). The harness will need \`flaredeck-agent login\` — say so on the card with set-needs-human if you can, otherwise stop.` }], isError: true };
155
+ }
156
+ if (res.status >= 500) {
157
+ last = `FlareDeck answered ${res.status}`;
158
+ continue;
159
+ }
160
+ if (res.body?.error) {
161
+ return { content: [{ type: 'text', text: `❌ ${res.body.error.message ?? JSON.stringify(res.body.error)}` }], isError: true };
162
+ }
163
+ const result = res.body?.result;
164
+ if (!result) {
165
+ last = `FlareDeck answered ${res.status} with no result`;
166
+ continue;
167
+ }
168
+ return {
169
+ content: Array.isArray(result.content) && result.content.length ? result.content : [{ type: 'text', text: JSON.stringify(result) }],
170
+ ...(result.isError ? { isError: true } : {}),
171
+ };
172
+ }
173
+ return { content: [{ type: 'text', text: `❌ ${last} — tried three times. FlareDeck is not answering right now; do not pretend the call happened.` }], isError: true };
174
+ });
175
+ });
176
+ if (notes.length)
177
+ warn(`FlareDeck tool schemas partly loosened: ${notes.slice(0, 4).join('; ')}${notes.length > 4 ? ` (+${notes.length - 4})` : ''}`);
178
+ const server = createSdkMcpServer({
179
+ name: serverName,
180
+ version: '1.0.0',
181
+ ...(discovered.instructions ? { instructions: discovered.instructions } : {}),
182
+ tools,
183
+ });
184
+ return { server, toolNames: discovered.tools.map((t) => `mcp__${serverName}__${t.name}`) };
185
+ }
186
+ //# sourceMappingURL=flaredeck-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flaredeck-proxy.js","sourceRoot":"","sources":["../src/flaredeck-proxy.ts"],"names":[],"mappings":"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"}