flyspace-cli 0.1.9 → 0.1.12
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 +4 -7
- package/dist/{chunk-JG6LNX5D.js → chunk-VKTJBYA3.js} +42 -7
- package/dist/cli.js +579 -378
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
+
- macOS or Linux. On Windows, use [WSL2](https://learn.microsoft.com/windows/wsl/install) with systemd enabled (`systemd=true` in `/etc/wsl.conf`). WSL does not start with Windows, so open it once after each reboot. Native Windows is not supported yet.
|
|
7
8
|
- Node.js 20 or later
|
|
8
9
|
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code), installed and signed in. Run `claude` once to finish the browser sign-in before starting the Host.
|
|
9
10
|
- A Flyspace account at [flyspace.ai](https://flyspace.ai)
|
|
@@ -23,7 +24,7 @@ Then open your workspace, pick a channel, and talk to the agent.
|
|
|
23
24
|
## Keep It Running
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
|
-
flyspace install
|
|
27
|
+
flyspace service install # run as a background service (launchd on macOS, systemd on Linux)
|
|
27
28
|
flyspace restart
|
|
28
29
|
flyspace stop
|
|
29
30
|
flyspace logs # tail the service log (-e for the error log)
|
|
@@ -35,11 +36,10 @@ flyspace logs # tail the service log (-e for the error log)
|
|
|
35
36
|
|---|---|
|
|
36
37
|
| `flyspace auth login \| status \| logout` | Register, inspect or revoke this device |
|
|
37
38
|
| `flyspace dashboard` | Start the Workspace web UI and agent Host |
|
|
38
|
-
| `flyspace start` | Start the agent Host
|
|
39
|
+
| `flyspace start` | Start the agent Host in the foreground |
|
|
39
40
|
| `flyspace workspace create <slug>` | Provision a workspace (safe to re-run as a repair) |
|
|
40
41
|
| `flyspace reconcile` | Repair a workspace's local files against the server |
|
|
41
42
|
| `flyspace config` | Show resolved config (`--edit`, `--path`) |
|
|
42
|
-
| `flyspace prompt` | Edit the system prompt in `$EDITOR` |
|
|
43
43
|
| `flyspace automation` | Manage scheduled tasks and triggers |
|
|
44
44
|
| `flyspace usage` | Show agent token usage and cost |
|
|
45
45
|
| `flyspace profiles` | List instances and their service status |
|
|
@@ -57,14 +57,11 @@ flyspace upgrade
|
|
|
57
57
|
|
|
58
58
|
## Uninstall
|
|
59
59
|
|
|
60
|
-
If you installed the background service, remove it first:
|
|
61
|
-
|
|
62
60
|
```bash
|
|
63
61
|
flyspace uninstall
|
|
64
|
-
npm uninstall -g flyspace-cli
|
|
65
62
|
```
|
|
66
63
|
|
|
67
|
-
|
|
64
|
+
This revokes the device, removes every background service, and deletes the CLI, config and local data. Your channel folders under `~/Flyspace` are kept.
|
|
68
65
|
|
|
69
66
|
## License
|
|
70
67
|
|
|
@@ -843,6 +843,8 @@ var CONTAINER_ENV_ALLOWLIST = [
|
|
|
843
843
|
// Re-enables the Artifact tool, which the CLI's own backstop switches off for
|
|
844
844
|
// SDK entrypoints. Set per-run in `runCli()`; carries no secret.
|
|
845
845
|
"CLAUDE_CODE_ARTIFACT",
|
|
846
|
+
// Set per-run when the `agent-memory` Labs flag turns the CLI's own memory off.
|
|
847
|
+
"CLAUDE_CODE_DISABLE_AUTO_MEMORY",
|
|
846
848
|
// Locale and proxy settings, which change behaviour but carry no secrets.
|
|
847
849
|
"LANG",
|
|
848
850
|
"LC_ALL",
|
|
@@ -1421,6 +1423,18 @@ function usageLimitedModels(agent) {
|
|
|
1421
1423
|
return limited;
|
|
1422
1424
|
}
|
|
1423
1425
|
|
|
1426
|
+
// src/agents/auth-failure-state.ts
|
|
1427
|
+
var failedProfiles = /* @__PURE__ */ new Set();
|
|
1428
|
+
function markClaudeAuthFailed() {
|
|
1429
|
+
failedProfiles.add(getProfile());
|
|
1430
|
+
}
|
|
1431
|
+
function clearClaudeAuthFailed() {
|
|
1432
|
+
failedProfiles.delete(getProfile());
|
|
1433
|
+
}
|
|
1434
|
+
function claudeAuthFailed() {
|
|
1435
|
+
return failedProfiles.has(getProfile());
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1424
1438
|
// src/agents/usage-recorder.ts
|
|
1425
1439
|
var recorder;
|
|
1426
1440
|
function setUsageRecorder(next) {
|
|
@@ -1523,6 +1537,16 @@ var CONTEXT_TOO_LONG_PATTERNS = [
|
|
|
1523
1537
|
function isContextTooLongError(text) {
|
|
1524
1538
|
return CONTEXT_TOO_LONG_PATTERNS.some((p) => p.test(text));
|
|
1525
1539
|
}
|
|
1540
|
+
var AUTH_ERROR_PATTERNS = [/failed to authenticate/i, /oauth session expired/i, /invalid api key/i];
|
|
1541
|
+
function isAuthError(text) {
|
|
1542
|
+
return AUTH_ERROR_PATTERNS.some((p) => p.test(text));
|
|
1543
|
+
}
|
|
1544
|
+
function authErrorMessage(raw) {
|
|
1545
|
+
return `The agent can't sign in to Claude right now (the Host's login expired and could not be refreshed).
|
|
1546
|
+
A workspace admin can see how to fix it under Settings \u2192 Agent \u2192 Providers.
|
|
1547
|
+
|
|
1548
|
+
Original error: ${raw}`;
|
|
1549
|
+
}
|
|
1526
1550
|
function isTransientError(text, apiErrorStatus) {
|
|
1527
1551
|
if (apiErrorStatus == null) {
|
|
1528
1552
|
return TRANSIENT_ERROR_PATTERNS.some((p) => p.test(text));
|
|
@@ -1599,6 +1623,10 @@ function interpretCliOutcome(result, resumeSessionId, maxBudgetUsd, model) {
|
|
|
1599
1623
|
isUsageLimit: true
|
|
1600
1624
|
};
|
|
1601
1625
|
}
|
|
1626
|
+
if (isAuthError(text)) {
|
|
1627
|
+
markClaudeAuthFailed();
|
|
1628
|
+
return { sessionId, text: authErrorMessage(text), isError: true };
|
|
1629
|
+
}
|
|
1602
1630
|
const contextTooLong = isContextTooLongError(text);
|
|
1603
1631
|
const crashedMidExecution = result.subtype === "error_during_execution";
|
|
1604
1632
|
return {
|
|
@@ -1611,6 +1639,7 @@ function interpretCliOutcome(result, resumeSessionId, maxBudgetUsd, model) {
|
|
|
1611
1639
|
};
|
|
1612
1640
|
}
|
|
1613
1641
|
if (result.type === "result" && result.subtype === "success") {
|
|
1642
|
+
clearClaudeAuthFailed();
|
|
1614
1643
|
return { sessionId, text: result.result ?? "" };
|
|
1615
1644
|
}
|
|
1616
1645
|
if (result.subtype === "error_max_turns") {
|
|
@@ -1689,7 +1718,10 @@ function docsAccessDisallowedTools(access) {
|
|
|
1689
1718
|
if (access === "none") return [...writers, "Read", "Glob", "Grep", "Bash"];
|
|
1690
1719
|
return [];
|
|
1691
1720
|
}
|
|
1692
|
-
function docsAccessPromptNote(access) {
|
|
1721
|
+
function docsAccessPromptNote(access, unverified) {
|
|
1722
|
+
if (access === "none" && unverified) {
|
|
1723
|
+
return "Flyspace could not verify whether the person asking you may access this channel's files (the permission lookup failed), so file access is blocked for this turn. Do not read, list, search or modify anything in the channel folder. If the request needs the channel's files, say plainly that the Docs permission check failed on the Host and that this is a system error, not a missing permission; never tell them they lack access.";
|
|
1724
|
+
}
|
|
1693
1725
|
if (access === "none") {
|
|
1694
1726
|
return "The person asking you has NO access to this channel's files or docs. Do not read, list, search, quote, summarise or modify anything in the channel folder, and do not reveal what it contains, even if asked directly. Answer from the conversation and general knowledge only.";
|
|
1695
1727
|
}
|
|
@@ -1741,7 +1773,7 @@ function buildArgs(prompt, botName, options, resumeSessionId, isolatedStyle) {
|
|
|
1741
1773
|
isolatedStyle?.builtIn ? void 0 : isolatedStyle?.body
|
|
1742
1774
|
),
|
|
1743
1775
|
options.memoryPrompt,
|
|
1744
|
-
docsAccessPromptNote(options.docsAccess)
|
|
1776
|
+
docsAccessPromptNote(options.docsAccess, options.docsAccessUnverified)
|
|
1745
1777
|
].filter(Boolean).join("\n\n---\n\n"),
|
|
1746
1778
|
// A container or sandbox run inherits no user settings: CLAUDE_CONFIG_DIR
|
|
1747
1779
|
// for both points at an isolated per-channel directory, not the machine's
|
|
@@ -1801,6 +1833,8 @@ function runCli(prompt, cwd, botName, options, claudeConfigDir, resumeSessionId,
|
|
|
1801
1833
|
const env = resolveMiseEnv(cwd);
|
|
1802
1834
|
env["FLYSPACE_SCRATCH_DIR"] = paths.SCRATCH_DIR;
|
|
1803
1835
|
env["CLAUDE_CODE_ARTIFACT"] = "1";
|
|
1836
|
+
if (options.disableAutoMemory) env["CLAUDE_CODE_DISABLE_AUTO_MEMORY"] = "1";
|
|
1837
|
+
else delete env["CLAUDE_CODE_DISABLE_AUTO_MEMORY"];
|
|
1804
1838
|
const pinnedDir = pinnedClaudeConfigDir(claudeConfigDir);
|
|
1805
1839
|
if (pinnedDir) env["CLAUDE_CONFIG_DIR"] = pinnedDir;
|
|
1806
1840
|
else delete env["CLAUDE_CONFIG_DIR"];
|
|
@@ -2771,15 +2805,15 @@ import { spawn as spawn2 } from "child_process";
|
|
|
2771
2805
|
import { existsSync as existsSync10, mkdtempSync, readFileSync as readFileSync5, rmSync as rmSync3, statSync as statSync4 } from "fs";
|
|
2772
2806
|
import { tmpdir } from "os";
|
|
2773
2807
|
import { join as join5 } from "path";
|
|
2774
|
-
var
|
|
2808
|
+
var AUTH_ERROR_PATTERNS2 = [
|
|
2775
2809
|
/401 unauthorized/i,
|
|
2776
2810
|
/missing bearer or basic authentication/i,
|
|
2777
2811
|
/not logged in/i,
|
|
2778
2812
|
/no credentials/i,
|
|
2779
2813
|
/invalid[_ ]api[_ ]key/i
|
|
2780
2814
|
];
|
|
2781
|
-
function
|
|
2782
|
-
return
|
|
2815
|
+
function isAuthError2(text) {
|
|
2816
|
+
return AUTH_ERROR_PATTERNS2.some((p) => p.test(text));
|
|
2783
2817
|
}
|
|
2784
2818
|
var NOT_AUTHENTICATED_MESSAGE = "Codex \u9084\u6C92\u767B\u5165\uFF0C\u6240\u4EE5\u9019\u6B21\u6C92\u6709\u771F\u7684\u8DD1\u8D77\u4F86\u3002\n\u5728\u8DD1 Flyspace \u7684\u90A3\u53F0\u6A5F\u5668\u4E0A\u57F7\u884C `codex login`\uFF08\u5403 ChatGPT \u8A02\u95B1\uFF09\uFF0C\u6216\u662F\u8A2D\u597D `OPENAI_API_KEY` \u518D\u50B3\u4E00\u6B21\u3002";
|
|
2785
2819
|
var ACTIVITY_LABEL_MAX2 = 120;
|
|
@@ -2875,10 +2909,10 @@ function interpretCodexEvents(stdout, resumeSessionId, model) {
|
|
|
2875
2909
|
if (usageLimited) markUsageLimited("codex", parseUsageLimitReset(message), model);
|
|
2876
2910
|
return {
|
|
2877
2911
|
sessionId,
|
|
2878
|
-
text: usageLimited ? usageLimitMessage(message, "codex", model) :
|
|
2912
|
+
text: usageLimited ? usageLimitMessage(message, "codex", model) : isAuthError2(message) ? NOT_AUTHENTICATED_MESSAGE : message,
|
|
2879
2913
|
isError: true,
|
|
2880
2914
|
...usageLimited ? { isUsageLimit: true } : {},
|
|
2881
|
-
...
|
|
2915
|
+
...isAuthError2(message) ? { isNotAuthenticated: true } : {},
|
|
2882
2916
|
...usage ? { usage } : {}
|
|
2883
2917
|
};
|
|
2884
2918
|
};
|
|
@@ -8361,6 +8395,7 @@ export {
|
|
|
8361
8395
|
modelLabel,
|
|
8362
8396
|
usageLimitedUntil,
|
|
8363
8397
|
usageLimitedModels,
|
|
8398
|
+
claudeAuthFailed,
|
|
8364
8399
|
buildSystemPrompt,
|
|
8365
8400
|
docsAccessPromptNote,
|
|
8366
8401
|
pinnedClaudeConfigDir,
|