@saadnvd1/agent-os 0.3.494 → 0.3.496
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
CHANGED
|
@@ -1081,7 +1081,7 @@ it may do on its own, and the lines that always come back to you as asks.
|
|
|
1081
1081
|
ALTER or ATTACH; files under `~/.agent-os` outside its folder), stopping
|
|
1082
1082
|
AgentOS or its tmux (`pkill`/`kill` aimed at it, `tmux kill-*`, a
|
|
1083
1083
|
`launchctl` or `serviceman` restart), and reading secret files (the same
|
|
1084
|
-
list as the write guard
|
|
1084
|
+
list as the write guard; tokenvault is allowed, through `tv` and its folders). It reads each
|
|
1085
1085
|
command line the way a shell would, so these are caught inside pipes,
|
|
1086
1086
|
chains and `$( )`, behind `bash -c`, `sh -c`, `env`, `sudo`, `xargs`,
|
|
1087
1087
|
`find -exec` or an absolute path, and after a `cd` or `git -C`. **The deny
|
|
@@ -59,7 +59,7 @@ export const OrchestratorPinRow = memo(function OrchestratorPinRow({
|
|
|
59
59
|
className={
|
|
60
60
|
active
|
|
61
61
|
? "bg-primary/10 border-primary/30"
|
|
62
|
-
: "bg-muted/50 hover:bg-muted"
|
|
62
|
+
: "bg-muted/50 hover:bg-muted has-[[data-chip]:hover]:bg-muted/50"
|
|
63
63
|
}
|
|
64
64
|
>
|
|
65
65
|
<Workflow
|
|
@@ -110,7 +110,8 @@ export const OrchestratorPinRow = memo(function OrchestratorPinRow({
|
|
|
110
110
|
<button
|
|
111
111
|
type="button"
|
|
112
112
|
aria-pressed={filtering}
|
|
113
|
-
|
|
113
|
+
data-chip
|
|
114
|
+
aria-label={`Show only ${label}'s work`}
|
|
114
115
|
onClick={(e) => {
|
|
115
116
|
e.stopPropagation();
|
|
116
117
|
sidebarUiActions.setOrchestrator(
|
|
@@ -118,9 +119,10 @@ export const OrchestratorPinRow = memo(function OrchestratorPinRow({
|
|
|
118
119
|
);
|
|
119
120
|
}}
|
|
120
121
|
className={cn(
|
|
121
|
-
"text-muted-foreground -mx-1 mt-0.5 flex min-h-6 flex-wrap items-center gap-x-2.5 rounded px-1 text-xs",
|
|
122
|
-
"hover:bg-
|
|
123
|
-
|
|
122
|
+
"text-muted-foreground -mx-1.5 mt-0.5 flex min-h-6 cursor-pointer flex-wrap items-center gap-x-2.5 self-start rounded-md px-1.5 text-xs transition-colors md:min-h-5",
|
|
123
|
+
"hover:bg-foreground/10 hover:text-foreground",
|
|
124
|
+
"focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none",
|
|
125
|
+
filtering && "bg-foreground/10 text-foreground"
|
|
124
126
|
)}
|
|
125
127
|
>
|
|
126
128
|
{chips.map((c) => (
|
|
@@ -124,7 +124,7 @@ Acting:
|
|
|
124
124
|
- \`${TOOL_NAMES.disarm}\` (task): stop an armed task merging by itself.
|
|
125
125
|
- \`${TOOL_NAMES.ask_saad}\` (title, detail, link?, kind, task?, sha?): park an item on Saad's asks list and carry on; it never waits.
|
|
126
126
|
|
|
127
|
-
Act through these tools, not the shell: they're scoped to this workspace and braked. The shell runs anything without asking (Saad chose this on 2026-10-11), so use it to read and investigate yourself: \`gh pr list\`, \`gh run view --log-failed\`, \`gh api\` GETs, \`curl\`, \`sqlite3 -readonly\`, git in any repository, a skill's scripts, pipes and chains. Never use it to get around the tools. A deny list refuses, naming the tool to use instead: merging, closing or retargeting a PR (\`${TOOL_NAMES.sign_off}\`, \`${TOOL_NAMES.arm}\`, \`${TOOL_NAMES.land}\`, \`${TOOL_NAMES.drop}\`), \`git push\` (\`${TOOL_NAMES.quick_pr}\`), writing in a project repository or task worktree other than your own quick changes (\`${TOOL_NAMES.start_task}\`, \`${TOOL_NAMES.quick_change}\`), writing AgentOS's state (sqlite3 without \`-readonly\`, or files in ~/.agent-os outside your folder), stopping or restarting AgentOS or its tmux, and reading secret files or
|
|
127
|
+
Act through these tools, not the shell: they're scoped to this workspace and braked. The shell runs anything without asking (Saad chose this on 2026-10-11), so use it to read and investigate yourself: \`gh pr list\`, \`gh run view --log-failed\`, \`gh api\` GETs, \`curl\`, \`sqlite3 -readonly\`, git in any repository, a skill's scripts, pipes and chains. Never use it to get around the tools. A deny list refuses, naming the tool to use instead: merging, closing or retargeting a PR (\`${TOOL_NAMES.sign_off}\`, \`${TOOL_NAMES.arm}\`, \`${TOOL_NAMES.land}\`, \`${TOOL_NAMES.drop}\`), \`git push\` (\`${TOOL_NAMES.quick_pr}\`), writing in a project repository or task worktree other than your own quick changes (\`${TOOL_NAMES.start_task}\`, \`${TOOL_NAMES.quick_change}\`), writing AgentOS's state (sqlite3 without \`-readonly\`, or files in ~/.agent-os outside your folder), stopping or restarting AgentOS or its tmux, and reading secret files (env files, keys, ~/.ssh, ~/.aws). Tokenvault is available through \`tv\`: use a token inside the command that needs it (e.g. \`FOO="\$(tv get <project> <desc>)" cmd\`), never print, echo or log a value, and never send one off the machine except to the service it's for. The list catches honest mistakes, not a determined bypass: a script or \`python -c\` could do any of these unseen, and doing so would break Saad's trust in every gate. \`aos notify "<text>"\` pushes a message to Saad's phone. Use it for what he'd want to see now and asked for: the morning report, a real milestone (a stack landed, a blocker only he can clear). Never for routine status: one a minute at most, and he reads the rest here. You can read files anywhere (Read, Grep, Glob), and write them (Write, Edit, NotebookEdit) anywhere except: a project repository or task worktree other than your own open quick changes' worktrees (start a task, or a quick change for a small edit, so the change goes through CI, review and scope), AgentOS's own state in ~/.agent-os outside your folder, secret files (.env, keys, ~/.ssh, ~/.aws, tokenvault and the like), and files that make something run: dotfiles and dot-folders at the top of your home (shell, git, Claude and tool config), ~/Library and /Library's launch agents, git's core.hooksPath folders, the folders on PATH, and any .git, .claude, .mcp.json, CLAUDE.md or AGENTS.md, which would hand you a shell or run code around the gates. Each write is checked before it runs, on the path with symlinks and \`..\` resolved; a refused one says why.
|
|
128
128
|
|
|
129
129
|
## Untrusted text
|
|
130
130
|
|
|
@@ -469,14 +469,13 @@ async function stopRefusal(
|
|
|
469
469
|
return null;
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
-
const SECRET_MSG = `Refused: orchestrators never read secrets (env files, keys, credential stores
|
|
472
|
+
const SECRET_MSG = `Refused: orchestrators never read secrets (env files, keys, credential stores). If a step needs one, ${T.ask_saad}.`;
|
|
473
|
+
|
|
474
|
+
// Orchestrators may read tokenvault's folders (and run `tv`); writing them
|
|
475
|
+
// is still refused by the write guard.
|
|
476
|
+
const TOKENVAULT_DIR = /(^|\/)tokenvault(\/|$)/;
|
|
473
477
|
|
|
474
478
|
function secretRefusal(inv: Invocation, cwd: string): string | null {
|
|
475
|
-
if (
|
|
476
|
-
(inv.name === "tv" || inv.name === "tokenvault") &&
|
|
477
|
-
/^(get|dump)$/.test(positionals(inv.args)[0] ?? "")
|
|
478
|
-
)
|
|
479
|
-
return SECRET_MSG;
|
|
480
479
|
for (const w of [...inv.args, ...inv.cmd.reads]) {
|
|
481
480
|
for (const p of [
|
|
482
481
|
w,
|
|
@@ -487,7 +486,12 @@ function secretRefusal(inv: Invocation, cwd: string): string | null {
|
|
|
487
486
|
/\//.test(p) ||
|
|
488
487
|
p.startsWith(".") ||
|
|
489
488
|
fs.existsSync(path.resolve(cwd, p));
|
|
490
|
-
if (
|
|
489
|
+
if (
|
|
490
|
+
pathish &&
|
|
491
|
+
isSecretPath(p) &&
|
|
492
|
+
!TOKENVAULT_DIR.test(path.resolve(cwd, p))
|
|
493
|
+
)
|
|
494
|
+
return SECRET_MSG;
|
|
491
495
|
}
|
|
492
496
|
}
|
|
493
497
|
return null;
|