@aligndottech/cli 0.46.1 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/connect-agents.d.ts.map +1 -1
- package/dist/commands/connect-agents.js +13 -3
- package/dist/commands/connect-agents.js.map +1 -1
- package/dist/commands/default-action.d.ts +5 -5
- package/dist/commands/default-action.d.ts.map +1 -1
- package/dist/commands/default-action.js +40 -13
- package/dist/commands/default-action.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +12 -4
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +2 -0
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/setup.d.ts +2 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +84 -114
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/use.d.ts +32 -0
- package/dist/commands/use.d.ts.map +1 -0
- package/dist/commands/use.js +94 -0
- package/dist/commands/use.js.map +1 -0
- package/dist/lib/agent-rules.d.ts +18 -5
- package/dist/lib/agent-rules.d.ts.map +1 -1
- package/dist/lib/agent-rules.js +81 -22
- package/dist/lib/agent-rules.js.map +1 -1
- package/dist/lib/config.d.ts +14 -10
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +64 -17
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/foreign-env.d.ts +23 -0
- package/dist/lib/foreign-env.d.ts.map +1 -0
- package/dist/lib/foreign-env.js +27 -0
- package/dist/lib/foreign-env.js.map +1 -0
- package/dist/lib/gateway-client.d.ts +5 -1
- package/dist/lib/gateway-client.d.ts.map +1 -1
- package/dist/lib/gateway-client.js +10 -2
- package/dist/lib/gateway-client.js.map +1 -1
- package/dist/lib/launch/adapters/args.d.ts +7 -0
- package/dist/lib/launch/adapters/args.d.ts.map +1 -0
- package/dist/lib/launch/adapters/args.js +10 -0
- package/dist/lib/launch/adapters/args.js.map +1 -0
- package/dist/lib/launch/adapters/claude-code.d.ts +39 -0
- package/dist/lib/launch/adapters/claude-code.d.ts.map +1 -0
- package/dist/lib/launch/adapters/claude-code.js +39 -0
- package/dist/lib/launch/adapters/claude-code.js.map +1 -0
- package/dist/lib/launch/adapters/cursor.d.ts +18 -0
- package/dist/lib/launch/adapters/cursor.d.ts.map +1 -0
- package/dist/lib/launch/adapters/cursor.js +27 -0
- package/dist/lib/launch/adapters/cursor.js.map +1 -0
- package/dist/lib/launch/adapters/opencode.d.ts +21 -0
- package/dist/lib/launch/adapters/opencode.d.ts.map +1 -0
- package/dist/lib/launch/adapters/opencode.js +64 -0
- package/dist/lib/launch/adapters/opencode.js.map +1 -0
- package/dist/lib/launch/adapters/pi.d.ts +23 -0
- package/dist/lib/launch/adapters/pi.d.ts.map +1 -0
- package/dist/lib/launch/adapters/pi.js +35 -0
- package/dist/lib/launch/adapters/pi.js.map +1 -0
- package/dist/lib/launch/agents.d.ts +24 -0
- package/dist/lib/launch/agents.d.ts.map +1 -0
- package/dist/lib/launch/agents.js +22 -0
- package/dist/lib/launch/agents.js.map +1 -0
- package/dist/lib/launch/config-writes.d.ts +37 -0
- package/dist/lib/launch/config-writes.d.ts.map +1 -0
- package/dist/lib/launch/config-writes.js +26 -0
- package/dist/lib/launch/config-writes.js.map +1 -0
- package/dist/lib/launch/cursor-state.d.ts +14 -0
- package/dist/lib/launch/cursor-state.d.ts.map +1 -0
- package/dist/lib/launch/cursor-state.js +26 -0
- package/dist/lib/launch/cursor-state.js.map +1 -0
- package/dist/lib/launch/detect.d.ts +7 -0
- package/dist/lib/launch/detect.d.ts.map +1 -0
- package/dist/lib/launch/detect.js +34 -0
- package/dist/lib/launch/detect.js.map +1 -0
- package/dist/lib/launch/launch-files.d.ts +15 -0
- package/dist/lib/launch/launch-files.d.ts.map +1 -0
- package/dist/lib/launch/launch-files.js +56 -0
- package/dist/lib/launch/launch-files.js.map +1 -0
- package/dist/lib/launch/launch.d.ts +59 -0
- package/dist/lib/launch/launch.d.ts.map +1 -0
- package/dist/lib/launch/launch.js +198 -0
- package/dist/lib/launch/launch.js.map +1 -0
- package/dist/lib/launch/opencode-state.d.ts +16 -0
- package/dist/lib/launch/opencode-state.d.ts.map +1 -0
- package/dist/lib/launch/opencode-state.js +103 -0
- package/dist/lib/launch/opencode-state.js.map +1 -0
- package/dist/lib/launch/pi-state.d.ts +23 -0
- package/dist/lib/launch/pi-state.d.ts.map +1 -0
- package/dist/lib/launch/pi-state.js +112 -0
- package/dist/lib/launch/pi-state.js.map +1 -0
- package/dist/lib/launch/pick-agent.d.ts +28 -0
- package/dist/lib/launch/pick-agent.d.ts.map +1 -0
- package/dist/lib/launch/pick-agent.js +63 -0
- package/dist/lib/launch/pick-agent.js.map +1 -0
- package/dist/lib/launch/project-state.d.ts +21 -0
- package/dist/lib/launch/project-state.d.ts.map +1 -0
- package/dist/lib/launch/project-state.js +100 -0
- package/dist/lib/launch/project-state.js.map +1 -0
- package/dist/lib/launch/run-agent.d.ts +21 -0
- package/dist/lib/launch/run-agent.d.ts.map +1 -0
- package/dist/lib/launch/run-agent.js +69 -0
- package/dist/lib/launch/run-agent.js.map +1 -0
- package/dist/lib/local-gateway-client.d.ts +4 -4
- package/dist/lib/local-gateway-client.d.ts.map +1 -1
- package/dist/lib/local-gateway-client.js +3 -1
- package/dist/lib/local-gateway-client.js.map +1 -1
- package/dist/lib/mcp-setup.d.ts +9 -2
- package/dist/lib/mcp-setup.d.ts.map +1 -1
- package/dist/lib/mcp-setup.js +104 -28
- package/dist/lib/mcp-setup.js.map +1 -1
- package/dist/lib/safe-config-write.d.ts +140 -0
- package/dist/lib/safe-config-write.d.ts.map +1 -0
- package/dist/lib/safe-config-write.js +701 -0
- package/dist/lib/safe-config-write.js.map +1 -0
- package/dist/lib/setup-route.d.ts +26 -0
- package/dist/lib/setup-route.d.ts.map +1 -0
- package/dist/lib/setup-route.js +36 -0
- package/dist/lib/setup-route.js.map +1 -0
- package/dist/lib/usage-telemetry.d.ts +6 -2
- package/dist/lib/usage-telemetry.d.ts.map +1 -1
- package/dist/lib/usage-telemetry.js +6 -2
- package/dist/lib/usage-telemetry.js.map +1 -1
- package/dist/lib/user-hooks.d.ts +2 -1
- package/dist/lib/user-hooks.d.ts.map +1 -1
- package/dist/lib/user-hooks.js +42 -10
- package/dist/lib/user-hooks.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.js","sourceRoot":"","sources":["../../../../src/lib/launch/adapters/pi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAa9C,mFAAmF;AACnF,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAC3C,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,CAAkB;IAC9C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,QAAQ,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,CAAC,CAAC,mBAAmB,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAChJ,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACvJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentName } from '../sessions/types.js';
|
|
2
|
+
export interface LaunchAgent {
|
|
3
|
+
name: AgentName;
|
|
4
|
+
label: string;
|
|
5
|
+
bin: string;
|
|
6
|
+
/** per-session: nothing written to the user's config. written-once: later phases. */
|
|
7
|
+
injection: 'per-session' | 'written-once';
|
|
8
|
+
/** A launch target today. Later phases flip more entries to true; nothing else changes. */
|
|
9
|
+
supported: boolean;
|
|
10
|
+
install: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const LAUNCH_AGENTS: readonly LaunchAgent[];
|
|
13
|
+
export declare function agentByName(name: string | undefined): LaunchAgent | undefined;
|
|
14
|
+
export declare const supportedAgents: () => LaunchAgent[];
|
|
15
|
+
/**
|
|
16
|
+
* The agent's binary on PATH, and where. Only `bin` is accepted: for Cursor that is `cursor-agent`,
|
|
17
|
+
* which its installer always creates. Cursor's docs also call the command `agent`, but that name
|
|
18
|
+
* is too generic to run on a guess, so a bare `agent` on PATH is not Cursor.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveAgentBin(a: LaunchAgent, find: (bin: string, env: Record<string, string | undefined>, platform: string) => string | null, env: Record<string, string | undefined>, platform: string): {
|
|
21
|
+
bin: string;
|
|
22
|
+
path: string;
|
|
23
|
+
} | null;
|
|
24
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,SAAS,EAAE,aAAa,GAAG,cAAc,CAAC;IAC1C,2FAA2F;IAC3F,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAO/C,CAAC;AAEF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAE7E;AAED,eAAO,MAAM,eAAe,QAAO,WAAW,EAA8C,CAAC;AAE7F;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,CAAC,EAAE,WAAW,EACd,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EAC/F,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,QAAQ,EAAE,MAAM,GACf;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAGtC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const LAUNCH_AGENTS = [
|
|
2
|
+
{ name: 'claude-code', label: 'Claude Code', bin: 'claude', injection: 'per-session', supported: true, install: 'npm i -g @anthropic-ai/claude-code' },
|
|
3
|
+
{ name: 'codex', label: 'Codex', bin: 'codex', injection: 'per-session', supported: false, install: 'npm i -g @openai/codex' },
|
|
4
|
+
{ name: 'cursor', label: 'Cursor', bin: 'cursor-agent', injection: 'written-once', supported: true, install: 'https://cursor.com/cli' },
|
|
5
|
+
{ name: 'gemini-cli', label: 'Gemini CLI', bin: 'gemini', injection: 'per-session', supported: false, install: 'npm i -g @google/gemini-cli' },
|
|
6
|
+
{ name: 'opencode', label: 'OpenCode', bin: 'opencode', injection: 'per-session', supported: true, install: 'npm i -g opencode-ai' },
|
|
7
|
+
{ name: 'pi', label: 'pi', bin: 'pi', injection: 'written-once', supported: true, install: 'https://pi.dev' },
|
|
8
|
+
];
|
|
9
|
+
export function agentByName(name) {
|
|
10
|
+
return LAUNCH_AGENTS.find((a) => a.name === name);
|
|
11
|
+
}
|
|
12
|
+
export const supportedAgents = () => LAUNCH_AGENTS.filter((a) => a.supported);
|
|
13
|
+
/**
|
|
14
|
+
* The agent's binary on PATH, and where. Only `bin` is accepted: for Cursor that is `cursor-agent`,
|
|
15
|
+
* which its installer always creates. Cursor's docs also call the command `agent`, but that name
|
|
16
|
+
* is too generic to run on a guess, so a bare `agent` on PATH is not Cursor.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveAgentBin(a, find, env, platform) {
|
|
19
|
+
const found = find(a.bin, env, platform);
|
|
20
|
+
return found ? { bin: a.bin, path: found } : null;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/lib/launch/agents.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,oCAAoC,EAAE;IACtJ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,EAAE;IAC9H,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,wBAAwB,EAAE;IACvI,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,6BAA6B,EAAE;IAC9I,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,sBAAsB,EAAE;IACpI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE;CAC9G,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAwB;IAClD,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,GAAkB,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAE7F;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,CAAc,EACd,IAA+F,EAC/F,GAAuC,EACvC,QAAgB;IAEhB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A change to a file in the USER'S agent config that a written-once agent needs (C4): pi and
|
|
3
|
+
* Cursor have no per-session way to be handed an MCP server, so align adds its own entry once.
|
|
4
|
+
* Pure data, so the adapters stay pure; `applyConfigWrite` is the one place that touches disk.
|
|
5
|
+
*
|
|
6
|
+
* Cursor hooks are deliberately not here: Cursor's hooks docs (cursor.com/docs/hooks) confirm
|
|
7
|
+
* only `workspaceOpen` for the CLI and describe the tool hooks as editor-session hooks, so a
|
|
8
|
+
* hooks.json entry written for a CLI launch would not be known to run.
|
|
9
|
+
*/
|
|
10
|
+
export interface ConfigWrite {
|
|
11
|
+
kind: 'mcp-entry';
|
|
12
|
+
file: string;
|
|
13
|
+
topKey: string;
|
|
14
|
+
name: string;
|
|
15
|
+
entry: Record<string, unknown>;
|
|
16
|
+
/** Directories at or above this are the user's own and are not checked for links (set by the launcher: the home dir). */
|
|
17
|
+
root?: string;
|
|
18
|
+
/** One extra line after the first write (what the user has to do next). */
|
|
19
|
+
hint?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Remembers a refused write, so its notice is printed once rather than on every launch. It is
|
|
23
|
+
* not a permanent no: the path is looked at again each launch, and a file that stops being
|
|
24
|
+
* refused is written and forgotten.
|
|
25
|
+
*/
|
|
26
|
+
export interface RefusedMemo {
|
|
27
|
+
has(file: string): boolean;
|
|
28
|
+
add(file: string): void;
|
|
29
|
+
remove(file: string): void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Every line goes to `note` (stderr). An entry that is already there, under any shape, is
|
|
33
|
+
* never touched: this adds, it does not update. Throws on an unparseable or contested file;
|
|
34
|
+
* the caller reports it and launches anyway.
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyConfigWrite(w: ConfigWrite, note: (line: string) => void, memo?: RefusedMemo): void;
|
|
37
|
+
//# sourceMappingURL=config-writes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writes.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/config-writes.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,yHAAyH;IACzH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAKD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAiBvG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BACKUP_SUFFIX, safeWriteJson } from '../safe-config-write.js';
|
|
2
|
+
const isObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
3
|
+
/**
|
|
4
|
+
* Every line goes to `note` (stderr). An entry that is already there, under any shape, is
|
|
5
|
+
* never touched: this adds, it does not update. Throws on an unparseable or contested file;
|
|
6
|
+
* the caller reports it and launches anyway.
|
|
7
|
+
*/
|
|
8
|
+
export function applyConfigWrite(w, note, memo) {
|
|
9
|
+
const quiet = memo?.has(w.file) === true;
|
|
10
|
+
const status = safeWriteJson(w.file, (cur) => {
|
|
11
|
+
const servers = isObject(cur[w.topKey]) ? cur[w.topKey] : {};
|
|
12
|
+
if (w.name in servers)
|
|
13
|
+
return undefined;
|
|
14
|
+
return { ...cur, [w.topKey]: { ...servers, [w.name]: w.entry } };
|
|
15
|
+
}, { note: quiet ? () => undefined : note, trailingNewline: true, ...(w.root ? { root: w.root } : {}) });
|
|
16
|
+
if (status === 'symlink')
|
|
17
|
+
memo?.add(w.file);
|
|
18
|
+
else if (quiet)
|
|
19
|
+
memo?.remove(w.file);
|
|
20
|
+
if (status === 'written') {
|
|
21
|
+
note(`Added the ${w.name} MCP server to ${w.file} (original kept at ${w.file}${BACKUP_SUFFIX}). Undo: align use --undo`);
|
|
22
|
+
if (w.hint)
|
|
23
|
+
note(w.hint);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=config-writes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writes.js","sourceRoot":"","sources":["../../../src/lib/launch/config-writes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAmCvE,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAa,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAErG;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAc,EAAE,IAA4B,EAAE,IAAkB;IAC/F,MAAM,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;IACzC,MAAM,MAAM,GAAG,aAAa,CAC1B,CAAC,CAAC,IAAI,EACN,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO;YAAE,OAAO,SAAS,CAAC;QACxC,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IACnE,CAAC,EACD,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CACrG,CAAC;IACF,IAAI,MAAM,KAAK,SAAS;QAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SACvC,IAAI,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC,IAAI,sBAAsB,CAAC,CAAC,IAAI,GAAG,aAAa,2BAA2B,CAAC,CAAC;QACzH,IAAI,CAAC,CAAC,IAAI;YAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface CursorProjectState {
|
|
2
|
+
/** A local align server is available to Cursor by any route (ours, or the user's own). */
|
|
3
|
+
projectHasMcp: boolean;
|
|
4
|
+
/** ~/.cursor/mcp.json: the file align adds to. */
|
|
5
|
+
mcpFile: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* What Cursor would already read, in the project (.cursor/) and globally (~/.cursor/). Same
|
|
9
|
+
* "present means doing the same job" rule as the other agents; unreadable counts as absent.
|
|
10
|
+
*/
|
|
11
|
+
export declare function readCursorState(cwd: string, home: string, opts: {
|
|
12
|
+
localIsDefault: boolean;
|
|
13
|
+
}): CursorProjectState;
|
|
14
|
+
//# sourceMappingURL=cursor-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-state.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/cursor-state.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,0FAA0F;IAC1F,aAAa,EAAE,OAAO,CAAC;IACvB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,kBAAkB,CAQhH"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { isLocalAlignServer } from './project-state.js';
|
|
4
|
+
function readJson(file) {
|
|
5
|
+
try {
|
|
6
|
+
const parsed = JSON.parse(readFileSync(file, 'utf8'));
|
|
7
|
+
return typeof parsed === 'object' && parsed !== null ? parsed : null;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* What Cursor would already read, in the project (.cursor/) and globally (~/.cursor/). Same
|
|
15
|
+
* "present means doing the same job" rule as the other agents; unreadable counts as absent.
|
|
16
|
+
*/
|
|
17
|
+
export function readCursorState(cwd, home, opts) {
|
|
18
|
+
const { localIsDefault } = opts;
|
|
19
|
+
const mcpFile = path.join(home, '.cursor', 'mcp.json');
|
|
20
|
+
const servers = [path.join(cwd, '.cursor', 'mcp.json'), mcpFile].map((f) => readJson(f)?.['mcpServers']);
|
|
21
|
+
return {
|
|
22
|
+
projectHasMcp: servers.some((s) => s?.['align-local'] !== undefined) || servers.some((s) => isLocalAlignServer(s?.['align'], localIsDefault)),
|
|
23
|
+
mcpFile,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=cursor-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-state.js","sourceRoot":"","sources":["../../../src/lib/launch/cursor-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAWxD,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/D,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAE,MAAe,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,IAAY,EAAE,IAAiC;IAC1F,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAqB,CAAC,CAAC;IAC7H,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC;QAC7I,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A PATH scan and nothing else: no subprocess, and never a config dir. `~/.claude` existing
|
|
3
|
+
* says the agent was installed once, not that it can be launched now. On win32 the candidates
|
|
4
|
+
* come from PATHEXT, because an npm global install is `claude.cmd`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findOnPath(bin: string, env: Record<string, string | undefined>, platform: string): string | null;
|
|
7
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/detect.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBhH"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { accessSync, constants, statSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* A PATH scan and nothing else: no subprocess, and never a config dir. `~/.claude` existing
|
|
5
|
+
* says the agent was installed once, not that it can be launched now. On win32 the candidates
|
|
6
|
+
* come from PATHEXT, because an npm global install is `claude.cmd`.
|
|
7
|
+
*/
|
|
8
|
+
export function findOnPath(bin, env, platform) {
|
|
9
|
+
const win = platform === 'win32';
|
|
10
|
+
const raw = env['PATH'] ?? env['Path'] ?? '';
|
|
11
|
+
if (!raw)
|
|
12
|
+
return null;
|
|
13
|
+
const exts = win ? (env['PATHEXT'] ?? '.COM;.EXE;.BAT;.CMD').split(';').filter(Boolean) : [''];
|
|
14
|
+
const names = win && path.extname(bin) ? [bin] : exts.map((e) => bin + (win ? e.toLowerCase() : e));
|
|
15
|
+
for (const dir of raw.split(win ? ';' : ':')) {
|
|
16
|
+
if (!dir)
|
|
17
|
+
continue;
|
|
18
|
+
for (const name of names) {
|
|
19
|
+
const candidate = path.join(dir, name);
|
|
20
|
+
try {
|
|
21
|
+
if (!statSync(candidate).isFile())
|
|
22
|
+
continue;
|
|
23
|
+
if (!win)
|
|
24
|
+
accessSync(candidate, constants.X_OK);
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// not here, or not executable: keep scanning
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/lib/launch/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,GAAuC,EAAE,QAAgB;IAC/F,MAAM,GAAG,GAAG,QAAQ,KAAK,OAAO,CAAC;IACjC,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,qBAAqB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/F,MAAM,KAAK,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpG,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE;oBAAE,SAAS;gBAC5C,IAAI,CAAC,GAAG;oBAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChD,OAAO,SAAS,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,6CAA6C;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* $XDG_CACHE_HOME/align-cli/launch, honoured on every platform; else the OS cache dir.
|
|
3
|
+
* The XDG spec says a relative XDG_CACHE_HOME is invalid and must be ignored.
|
|
4
|
+
*/
|
|
5
|
+
export declare function launchCacheDir(env: Record<string, string | undefined>): string;
|
|
6
|
+
/**
|
|
7
|
+
* Write `content` only when it differs from what is there, via a temp file and rename so a
|
|
8
|
+
* reader (the agent starting up) never sees a half-written file. Returns whether it wrote.
|
|
9
|
+
* The dir is created 0700 and refused if another user owns it: these files name commands
|
|
10
|
+
* the agent will run, so a dir someone else controls is a way to run theirs.
|
|
11
|
+
*/
|
|
12
|
+
export declare function writeIfChanged(dir: string, name: string, content: string, opts?: {
|
|
13
|
+
uid?: number;
|
|
14
|
+
}): boolean;
|
|
15
|
+
//# sourceMappingURL=launch-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-files.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/launch-files.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAG9E;AAgBD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAmB/G"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import envPaths from 'env-paths';
|
|
2
|
+
import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* $XDG_CACHE_HOME/align-cli/launch, honoured on every platform; else the OS cache dir.
|
|
6
|
+
* The XDG spec says a relative XDG_CACHE_HOME is invalid and must be ignored.
|
|
7
|
+
*/
|
|
8
|
+
export function launchCacheDir(env) {
|
|
9
|
+
const xdg = env['XDG_CACHE_HOME'];
|
|
10
|
+
return path.join(xdg && path.isAbsolute(xdg) ? path.join(xdg, 'align-cli') : defaultCacheDir(), 'launch');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* env-paths reads process.env.XDG_CACHE_HOME itself and would hand a relative value straight
|
|
14
|
+
* back, so the variable is hidden from it for this one synchronous call.
|
|
15
|
+
*/
|
|
16
|
+
function defaultCacheDir() {
|
|
17
|
+
const saved = process.env['XDG_CACHE_HOME'];
|
|
18
|
+
delete process.env['XDG_CACHE_HOME'];
|
|
19
|
+
try {
|
|
20
|
+
return envPaths('align-cli', { suffix: '' }).cache;
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
if (saved !== undefined)
|
|
24
|
+
process.env['XDG_CACHE_HOME'] = saved;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Write `content` only when it differs from what is there, via a temp file and rename so a
|
|
29
|
+
* reader (the agent starting up) never sees a half-written file. Returns whether it wrote.
|
|
30
|
+
* The dir is created 0700 and refused if another user owns it: these files name commands
|
|
31
|
+
* the agent will run, so a dir someone else controls is a way to run theirs.
|
|
32
|
+
*/
|
|
33
|
+
export function writeIfChanged(dir, name, content, opts = {}) {
|
|
34
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
35
|
+
const uid = 'uid' in opts ? opts.uid : process.getuid?.();
|
|
36
|
+
if (uid !== undefined && process.platform !== 'win32' && statSync(dir).uid !== uid) {
|
|
37
|
+
throw new Error(`${dir} is owned by another user; refusing to use it for launch files`);
|
|
38
|
+
}
|
|
39
|
+
const target = path.join(dir, name);
|
|
40
|
+
// A name may carry sub-directories (OpenCode loads plugins/align.js from a config dir).
|
|
41
|
+
const targetDir = path.dirname(target);
|
|
42
|
+
if (targetDir !== dir)
|
|
43
|
+
mkdirSync(targetDir, { recursive: true, mode: 0o700 });
|
|
44
|
+
try {
|
|
45
|
+
if (readFileSync(target, 'utf8') === content)
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// missing: write it
|
|
50
|
+
}
|
|
51
|
+
const tmp = path.join(targetDir, `.${path.basename(name)}.${process.pid}.tmp`);
|
|
52
|
+
writeFileSync(tmp, content, 'utf8');
|
|
53
|
+
renameSync(tmp, target);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=launch-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-files.js","sourceRoot":"","sources":["../../../src/lib/launch/launch-files.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvF,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAuC;IACpE,MAAM,GAAG,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC5G,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;IACrD,CAAC;YAAS,CAAC;QACT,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAC;IACjE,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,IAAY,EAAE,OAAe,EAAE,OAAyB,EAAE;IACpG,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAC1D,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,gEAAgE,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,wFAAwF;IACxF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,SAAS,KAAK,GAAG;QAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,IAAI,CAAC;QACH,IAAI,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,oBAAoB;IACtB,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/E,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { AgentName } from '../sessions/types.js';
|
|
2
|
+
import { type LaunchAgent } from './agents.js';
|
|
3
|
+
import { type LaunchSpec } from './adapters/claude-code.js';
|
|
4
|
+
import { type ConfigWrite } from './config-writes.js';
|
|
5
|
+
import { type CursorProjectState } from './cursor-state.js';
|
|
6
|
+
import { type OpenCodeProjectState } from './opencode-state.js';
|
|
7
|
+
import { type PiProjectState } from './pi-state.js';
|
|
8
|
+
import { type ProjectState } from './project-state.js';
|
|
9
|
+
export interface LaunchDeps {
|
|
10
|
+
env: Record<string, string | undefined>;
|
|
11
|
+
argv: string[];
|
|
12
|
+
cwd: string;
|
|
13
|
+
home: string;
|
|
14
|
+
platform: string;
|
|
15
|
+
isTTY: boolean;
|
|
16
|
+
config: {
|
|
17
|
+
getAgent(): string | undefined;
|
|
18
|
+
setAgent(agent: string): void;
|
|
19
|
+
isLaunchOff?(): boolean;
|
|
20
|
+
};
|
|
21
|
+
findOnPath(bin: string, env: Record<string, string | undefined>, platform: string): string | null;
|
|
22
|
+
readProjectState(cwd: string, home: string): ProjectState;
|
|
23
|
+
/** What OpenCode would already load. Separate from readProjectState: it reads other files. */
|
|
24
|
+
readOpenCodeState(cwd: string, home: string): OpenCodeProjectState;
|
|
25
|
+
/** What pi would already load, and where its MCP file is. */
|
|
26
|
+
readPiState(cwd: string, home: string, env: Record<string, string | undefined>): PiProjectState;
|
|
27
|
+
/** What Cursor would already read. */
|
|
28
|
+
readCursorState(cwd: string, home: string): CursorProjectState;
|
|
29
|
+
/** Add to a file in the user's own agent config, once (C4). Lines go to `note`. */
|
|
30
|
+
applyConfigWrite(w: ConfigWrite, note: (line: string) => void): void;
|
|
31
|
+
cacheDir(env: Record<string, string | undefined>): string;
|
|
32
|
+
writeIfChanged(dir: string, name: string, content: string): boolean;
|
|
33
|
+
runAgent(spec: LaunchSpec): Promise<number>;
|
|
34
|
+
/** Fire and forget: the caller never awaits what this returns. */
|
|
35
|
+
record(agent: AgentName): void;
|
|
36
|
+
/** Ask which agent. Only called on a TTY with more than one supported agent installed. */
|
|
37
|
+
pick(candidates: LaunchAgent[]): Promise<AgentName | null>;
|
|
38
|
+
/** Every line align itself writes on this path. stderr only: stdout belongs to the agent (`align -- -p ... | jq`). */
|
|
39
|
+
err(line: string): void;
|
|
40
|
+
now(): number;
|
|
41
|
+
}
|
|
42
|
+
export type LaunchResult = {
|
|
43
|
+
handled: false;
|
|
44
|
+
} | {
|
|
45
|
+
handled: true;
|
|
46
|
+
code: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Whether an align command with no --env reads the local graph: the CLI's own resolver, so
|
|
50
|
+
* ALIGN_ENV, the signed-in rule and the demo-mode rule all apply exactly as they do for `align ask`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isLocalDefault(): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* What bare `align` does once a local graph exists: open the user's coding agent with Align
|
|
55
|
+
* wired in for that session only. Returns `handled: false` when the caller should show the
|
|
56
|
+
* second-run card as before.
|
|
57
|
+
*/
|
|
58
|
+
export declare function launchIfChosen(overrides?: Partial<LaunchDeps>): Promise<LaunchResult>;
|
|
59
|
+
//# sourceMappingURL=launch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/launch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import { performance } from 'node:perf_hooks';
|
|
3
|
+
import { createConfigStore } from '../config.js';
|
|
4
|
+
import { resolveEnv } from '../resolve-env.js';
|
|
5
|
+
import { agentByName, resolveAgentBin, supportedAgents } from './agents.js';
|
|
6
|
+
import { buildClaudeLaunch } from './adapters/claude-code.js';
|
|
7
|
+
import { buildCursorLaunch } from './adapters/cursor.js';
|
|
8
|
+
import { buildOpenCodeLaunch } from './adapters/opencode.js';
|
|
9
|
+
import { buildPiLaunch } from './adapters/pi.js';
|
|
10
|
+
import { applyConfigWrite } from './config-writes.js';
|
|
11
|
+
import { readCursorState } from './cursor-state.js';
|
|
12
|
+
import { findOnPath } from './detect.js';
|
|
13
|
+
import { launchCacheDir, writeIfChanged } from './launch-files.js';
|
|
14
|
+
import { readOpenCodeState } from './opencode-state.js';
|
|
15
|
+
import { readPiState } from './pi-state.js';
|
|
16
|
+
import { readProjectState } from './project-state.js';
|
|
17
|
+
import { runAgent } from './run-agent.js';
|
|
18
|
+
const set = (v) => v !== undefined && v !== '';
|
|
19
|
+
/**
|
|
20
|
+
* Whether an align command with no --env reads the local graph: the CLI's own resolver, so
|
|
21
|
+
* ALIGN_ENV, the signed-in rule and the demo-mode rule all apply exactly as they do for `align ask`.
|
|
22
|
+
*/
|
|
23
|
+
export function isLocalDefault() {
|
|
24
|
+
return resolveEnv(undefined, { preferLocalEmbedded: true }) === 'local';
|
|
25
|
+
}
|
|
26
|
+
function defaultDeps() {
|
|
27
|
+
const config = createConfigStore();
|
|
28
|
+
return {
|
|
29
|
+
env: process.env,
|
|
30
|
+
argv: process.argv,
|
|
31
|
+
cwd: process.cwd(),
|
|
32
|
+
home: os.homedir(),
|
|
33
|
+
platform: process.platform,
|
|
34
|
+
isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
35
|
+
config,
|
|
36
|
+
findOnPath,
|
|
37
|
+
readProjectState: (cwd, home) => readProjectState(cwd, home, { localIsDefault: isLocalDefault() }),
|
|
38
|
+
readOpenCodeState: (cwd, home) => readOpenCodeState(cwd, home, { localIsDefault: isLocalDefault() }, process.env),
|
|
39
|
+
readPiState: (cwd, home, env) => readPiState(cwd, home, { localIsDefault: isLocalDefault() }, env),
|
|
40
|
+
readCursorState: (cwd, home) => readCursorState(cwd, home, { localIsDefault: isLocalDefault() }),
|
|
41
|
+
applyConfigWrite: (w, note) => applyConfigWrite(w, note, { has: (f) => config.wasWriteRefused(f), add: (f) => config.markWriteRefused(f), remove: (f) => config.unmarkWriteRefused(f) }),
|
|
42
|
+
cacheDir: launchCacheDir,
|
|
43
|
+
writeIfChanged,
|
|
44
|
+
runAgent: (spec) => runAgent(spec),
|
|
45
|
+
record: (agent) => {
|
|
46
|
+
// Dynamic and un-awaited: telemetry consent rules live in recordFunnelStage, and none of
|
|
47
|
+
// its network time may sit between the user and the agent.
|
|
48
|
+
void import('../usage-telemetry.js')
|
|
49
|
+
.then((m) => m.recordFunnelStage(config.getEnvironment('local'), 'agent_launched', 'align', { agent }))
|
|
50
|
+
.catch(() => undefined);
|
|
51
|
+
},
|
|
52
|
+
pick: async (candidates) => {
|
|
53
|
+
const clack = await import('@clack/prompts');
|
|
54
|
+
const answer = await clack.select({
|
|
55
|
+
message: 'Which coding agent should `align` open?',
|
|
56
|
+
options: candidates.map((a) => ({ value: a.name, label: a.label })),
|
|
57
|
+
});
|
|
58
|
+
return clack.isCancel(answer) ? null : answer;
|
|
59
|
+
},
|
|
60
|
+
err: (l) => console.error(l),
|
|
61
|
+
now: () => performance.now(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Args after `--`, and the operands before it (anything there is a typo, not an agent arg). */
|
|
65
|
+
function splitArgv(argv) {
|
|
66
|
+
const user = argv.slice(2);
|
|
67
|
+
const sep = user.indexOf('--');
|
|
68
|
+
const before = sep < 0 ? user : user.slice(0, sep);
|
|
69
|
+
return { operands: before.filter((a) => !a.startsWith('-')), passthrough: sep < 0 ? [] : user.slice(sep + 1) };
|
|
70
|
+
}
|
|
71
|
+
/** One adapter per launchable agent. Each reads the project state ITS agent would load. */
|
|
72
|
+
const BUILDERS = {
|
|
73
|
+
'claude-code': (d, base) => buildClaudeLaunch({ ...base, ...d.readProjectState(d.cwd, d.home) }),
|
|
74
|
+
opencode: (d, base) => buildOpenCodeLaunch({ ...base, env: d.env, ...d.readOpenCodeState(d.cwd, d.home) }),
|
|
75
|
+
pi: (d, base) => buildPiLaunch({ ...base, ...d.readPiState(d.cwd, d.home, d.env) }),
|
|
76
|
+
cursor: (d, base) => buildCursorLaunch({ ...base, ...d.readCursorState(d.cwd, d.home) }),
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* What bare `align` does once a local graph exists: open the user's coding agent with Align
|
|
80
|
+
* wired in for that session only. Returns `handled: false` when the caller should show the
|
|
81
|
+
* second-run card as before.
|
|
82
|
+
*/
|
|
83
|
+
export async function launchIfChosen(overrides = {}) {
|
|
84
|
+
const d = { ...defaultDeps(), ...overrides };
|
|
85
|
+
if (set(d.env['ALIGN_WRAPPED']) || set(d.env['ALIGN_NO_LAUNCH']))
|
|
86
|
+
return { handled: false };
|
|
87
|
+
const { operands, passthrough } = splitArgv(d.argv);
|
|
88
|
+
if (operands.length > 0) {
|
|
89
|
+
d.err(`error: unknown command '${operands[0]}'`);
|
|
90
|
+
d.err('Run `align --help` for the commands, or `align -- <args>` to pass arguments to your agent.');
|
|
91
|
+
return { handled: true, code: 2 };
|
|
92
|
+
}
|
|
93
|
+
// No terminal and no explicit `align -- ...`: a pipe, a cron job or CI ran bare `align`. That
|
|
94
|
+
// is not a request for an interactive session, so print the card as before and decide nothing.
|
|
95
|
+
const explicit = d.argv.slice(2).includes('--');
|
|
96
|
+
if (!d.isTTY && !explicit)
|
|
97
|
+
return { handled: false };
|
|
98
|
+
let agent = agentByName(d.config.getAgent());
|
|
99
|
+
// `align use --undo` turned launching off: no auto-pick, no config writes, until `align use <agent>`.
|
|
100
|
+
if (!agent && d.config.isLaunchOff?.()) {
|
|
101
|
+
d.err('Launching is off after `align use --undo`. Run `align use <agent>` to turn it back on.');
|
|
102
|
+
// Bare `align` shows the card; an explicit `align -- ...` asked for a session, so dropping
|
|
103
|
+
// its arguments silently would be wrong (same rule as an agent that is not installed).
|
|
104
|
+
return explicit ? { handled: true, code: 1 } : { handled: false };
|
|
105
|
+
}
|
|
106
|
+
const stored = agent !== undefined;
|
|
107
|
+
let announce;
|
|
108
|
+
if (!agent) {
|
|
109
|
+
const installed = supportedAgents().filter((a) => resolveAgentBin(a, d.findOnPath, d.env, d.platform) !== null);
|
|
110
|
+
if (installed.length === 0) {
|
|
111
|
+
const works = supportedAgents();
|
|
112
|
+
d.err(`No coding agent that Align can open was found on your PATH. Align works with: ${works.map((a) => a.label).join(', ')}.`);
|
|
113
|
+
for (const a of works)
|
|
114
|
+
d.err(`Install ${a.label}: ${a.install}`);
|
|
115
|
+
d.err('Then run `align` again.');
|
|
116
|
+
return { handled: true, code: 1 };
|
|
117
|
+
}
|
|
118
|
+
if (installed.length === 1) {
|
|
119
|
+
agent = installed[0];
|
|
120
|
+
announce = `Opening ${agent.label}. Switch any time with \`align use\`.`;
|
|
121
|
+
}
|
|
122
|
+
else if (d.isTTY) {
|
|
123
|
+
const choice = await d.pick(installed);
|
|
124
|
+
agent = installed.find((a) => a.name === choice);
|
|
125
|
+
if (!agent)
|
|
126
|
+
return { handled: true, code: 1 };
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
d.err(`More than one coding agent is installed (${installed.map((a) => a.label).join(', ')}) and there is no terminal to ask in.`);
|
|
130
|
+
d.err(`Choose one: align use <agent> (${installed.map((a) => a.name).join(' | ')})`);
|
|
131
|
+
d.err('Then run `align` again.');
|
|
132
|
+
return { handled: true, code: 2 };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const build = BUILDERS[agent.name];
|
|
136
|
+
if (!agent.supported || !build) {
|
|
137
|
+
d.err(`${agent.label} launching is coming soon; showing your graph instead. Switch with \`align use\`.`);
|
|
138
|
+
return { handled: false };
|
|
139
|
+
}
|
|
140
|
+
const resolved = resolveAgentBin(agent, d.findOnPath, d.env, d.platform);
|
|
141
|
+
const found = resolved?.path ?? null;
|
|
142
|
+
if (!found) {
|
|
143
|
+
// Reachable only for a stored choice (a fresh pick came from the installed list).
|
|
144
|
+
d.err(`${agent.label} is not installed any more. Run \`align use\` to pick another, or reinstall it.`);
|
|
145
|
+
// Bare `align` falls back to the card; an explicit `align -- ...` asked for a session, so
|
|
146
|
+
// dropping its arguments silently would be wrong.
|
|
147
|
+
return explicit ? { handled: true, code: 127 } : { handled: false };
|
|
148
|
+
}
|
|
149
|
+
const dir = d.cacheDir(d.env);
|
|
150
|
+
const built = build(d, { passthrough, cachePath: (name) => `${dir}/${name}` });
|
|
151
|
+
// The adapter names the agent's usual binary; run whichever name is actually installed.
|
|
152
|
+
const spec = resolved && resolved.bin !== built.bin ? { ...built, bin: resolved.bin } : built;
|
|
153
|
+
try {
|
|
154
|
+
for (const f of spec.files)
|
|
155
|
+
d.writeIfChanged(dir, f.name, f.content);
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
d.err(`Could not write launch files (${e.message}). Showing your graph instead.`);
|
|
159
|
+
return { handled: false };
|
|
160
|
+
}
|
|
161
|
+
// On win32 the resolved path is what tells runAgent it holds a .cmd shim.
|
|
162
|
+
for (const n of spec.notes ?? [])
|
|
163
|
+
d.err(n);
|
|
164
|
+
const toRun = d.platform === 'win32' ? { ...spec, bin: found } : spec;
|
|
165
|
+
if (set(d.env['ALIGN_LAUNCH_TRACE']))
|
|
166
|
+
d.err(`align-overhead-ms=${Math.round(d.now())}`);
|
|
167
|
+
// A dry run measures; it must not change the machine, so nothing is persisted before this.
|
|
168
|
+
if (set(d.env['ALIGN_LAUNCH_DRY_RUN']))
|
|
169
|
+
return { handled: true, code: 0 };
|
|
170
|
+
if (!stored)
|
|
171
|
+
d.config.setAgent(agent.name);
|
|
172
|
+
// Written-once agents (pi, Cursor): the one place align adds to the user's own config. Not
|
|
173
|
+
// fatal: the session still opens, just without that piece.
|
|
174
|
+
for (const w of spec.writes ?? []) {
|
|
175
|
+
try {
|
|
176
|
+
d.applyConfigWrite({ ...w, root: d.home }, d.err);
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
d.err(`Could not update ${w.file} (${e.message}). Opening ${agent.label} without it.`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (announce)
|
|
183
|
+
d.err(announce);
|
|
184
|
+
d.record(agent.name);
|
|
185
|
+
try {
|
|
186
|
+
return { handled: true, code: await d.runAgent(toRun) };
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
const err = e;
|
|
190
|
+
if (err.code === 'ENOENT') {
|
|
191
|
+
d.err(`${agent.bin} is not on your PATH. Install it (${agent.install}), or pick another: align use`);
|
|
192
|
+
return { handled: true, code: 127 };
|
|
193
|
+
}
|
|
194
|
+
d.err(`align: ${err.message}`);
|
|
195
|
+
return { handled: true, code: 2 };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../../src/lib/launch/launch.ts"],"names":[],"mappings":"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"}
|