cueline 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 (130) hide show
  1. package/.claude-plugin/plugin.json +8 -0
  2. package/.codex-plugin/plugin.json +18 -0
  3. package/LICENSE +21 -0
  4. package/README.ja.md +144 -0
  5. package/README.ko.md +144 -0
  6. package/README.md +144 -0
  7. package/README.zh-CN.md +144 -0
  8. package/README.zh-TW.md +144 -0
  9. package/THIRD_PARTY_NOTICES.md +11 -0
  10. package/bin/cueline +14 -0
  11. package/config/routing.default.json +28 -0
  12. package/config/routing.schema.json +58 -0
  13. package/dist/src/api.d.ts +34 -0
  14. package/dist/src/api.js +153 -0
  15. package/dist/src/api.js.map +1 -0
  16. package/dist/src/browser/browser-adapter.d.ts +15 -0
  17. package/dist/src/browser/browser-adapter.js +2 -0
  18. package/dist/src/browser/browser-adapter.js.map +1 -0
  19. package/dist/src/browser/codex-iab/bootstrap.d.ts +66 -0
  20. package/dist/src/browser/codex-iab/bootstrap.js +41 -0
  21. package/dist/src/browser/codex-iab/bootstrap.js.map +1 -0
  22. package/dist/src/browser/codex-iab/chatgpt-client.d.ts +10 -0
  23. package/dist/src/browser/codex-iab/chatgpt-client.js +180 -0
  24. package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -0
  25. package/dist/src/browser/codex-iab/selectors.d.ts +3 -0
  26. package/dist/src/browser/codex-iab/selectors.js +17 -0
  27. package/dist/src/browser/codex-iab/selectors.js.map +1 -0
  28. package/dist/src/cli/main.d.ts +7 -0
  29. package/dist/src/cli/main.js +196 -0
  30. package/dist/src/cli/main.js.map +1 -0
  31. package/dist/src/cli/skill-links.d.ts +2 -0
  32. package/dist/src/cli/skill-links.js +64 -0
  33. package/dist/src/cli/skill-links.js.map +1 -0
  34. package/dist/src/core/controller-loop.d.ts +36 -0
  35. package/dist/src/core/controller-loop.js +292 -0
  36. package/dist/src/core/controller-loop.js.map +1 -0
  37. package/dist/src/core/errors.d.ts +10 -0
  38. package/dist/src/core/errors.js +18 -0
  39. package/dist/src/core/errors.js.map +1 -0
  40. package/dist/src/core/ids.d.ts +5 -0
  41. package/dist/src/core/ids.js +51 -0
  42. package/dist/src/core/ids.js.map +1 -0
  43. package/dist/src/core/runtime.d.ts +12 -0
  44. package/dist/src/core/runtime.js +35 -0
  45. package/dist/src/core/runtime.js.map +1 -0
  46. package/dist/src/core/state-machine.d.ts +28 -0
  47. package/dist/src/core/state-machine.js +99 -0
  48. package/dist/src/core/state-machine.js.map +1 -0
  49. package/dist/src/jobs/locks.d.ts +8 -0
  50. package/dist/src/jobs/locks.js +24 -0
  51. package/dist/src/jobs/locks.js.map +1 -0
  52. package/dist/src/jobs/status.d.ts +22 -0
  53. package/dist/src/jobs/status.js +53 -0
  54. package/dist/src/jobs/status.js.map +1 -0
  55. package/dist/src/jobs/supervisor.d.ts +22 -0
  56. package/dist/src/jobs/supervisor.js +96 -0
  57. package/dist/src/jobs/supervisor.js.map +1 -0
  58. package/dist/src/protocol/parse-command.d.ts +2 -0
  59. package/dist/src/protocol/parse-command.js +23 -0
  60. package/dist/src/protocol/parse-command.js.map +1 -0
  61. package/dist/src/protocol/types.d.ts +67 -0
  62. package/dist/src/protocol/types.js +2 -0
  63. package/dist/src/protocol/types.js.map +1 -0
  64. package/dist/src/protocol/validate-command.d.ts +2 -0
  65. package/dist/src/protocol/validate-command.js +181 -0
  66. package/dist/src/protocol/validate-command.js.map +1 -0
  67. package/dist/src/router/availability.d.ts +3 -0
  68. package/dist/src/router/availability.js +55 -0
  69. package/dist/src/router/availability.js.map +1 -0
  70. package/dist/src/router/config-loader.d.ts +3 -0
  71. package/dist/src/router/config-loader.js +92 -0
  72. package/dist/src/router/config-loader.js.map +1 -0
  73. package/dist/src/router/materialize.d.ts +8 -0
  74. package/dist/src/router/materialize.js +39 -0
  75. package/dist/src/router/materialize.js.map +1 -0
  76. package/dist/src/router/resolver.d.ts +6 -0
  77. package/dist/src/router/resolver.js +55 -0
  78. package/dist/src/router/resolver.js.map +1 -0
  79. package/dist/src/router/types.d.ts +24 -0
  80. package/dist/src/router/types.js +2 -0
  81. package/dist/src/router/types.js.map +1 -0
  82. package/dist/src/runners/process-runner.d.ts +15 -0
  83. package/dist/src/runners/process-runner.js +124 -0
  84. package/dist/src/runners/process-runner.js.map +1 -0
  85. package/dist/src/runners/registry.d.ts +17 -0
  86. package/dist/src/runners/registry.js +57 -0
  87. package/dist/src/runners/registry.js.map +1 -0
  88. package/dist/src/runners/runner-adapter.d.ts +32 -0
  89. package/dist/src/runners/runner-adapter.js +4 -0
  90. package/dist/src/runners/runner-adapter.js.map +1 -0
  91. package/dist/src/state/atomic-write.d.ts +1 -0
  92. package/dist/src/state/atomic-write.js +27 -0
  93. package/dist/src/state/atomic-write.js.map +1 -0
  94. package/dist/src/state/event-log.d.ts +8 -0
  95. package/dist/src/state/event-log.js +56 -0
  96. package/dist/src/state/event-log.js.map +1 -0
  97. package/dist/src/state/paths.d.ts +9 -0
  98. package/dist/src/state/paths.js +37 -0
  99. package/dist/src/state/paths.js.map +1 -0
  100. package/dist/src/state/store.d.ts +23 -0
  101. package/dist/src/state/store.js +108 -0
  102. package/dist/src/state/store.js.map +1 -0
  103. package/dist/src/version.d.ts +1 -0
  104. package/dist/src/version.js +2 -0
  105. package/dist/src/version.js.map +1 -0
  106. package/docs/architecture.md +83 -0
  107. package/docs/assets/README.md +51 -0
  108. package/docs/assets/cueline-banner-dark.svg +41 -0
  109. package/docs/assets/cueline-banner-light.svg +41 -0
  110. package/docs/assets/cueline-loop-en.svg +77 -0
  111. package/docs/assets/cueline-loop-ja.svg +77 -0
  112. package/docs/assets/cueline-loop-ko.svg +77 -0
  113. package/docs/assets/cueline-loop-zh-CN.svg +77 -0
  114. package/docs/assets/cueline-loop-zh-TW.svg +77 -0
  115. package/docs/assets/cueline-mark-dark.svg +10 -0
  116. package/docs/assets/cueline-mark-light.svg +10 -0
  117. package/docs/assets/cueline-wordmark-dark.svg +19 -0
  118. package/docs/assets/cueline-wordmark-light.svg +19 -0
  119. package/docs/compatibility.md +60 -0
  120. package/docs/controller-protocol.md +106 -0
  121. package/docs/provenance.md +10 -0
  122. package/docs/runner-contract.md +61 -0
  123. package/docs/state-and-recovery.md +67 -0
  124. package/evals/evals.json +41 -0
  125. package/install.sh +70 -0
  126. package/package.json +73 -0
  127. package/schemas/controller-command.schema.json +53 -0
  128. package/schemas/controller-observation.schema.json +32 -0
  129. package/skills/cueline/SKILL.md +80 -0
  130. package/skills/cueline/agents/openai.yaml +4 -0
@@ -0,0 +1,180 @@
1
+ import { CueLineError } from "../../core/errors.js";
2
+ import { readPageChatState, resolveIabBrowser, } from "./bootstrap.js";
3
+ import { CHATGPT_URL, COMPOSER_TEXTBOX_NAMES, SEND_BUTTON_NAMES } from "./selectors.js";
4
+ const DEFAULT_TIMEOUT_MS = 30 * 60 * 1_000;
5
+ const DEFAULT_POLL_INTERVAL_MS = 1_000;
6
+ const DEFAULT_STABLE_MS = 1_500;
7
+ const COMPOSER_HYDRATION_TIMEOUT_MS = 5_000;
8
+ const CONTENTEDITABLE_COMPOSER_SELECTOR = '#prompt-textarea[contenteditable="true"]';
9
+ function delay(milliseconds) {
10
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
11
+ }
12
+ async function findUniqueLocator(tab, role, names) {
13
+ for (const name of names) {
14
+ const locator = tab.playwright.getByRole(role, { name });
15
+ if ((await locator.count()) === 1) {
16
+ return locator;
17
+ }
18
+ }
19
+ return undefined;
20
+ }
21
+ async function findHydratedComposer(tab) {
22
+ if (!tab.playwright.locator)
23
+ return undefined;
24
+ const composer = tab.playwright.locator(CONTENTEDITABLE_COMPOSER_SELECTOR);
25
+ try {
26
+ await composer.waitFor?.({ state: "visible", timeoutMs: COMPOSER_HYDRATION_TIMEOUT_MS });
27
+ return (await composer.count()) === 1 ? composer : undefined;
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ }
33
+ function isConversationUrl(url) {
34
+ return /^https:\/\/chatgpt\.com\/c\/[A-Za-z0-9-]+/.test(url);
35
+ }
36
+ function isTransientClickError(error) {
37
+ const message = error instanceof Error ? error.message : String(error);
38
+ return /deadline exceeded|timed? out|timeout|detached|stale|not enabled|not visible/i.test(message);
39
+ }
40
+ class CodexIabAdapter {
41
+ #options;
42
+ #browser;
43
+ #tab;
44
+ constructor(options) {
45
+ this.#options = {
46
+ timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
47
+ pollIntervalMs: options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,
48
+ stableMs: options.stableMs ?? DEFAULT_STABLE_MS,
49
+ ...(options.browser === undefined ? {} : { browser: options.browser }),
50
+ ...(options.conversationUrl === undefined ? {} : { conversationUrl: options.conversationUrl }),
51
+ };
52
+ }
53
+ async #getBrowser() {
54
+ this.#browser ??= await resolveIabBrowser(this.#options.browser);
55
+ return this.#browser;
56
+ }
57
+ async #getTab() {
58
+ if (this.#tab)
59
+ return this.#tab;
60
+ const browser = await this.#getBrowser();
61
+ const targetUrl = this.#options.conversationUrl;
62
+ const matchesTarget = (url) => targetUrl ? url === targetUrl : url.startsWith(CHATGPT_URL);
63
+ const selected = await browser.tabs.selected?.().catch(() => undefined);
64
+ if (selected && matchesTarget((await selected.url().catch(() => "")) ?? "")) {
65
+ this.#tab = selected;
66
+ return selected;
67
+ }
68
+ const sessionTabs = await browser.tabs.list?.().catch(() => []);
69
+ const sessionCandidate = sessionTabs?.find((tab) => matchesTarget(String(tab.url ?? "")));
70
+ let tab;
71
+ if (sessionCandidate?.id && browser.tabs.get) {
72
+ tab = await browser.tabs.get(sessionCandidate.id);
73
+ }
74
+ const openTabs = tab === undefined ? await browser.user?.openTabs?.().catch(() => []) : [];
75
+ const candidate = openTabs?.find((openTab) => {
76
+ const url = String(openTab.url ?? "");
77
+ return matchesTarget(url);
78
+ });
79
+ if (tab === undefined && candidate && browser.user?.claimTab) {
80
+ tab = await browser.user.claimTab(candidate);
81
+ }
82
+ else if (tab === undefined) {
83
+ tab = await browser.tabs.new();
84
+ await tab.goto(targetUrl ?? CHATGPT_URL);
85
+ }
86
+ this.#tab = tab;
87
+ await tab.playwright.waitForLoadState?.({
88
+ state: "domcontentloaded",
89
+ timeoutMs: 30_000,
90
+ });
91
+ return tab;
92
+ }
93
+ async #submissionStarted(tab, previousUrl) {
94
+ const currentUrl = (await tab.url().catch(() => previousUrl)) ?? previousUrl;
95
+ if (!isConversationUrl(previousUrl) && isConversationUrl(currentUrl)) {
96
+ return true;
97
+ }
98
+ return (await readPageChatState(tab).catch(() => ({
99
+ isAnswering: false,
100
+ assistantText: "",
101
+ assistantMessageCount: 0,
102
+ }))).isAnswering;
103
+ }
104
+ async #clickSend(tab) {
105
+ const previousUrl = (await tab.url()) ?? "";
106
+ for (let attempt = 0; attempt < 2; attempt += 1) {
107
+ const button = await findUniqueLocator(tab, "button", SEND_BUTTON_NAMES);
108
+ if (!button) {
109
+ if (attempt > 0 && await this.#submissionStarted(tab, previousUrl)) {
110
+ return;
111
+ }
112
+ throw new CueLineError("SEND_BUTTON_MISSING", "Could not find ChatGPT's send button.");
113
+ }
114
+ try {
115
+ await button.click({ timeoutMs: 10_000 });
116
+ return;
117
+ }
118
+ catch (error) {
119
+ if (await this.#submissionStarted(tab, previousUrl)) {
120
+ return;
121
+ }
122
+ if (attempt === 1 || !isTransientClickError(error)) {
123
+ throw error;
124
+ }
125
+ await tab.playwright.domSnapshot();
126
+ await tab.playwright.waitForTimeout(250);
127
+ }
128
+ }
129
+ }
130
+ async #waitForCompletion(tab, baseline) {
131
+ const deadline = Date.now() + this.#options.timeoutMs;
132
+ let stableText = "";
133
+ let stableSince = 0;
134
+ let responseStarted = false;
135
+ while (Date.now() < deadline) {
136
+ const state = await readPageChatState(tab);
137
+ if (state.isAnswering || state.assistantMessageCount > baseline.assistantMessageCount) {
138
+ responseStarted = true;
139
+ }
140
+ if (responseStarted && !state.isAnswering && state.assistantText !== "") {
141
+ if (state.assistantText !== stableText) {
142
+ stableText = state.assistantText;
143
+ stableSince = Date.now();
144
+ }
145
+ if (Date.now() - stableSince >= this.#options.stableMs) {
146
+ return stableText;
147
+ }
148
+ }
149
+ else {
150
+ stableText = state.assistantText;
151
+ stableSince = Date.now();
152
+ }
153
+ await delay(this.#options.pollIntervalMs);
154
+ }
155
+ throw new CueLineError("CHATGPT_RESPONSE_TIMEOUT", "ChatGPT did not finish before timeout.");
156
+ }
157
+ async sendTurn(input) {
158
+ const tab = await this.#getTab();
159
+ const baseline = await readPageChatState(tab);
160
+ const composer = (await findHydratedComposer(tab)) ??
161
+ (await findUniqueLocator(tab, "textbox", COMPOSER_TEXTBOX_NAMES));
162
+ if (!composer) {
163
+ throw new CueLineError("COMPOSER_MISSING", "Could not find ChatGPT's message composer.");
164
+ }
165
+ await composer.fill(input.prompt, {});
166
+ await this.#clickSend(tab);
167
+ const text = await this.#waitForCompletion(tab, baseline);
168
+ const conversationUrl = (await tab.url()) ?? "";
169
+ const title = await tab.title?.();
170
+ return {
171
+ text,
172
+ ...(conversationUrl === "" ? {} : { conversationUrl }),
173
+ ...(title === undefined || title === "" ? {} : { title }),
174
+ };
175
+ }
176
+ }
177
+ export function createCodexIabAdapter(options = {}) {
178
+ return new CodexIabAdapter(options);
179
+ }
180
+ //# sourceMappingURL=chatgpt-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-client.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/chatgpt-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const COMPOSER_TEXTBOX_NAMES: readonly ["Message ChatGPT", "Chat with ChatGPT", "與 ChatGPT 對話", "傳訊息給 ChatGPT", "和 ChatGPT 聊天"];
2
+ export declare const SEND_BUTTON_NAMES: readonly ["Send prompt", "Send message", "傳送提示", "傳送訊息", "送出提示", "送出訊息"];
3
+ export declare const CHATGPT_URL = "https://chatgpt.com/";
@@ -0,0 +1,17 @@
1
+ export const COMPOSER_TEXTBOX_NAMES = [
2
+ "Message ChatGPT",
3
+ "Chat with ChatGPT",
4
+ "與 ChatGPT 對話",
5
+ "傳訊息給 ChatGPT",
6
+ "和 ChatGPT 聊天",
7
+ ];
8
+ export const SEND_BUTTON_NAMES = [
9
+ "Send prompt",
10
+ "Send message",
11
+ "傳送提示",
12
+ "傳送訊息",
13
+ "送出提示",
14
+ "送出訊息",
15
+ ];
16
+ export const CHATGPT_URL = "https://chatgpt.com/";
17
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/selectors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,iBAAiB;IACjB,mBAAmB;IACnB,cAAc;IACd,cAAc;IACd,cAAc;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,aAAa;IACb,cAAc;IACd,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACE,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ interface CliIo {
3
+ stdout: (line: string) => void;
4
+ stderr: (line: string) => void;
5
+ }
6
+ export declare function main(args?: readonly string[], environment?: NodeJS.ProcessEnv, io?: CliIo): Promise<number>;
7
+ export {};
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ import { readdir, readFile } from "node:fs/promises";
3
+ import { realpathSync } from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
+ import { routingConfigPath } from "../api.js";
7
+ import { CueLineError } from "../core/errors.js";
8
+ import { executableAvailability } from "../router/availability.js";
9
+ import { loadRoutingConfig } from "../router/config-loader.js";
10
+ import { resolveRoute } from "../router/resolver.js";
11
+ import { defaultCueLineHome } from "../state/paths.js";
12
+ import { CUELINE_VERSION } from "../version.js";
13
+ import { installSkill, uninstallSkill } from "./skill-links.js";
14
+ const processIo = {
15
+ stdout: (line) => process.stdout.write(`${line}\n`),
16
+ stderr: (line) => process.stderr.write(`${line}\n`),
17
+ };
18
+ function usage() {
19
+ return "usage: cueline <install|uninstall|doctor|routing|jobs|api path|config path|help|version>";
20
+ }
21
+ function help() {
22
+ return [
23
+ "CueLine — a ChatGPT web conversation directs; this machine executes.",
24
+ "",
25
+ usage(),
26
+ "",
27
+ "commands:",
28
+ " install link the bundled skill into Codex",
29
+ " uninstall remove only the skill link owned by this package",
30
+ " doctor report Node, routing config, state home, and usable lanes",
31
+ " routing list every lane and the candidate that would be selected",
32
+ " jobs list persisted local jobs, oldest first",
33
+ " api path print the bundled API module path",
34
+ " config path print the routing configuration file in effect",
35
+ " help print this text",
36
+ " version print the CueLine version",
37
+ "",
38
+ "flags:",
39
+ " -h, --help same as `cueline help`",
40
+ " -v, --version same as `cueline version`",
41
+ "",
42
+ "environment:",
43
+ " CUELINE_HOME run and job state directory (default: ~/.cueline)",
44
+ " CUELINE_CONFIG routing configuration file (default: the bundled config)",
45
+ "",
46
+ "exit codes:",
47
+ " 0 the command answered and the checked surface is usable",
48
+ " 1 the command ran but the surface is degraded or unreadable",
49
+ " 2 the arguments were not understood",
50
+ "",
51
+ "These commands only diagnose the local installation. A live run is driven",
52
+ "through the imported API inside Codex, where the built-in Browser lives.",
53
+ ].join("\n");
54
+ }
55
+ function errorMessage(error) {
56
+ if (error instanceof CueLineError)
57
+ return `${error.code}: ${error.message}`;
58
+ return error instanceof Error ? error.message : String(error);
59
+ }
60
+ async function routingCommand(environment, io) {
61
+ const config = await loadRoutingConfig(routingConfigPath(environment));
62
+ const availability = executableAvailability(environment);
63
+ let available = 0;
64
+ for (const [lane, laneConfig] of Object.entries(config.lanes)) {
65
+ if (!laneConfig.enabled) {
66
+ io.stdout(`${lane}\t-\tdisabled`);
67
+ continue;
68
+ }
69
+ try {
70
+ const route = resolveRoute(lane, config, availability);
71
+ available += 1;
72
+ io.stdout(`${lane}\t${route.candidate.id}\tavailable`);
73
+ }
74
+ catch (error) {
75
+ io.stdout(`${lane}\t-\tunavailable (${errorMessage(error)})`);
76
+ }
77
+ }
78
+ return available > 0 ? 0 : 1;
79
+ }
80
+ async function readJobs(home) {
81
+ const directory = path.join(home, "jobs");
82
+ let names;
83
+ try {
84
+ names = await readdir(directory);
85
+ }
86
+ catch (error) {
87
+ if (error.code === "ENOENT")
88
+ return [];
89
+ throw error;
90
+ }
91
+ const statuses = [];
92
+ for (const name of names.filter((candidate) => candidate.endsWith(".json")).sort()) {
93
+ try {
94
+ statuses.push(JSON.parse(await readFile(path.join(directory, name), "utf8")));
95
+ }
96
+ catch (error) {
97
+ throw new CueLineError("JOB_STATUS_INVALID", `unable to parse job status: ${name}`, {
98
+ cause: error,
99
+ });
100
+ }
101
+ }
102
+ return statuses.sort((left, right) => left.startedAt.localeCompare(right.startedAt));
103
+ }
104
+ async function jobsCommand(environment, io) {
105
+ const jobs = await readJobs(defaultCueLineHome(environment));
106
+ if (jobs.length === 0) {
107
+ io.stdout("No jobs.");
108
+ return 0;
109
+ }
110
+ for (const job of jobs) {
111
+ io.stdout(`${job.jobId}\t${job.execution}\t${job.status}\t${job.startedAt}`);
112
+ }
113
+ return 0;
114
+ }
115
+ async function doctorCommand(environment, io) {
116
+ const configPath = routingConfigPath(environment);
117
+ const home = defaultCueLineHome(environment);
118
+ const major = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10);
119
+ const nodeOk = major >= 22;
120
+ const config = await loadRoutingConfig(configPath);
121
+ const availability = executableAvailability(environment);
122
+ let availableLanes = 0;
123
+ for (const [lane, laneConfig] of Object.entries(config.lanes)) {
124
+ if (!laneConfig.enabled)
125
+ continue;
126
+ try {
127
+ resolveRoute(lane, config, availability);
128
+ availableLanes += 1;
129
+ }
130
+ catch {
131
+ // Doctor reports the aggregate below; `cueline routing` shows lane details.
132
+ }
133
+ }
134
+ const ok = nodeOk && availableLanes > 0;
135
+ io.stdout(`CueLine ${CUELINE_VERSION}`);
136
+ io.stdout(`status\t${ok ? "ok" : "degraded"}`);
137
+ io.stdout(`node\t${process.versions.node}\t${nodeOk ? "ok" : "requires >=22"}`);
138
+ io.stdout(`config\t${configPath}\tvalid`);
139
+ io.stdout(`home\t${home}`);
140
+ io.stdout(`available_lanes\t${availableLanes}`);
141
+ return ok ? 0 : 1;
142
+ }
143
+ export async function main(args = process.argv.slice(2), environment = process.env, io = processIo) {
144
+ try {
145
+ if (args.length === 0) {
146
+ io.stdout(help());
147
+ return 0;
148
+ }
149
+ if (args.length === 1 && ["help", "--help", "-h"].includes(args[0])) {
150
+ io.stdout(help());
151
+ return 0;
152
+ }
153
+ if (args.length === 1 && ["version", "--version", "-v"].includes(args[0])) {
154
+ io.stdout(CUELINE_VERSION);
155
+ return 0;
156
+ }
157
+ if (args[0] === "config" && args[1] === "path" && args.length === 2) {
158
+ io.stdout(routingConfigPath(environment));
159
+ return 0;
160
+ }
161
+ if (args[0] === "api" && args[1] === "path" && args.length === 2) {
162
+ io.stdout(fileURLToPath(new URL("../api.js", import.meta.url)));
163
+ return 0;
164
+ }
165
+ if (args[0] === "install" && args.length === 1) {
166
+ io.stdout(await installSkill(environment));
167
+ return 0;
168
+ }
169
+ if (args[0] === "uninstall" && args.length === 1) {
170
+ io.stdout(await uninstallSkill(environment));
171
+ return 0;
172
+ }
173
+ if (args[0] === "routing" && args.length === 1) {
174
+ return routingCommand(environment, io);
175
+ }
176
+ if (args[0] === "jobs" && args.length === 1) {
177
+ return jobsCommand(environment, io);
178
+ }
179
+ if (args[0] === "doctor" && args.length === 1) {
180
+ return doctorCommand(environment, io);
181
+ }
182
+ io.stderr(`cueline: unrecognized command: ${args.join(" ")}`);
183
+ io.stderr(usage());
184
+ io.stderr("try `cueline help`");
185
+ return 2;
186
+ }
187
+ catch (error) {
188
+ io.stderr(`CueLine: ${errorMessage(error)}`);
189
+ return 1;
190
+ }
191
+ }
192
+ if (process.argv[1] !== undefined &&
193
+ realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
194
+ process.exitCode = await main();
195
+ }
196
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function installSkill(environment: NodeJS.ProcessEnv): Promise<string>;
2
+ export declare function uninstallSkill(environment: NodeJS.ProcessEnv): Promise<string>;
@@ -0,0 +1,64 @@
1
+ import { access, lstat, mkdir, readlink, symlink, unlink } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const skillSource = fileURLToPath(new URL("../../../skills/cueline", import.meta.url));
6
+ function codexHome(environment) {
7
+ if (environment.CODEX_HOME)
8
+ return path.resolve(environment.CODEX_HOME);
9
+ const home = environment.HOME || homedir();
10
+ return path.join(home, ".codex");
11
+ }
12
+ function skillTarget(environment) {
13
+ return path.join(codexHome(environment), "skills", "cueline");
14
+ }
15
+ async function pathExists(candidate) {
16
+ try {
17
+ await lstat(candidate);
18
+ return true;
19
+ }
20
+ catch (error) {
21
+ if (error.code === "ENOENT")
22
+ return false;
23
+ throw error;
24
+ }
25
+ }
26
+ async function linkMatches(target, source) {
27
+ try {
28
+ const details = await lstat(target);
29
+ if (!details.isSymbolicLink())
30
+ return false;
31
+ const linked = await readlink(target);
32
+ return path.resolve(path.dirname(target), linked) === path.resolve(source);
33
+ }
34
+ catch (error) {
35
+ if (error.code === "ENOENT")
36
+ return false;
37
+ throw error;
38
+ }
39
+ }
40
+ export async function installSkill(environment) {
41
+ const target = skillTarget(environment);
42
+ await access(path.join(skillSource, "SKILL.md"));
43
+ if (await linkMatches(target, skillSource)) {
44
+ return `CueLine skill already installed: ${target}`;
45
+ }
46
+ if (await pathExists(target)) {
47
+ throw new Error(`refusing to replace foreign path: ${target}`);
48
+ }
49
+ await mkdir(path.dirname(target), { recursive: true });
50
+ await symlink(skillSource, target, process.platform === "win32" ? "junction" : "dir");
51
+ return `CueLine skill installed: ${target}`;
52
+ }
53
+ export async function uninstallSkill(environment) {
54
+ const target = skillTarget(environment);
55
+ if (await linkMatches(target, skillSource)) {
56
+ await unlink(target);
57
+ return `CueLine skill removed: ${target}`;
58
+ }
59
+ if (await pathExists(target)) {
60
+ return `CueLine preserved foreign path: ${target}`;
61
+ }
62
+ return `CueLine skill not installed: ${target}`;
63
+ }
64
+ //# sourceMappingURL=skill-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-links.js","sourceRoot":"","sources":["../../../src/cli/skill-links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { BrowserAdapter } from "../browser/browser-adapter.js";
2
+ import type { JobStatus } from "../jobs/status.js";
3
+ import { type ControllerJobSpec } from "../protocol/types.js";
4
+ import type { RunnerSpec } from "../runners/runner-adapter.js";
5
+ import { type CueLineRunState, type CueLineRunStatus } from "./state-machine.js";
6
+ export interface JobSupervisorLike {
7
+ start(spec: RunnerSpec): Promise<JobStatus>;
8
+ waitForCompletion(jobId: string): Promise<JobStatus>;
9
+ inspect(jobId: string): Promise<JobStatus>;
10
+ }
11
+ export interface ControllerRuntimeOptions {
12
+ browser: BrowserAdapter;
13
+ jobSupervisor: JobSupervisorLike;
14
+ resolveRunnerSpec: (jobId: string, job: ControllerJobSpec) => RunnerSpec;
15
+ home?: string;
16
+ maxRounds?: number;
17
+ maxRepairAttempts?: number;
18
+ controllerInstructions?: readonly string[];
19
+ now?: () => Date;
20
+ }
21
+ export interface ControllerLoopOptions extends ControllerRuntimeOptions {
22
+ request: string;
23
+ runId?: string;
24
+ }
25
+ export interface ContinueControllerLoopOptions extends ControllerRuntimeOptions {
26
+ runId: string;
27
+ }
28
+ export interface CueLineResult {
29
+ runId: string;
30
+ status: Exclude<CueLineRunStatus, "running" | "failed">;
31
+ finalDeliveryText?: string;
32
+ conversationUrl?: string;
33
+ state: CueLineRunState;
34
+ }
35
+ export declare function runControllerLoop(options: ControllerLoopOptions): Promise<CueLineResult>;
36
+ export declare function continueControllerLoop(options: ContinueControllerLoopOptions): Promise<CueLineResult>;