orchestrating 0.1.38 → 0.2.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/bin/orch +75 -7
- package/package.json +3 -2
package/bin/orch
CHANGED
|
@@ -242,6 +242,50 @@ if (firstArg === "logout") {
|
|
|
242
242
|
process.exit(0);
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
// --- Config subcommand: manage API key and settings ---
|
|
246
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
247
|
+
|
|
248
|
+
function loadConfig() {
|
|
249
|
+
try {
|
|
250
|
+
return JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
251
|
+
} catch {
|
|
252
|
+
return {};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function saveConfig(data) {
|
|
257
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
258
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2) + "\n");
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (firstArg === "config") {
|
|
262
|
+
const configArgs = process.argv.slice(3);
|
|
263
|
+
if (configArgs[0] === "set" && configArgs[1] === "api-key" && configArgs[2]) {
|
|
264
|
+
const config = loadConfig();
|
|
265
|
+
config.anthropic_api_key = configArgs[2];
|
|
266
|
+
saveConfig(config);
|
|
267
|
+
console.log("Anthropic API key saved. Claude Code will use this key automatically.");
|
|
268
|
+
} else if (configArgs[0] === "get" && configArgs[1] === "api-key") {
|
|
269
|
+
const config = loadConfig();
|
|
270
|
+
if (config.anthropic_api_key) {
|
|
271
|
+
console.log(`API key: ${config.anthropic_api_key.slice(0, 10)}…${config.anthropic_api_key.slice(-4)}`);
|
|
272
|
+
} else {
|
|
273
|
+
console.log("No API key configured. Run: orch config set api-key <your-anthropic-key>");
|
|
274
|
+
}
|
|
275
|
+
} else if (configArgs[0] === "unset" && configArgs[1] === "api-key") {
|
|
276
|
+
const config = loadConfig();
|
|
277
|
+
delete config.anthropic_api_key;
|
|
278
|
+
saveConfig(config);
|
|
279
|
+
console.log("API key removed.");
|
|
280
|
+
} else {
|
|
281
|
+
console.error("Usage:");
|
|
282
|
+
console.error(" orch config set api-key <key> Save your Anthropic API key");
|
|
283
|
+
console.error(" orch config get api-key Show stored API key");
|
|
284
|
+
console.error(" orch config unset api-key Remove stored API key");
|
|
285
|
+
}
|
|
286
|
+
process.exit(0);
|
|
287
|
+
}
|
|
288
|
+
|
|
245
289
|
if (firstArg === "daemon") {
|
|
246
290
|
const daemonArgs = process.argv.slice(3);
|
|
247
291
|
const pidFile = path.join(os.homedir(), ".orch-daemon.pid");
|
|
@@ -740,6 +784,7 @@ while (i < args.length) {
|
|
|
740
784
|
console.error("Usage: orch [-l label] [-y] <command> [args...]");
|
|
741
785
|
console.error(" orch login — Authenticate with orchestrat.ing");
|
|
742
786
|
console.error(" orch logout — Clear stored credentials");
|
|
787
|
+
console.error(" orch config — Manage settings (API keys, etc.)");
|
|
743
788
|
console.error(" orch daemon — Run background daemon for remote session launching");
|
|
744
789
|
console.error("");
|
|
745
790
|
console.error(" -l <label> Optional human-readable session label");
|
|
@@ -763,6 +808,10 @@ while (i < args.length) {
|
|
|
763
808
|
console.error(" orch daemon -b");
|
|
764
809
|
console.error(" orch daemon --enable");
|
|
765
810
|
console.error("");
|
|
811
|
+
console.error("Setup (one-time):");
|
|
812
|
+
console.error(" orch login");
|
|
813
|
+
console.error(' orch config set api-key sk-ant-... # Your Anthropic API key');
|
|
814
|
+
console.error("");
|
|
766
815
|
console.error("Environment:");
|
|
767
816
|
console.error(" ORC_URL WebSocket server URL (default: wss://api.orchestrat.ing/ws)");
|
|
768
817
|
console.error(" ORC_TOKEN Auth token (overrides stored credentials)");
|
|
@@ -779,7 +828,19 @@ if (commandArgs.length === 0) {
|
|
|
779
828
|
process.exit(1);
|
|
780
829
|
}
|
|
781
830
|
|
|
782
|
-
|
|
831
|
+
// Resolve claude binary: prefer bundled @anthropic-ai/claude-code, fall back to system PATH
|
|
832
|
+
let command = commandArgs[0];
|
|
833
|
+
let claudeBundled = false;
|
|
834
|
+
if (command === "claude") {
|
|
835
|
+
try {
|
|
836
|
+
// The npm package has a bin entry that npm links globally; for local use, resolve directly
|
|
837
|
+
const bundledBin = path.join(__dirname, "..", "node_modules", ".bin", "claude");
|
|
838
|
+
if (existsSync(bundledBin)) {
|
|
839
|
+
command = bundledBin;
|
|
840
|
+
claudeBundled = true;
|
|
841
|
+
}
|
|
842
|
+
} catch {}
|
|
843
|
+
}
|
|
783
844
|
const spawnArgs = commandArgs.slice(1);
|
|
784
845
|
let sessionId;
|
|
785
846
|
const hostname = os.hostname().replace(/\.(lan|local|home|internal)$/i, "");
|
|
@@ -830,6 +891,7 @@ const eventHistory = []; // all agent events for replay on reconnect
|
|
|
830
891
|
function sendToServer(msg) {
|
|
831
892
|
// Track agent events for reconnect replay
|
|
832
893
|
if (msg.type === "agent_event" && msg.event) {
|
|
894
|
+
if (!msg.event.ts) msg.event.ts = Date.now();
|
|
833
895
|
eventHistory.push(msg.event);
|
|
834
896
|
while (eventHistory.length > MAX_EVENT_HISTORY) {
|
|
835
897
|
eventHistory.shift();
|
|
@@ -942,11 +1004,15 @@ if (adapter) {
|
|
|
942
1004
|
// Confirmation-type tools — these need "yes" response, not permission grants
|
|
943
1005
|
const CONFIRMATION_TOOLS = new Set(["ExitPlanMode", "EnterPlanMode"]);
|
|
944
1006
|
|
|
945
|
-
// Build clean env for child processes
|
|
1007
|
+
// Build clean env for child processes
|
|
1008
|
+
// Inject stored Anthropic API key if available (so users don't need separate `claude login`)
|
|
946
1009
|
const childEnv = (() => {
|
|
947
1010
|
const e = { ...process.env };
|
|
948
1011
|
delete e.CLAUDECODE;
|
|
949
|
-
|
|
1012
|
+
const config = loadConfig();
|
|
1013
|
+
if (config.anthropic_api_key && !e.ANTHROPIC_API_KEY) {
|
|
1014
|
+
e.ANTHROPIC_API_KEY = config.anthropic_api_key;
|
|
1015
|
+
}
|
|
950
1016
|
return e;
|
|
951
1017
|
})();
|
|
952
1018
|
|
|
@@ -1083,20 +1149,21 @@ if (adapter) {
|
|
|
1083
1149
|
for (const line of latest.split("\n").filter(Boolean)) {
|
|
1084
1150
|
try {
|
|
1085
1151
|
const record = JSON.parse(line);
|
|
1152
|
+
const ts = record.timestamp ? new Date(record.timestamp).getTime() : undefined;
|
|
1086
1153
|
if (record.type === "user" && record.message?.content) {
|
|
1087
1154
|
const text = typeof record.message.content === "string"
|
|
1088
1155
|
? record.message.content
|
|
1089
1156
|
: record.message.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
1090
1157
|
if (text) {
|
|
1091
|
-
historyEvents.push({ kind: "user_message", text });
|
|
1158
|
+
historyEvents.push({ kind: "user_message", text, ...(ts ? { ts } : {}) });
|
|
1092
1159
|
}
|
|
1093
1160
|
} else if (record.message?.role === "assistant" && record.message?.content) {
|
|
1094
1161
|
const msgId = `hist-${msgCounter++}`;
|
|
1095
|
-
historyEvents.push({ kind: "message_start", messageId: msgId });
|
|
1162
|
+
historyEvents.push({ kind: "message_start", messageId: msgId, ...(ts ? { ts } : {}) });
|
|
1096
1163
|
for (const block of record.message.content) {
|
|
1097
1164
|
if (block.type === "text" && block.text) {
|
|
1098
1165
|
const blockId = `hist-text-${msgCounter++}`;
|
|
1099
|
-
historyEvents.push({ kind: "text_delta", blockId, text: block.text });
|
|
1166
|
+
historyEvents.push({ kind: "text_delta", blockId, text: block.text, ...(ts ? { ts } : {}) });
|
|
1100
1167
|
} else if (block.type === "tool_use") {
|
|
1101
1168
|
const blockId = `hist-tool-${msgCounter++}`;
|
|
1102
1169
|
historyEvents.push({
|
|
@@ -1104,10 +1171,11 @@ if (adapter) {
|
|
|
1104
1171
|
toolName: block.name || "unknown",
|
|
1105
1172
|
toolId: block.id || blockId,
|
|
1106
1173
|
input: typeof block.input === "string" ? block.input : JSON.stringify(block.input || {}),
|
|
1174
|
+
...(ts ? { ts } : {}),
|
|
1107
1175
|
});
|
|
1108
1176
|
}
|
|
1109
1177
|
}
|
|
1110
|
-
historyEvents.push({ kind: "message_end", messageId: msgId });
|
|
1178
|
+
historyEvents.push({ kind: "message_end", messageId: msgId, ...(ts ? { ts } : {}) });
|
|
1111
1179
|
}
|
|
1112
1180
|
} catch {}
|
|
1113
1181
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orchestrating",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Stream terminal sessions to the orchestrat.ing dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"dashboard"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"ws": "^8.18.0"
|
|
33
|
+
"ws": "^8.18.0",
|
|
34
|
+
"@anthropic-ai/claude-code": "^2.1.0"
|
|
34
35
|
}
|
|
35
36
|
}
|