@trycedar/argus 0.1.0 → 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/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/README.md +13 -7
- package/dist/index.js +98 -40
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 - 2026-05-13
|
|
4
|
+
|
|
5
|
+
**Breaking changes** — codename Argus is now the system identity, not just the npm scope. Existing 0.1.x workspaces auto-migrate.
|
|
6
|
+
|
|
7
|
+
### Breaking
|
|
8
|
+
|
|
9
|
+
- CLI binary renamed: `proactive` → `argus`. Update your install command (`npm i -g @trycedar/argus`) and any scripts that call `proactive`.
|
|
10
|
+
- Workspace state directory renamed: `.proactive/` → `.argus/`. The CLI auto-migrates on first run when only the legacy directory exists; manual rename is otherwise safe.
|
|
11
|
+
- Environment variables renamed: `PROACTIVE_CODEX_COMMAND` → `ARGUS_CODEX_COMMAND`, `PROACTIVE_CODEX_TIMEOUT_MS` → `ARGUS_CODEX_TIMEOUT_MS`. The legacy names continue to work for one release with a deprecation warning, then will be removed in 0.3.0.
|
|
12
|
+
|
|
13
|
+
### Fixed (rolled in from unreleased 0.1.1)
|
|
14
|
+
|
|
15
|
+
- `argus approve` / `argus reject` now update the matched inbox file in place instead of creating a duplicate `<id>.md` file when the source filename has a descriptive suffix. (task-018)
|
|
16
|
+
- Repeat approvals no longer stack `## CEO Response` sections; the latest response replaces any prior one.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Migration helper `migrateLegacyWorkspaceDir()` runs as a Commander `preAction` hook on every invocation. Idempotent and side-effect-free when no legacy directory is present.
|
|
21
|
+
- Codex provider temp-dir prefix renamed `proactive-codex-` → `argus-codex-`.
|
|
22
|
+
|
|
3
23
|
## 0.1.0 - 2026-05-13
|
|
4
24
|
|
|
5
25
|
Initial dogfood release candidate. Published as `@trycedar/argus` (codename Argus). The CLI binary is `proactive` in this release and will be renamed to `argus` in 0.2.0.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jacob Wang and Argus contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Argus
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@trycedar/argus)
|
|
4
|
+
[](https://github.com/xiangkangjw/argus/actions/workflows/validate.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](./tsconfig.json)
|
|
8
|
+
|
|
9
|
+
> A Git-native agentic organization framework where a human CEO directs proactive role agents that create tasks, produce artifacts, request approvals, and help build software products. Codename: Argus.
|
|
4
10
|
|
|
5
11
|
## Vision
|
|
6
12
|
|
|
@@ -16,7 +22,7 @@ Proactive AI is not multi-agent chat. It is a local-first company workspace wher
|
|
|
16
22
|
|
|
17
23
|
## Current status
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
`@trycedar/argus@0.2.0` — dogfood release. The CLI binary is `argus`. Workspaces from 0.1.x auto-migrate on first run.
|
|
20
26
|
|
|
21
27
|
Key docs:
|
|
22
28
|
|
|
@@ -32,7 +38,7 @@ Key docs:
|
|
|
32
38
|
This repo includes the initial Proactive AI workspace structure:
|
|
33
39
|
|
|
34
40
|
```text
|
|
35
|
-
.
|
|
41
|
+
.argus/
|
|
36
42
|
company/
|
|
37
43
|
tasks/
|
|
38
44
|
artifacts/
|
|
@@ -65,14 +71,14 @@ From source:
|
|
|
65
71
|
pnpm install
|
|
66
72
|
pnpm build
|
|
67
73
|
pnpm link --global
|
|
68
|
-
|
|
74
|
+
argus --help
|
|
69
75
|
```
|
|
70
76
|
|
|
71
77
|
After npm publication:
|
|
72
78
|
|
|
73
79
|
```bash
|
|
74
80
|
npm install -g @trycedar/argus
|
|
75
|
-
|
|
81
|
+
argus --help
|
|
76
82
|
```
|
|
77
83
|
|
|
78
84
|
## CLI
|
|
@@ -92,7 +98,7 @@ pnpm exec tsx src/cli/index.ts reject <item-id> --response "Rejected"
|
|
|
92
98
|
pnpm exec tsx src/cli/index.ts agents
|
|
93
99
|
```
|
|
94
100
|
|
|
95
|
-
`
|
|
101
|
+
`argus run --no-ai` scans the workspace and plans agent wakeups without invoking Codex. `argus run --provider stub` performs a controlled dogfood run with deterministic stubbed agent output. Running without `--no-ai` uses the default `CodexProvider`, which shells out to `codex exec`; set `ARGUS_CODEX_COMMAND` if the executable name differs.
|
|
96
102
|
|
|
97
103
|
## Property-management demo
|
|
98
104
|
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile7 } from
|
|
|
7
7
|
|
|
8
8
|
// src/workspace/init.ts
|
|
9
9
|
import { mkdir as mkdir2, writeFile as writeFile3 } from "fs/promises";
|
|
10
|
-
import
|
|
10
|
+
import path4 from "path";
|
|
11
11
|
import YAML from "yaml";
|
|
12
12
|
|
|
13
13
|
// src/markdown/frontmatter.ts
|
|
@@ -129,7 +129,48 @@ async function readEvents(workspaceRoot) {
|
|
|
129
129
|
|
|
130
130
|
// src/workspace/state.ts
|
|
131
131
|
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
132
|
+
import path3 from "path";
|
|
133
|
+
|
|
134
|
+
// src/workspace/paths.ts
|
|
135
|
+
import { rename } from "fs/promises";
|
|
132
136
|
import path2 from "path";
|
|
137
|
+
var WORKSPACE_DIR = ".argus";
|
|
138
|
+
var LEGACY_WORKSPACE_DIR = ".proactive";
|
|
139
|
+
async function migrateLegacyWorkspaceDir(workspaceRoot) {
|
|
140
|
+
const fs = await import("fs/promises");
|
|
141
|
+
const legacy = path2.join(workspaceRoot, LEGACY_WORKSPACE_DIR);
|
|
142
|
+
const target = path2.join(workspaceRoot, WORKSPACE_DIR);
|
|
143
|
+
const [legacyExists, targetExists] = await Promise.all([
|
|
144
|
+
fs.stat(legacy).then(
|
|
145
|
+
() => true,
|
|
146
|
+
() => false
|
|
147
|
+
),
|
|
148
|
+
fs.stat(target).then(
|
|
149
|
+
() => true,
|
|
150
|
+
() => false
|
|
151
|
+
)
|
|
152
|
+
]);
|
|
153
|
+
if (!legacyExists || targetExists) return false;
|
|
154
|
+
await rename(legacy, target);
|
|
155
|
+
console.warn(
|
|
156
|
+
`[argus] migrated legacy workspace directory ${LEGACY_WORKSPACE_DIR}/ -> ${WORKSPACE_DIR}/`
|
|
157
|
+
);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
var taskStatusToDirectory = {
|
|
161
|
+
backlog: "backlog",
|
|
162
|
+
ready: "ready",
|
|
163
|
+
in_progress: "in-progress",
|
|
164
|
+
review: "review",
|
|
165
|
+
done: "done",
|
|
166
|
+
blocked: "blocked",
|
|
167
|
+
cancelled: "cancelled"
|
|
168
|
+
};
|
|
169
|
+
function resolveWorkspace(root = process.cwd()) {
|
|
170
|
+
return path2.resolve(root);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// src/workspace/state.ts
|
|
133
174
|
function initialState() {
|
|
134
175
|
return {
|
|
135
176
|
last_event_id: "evt-001",
|
|
@@ -139,7 +180,7 @@ function initialState() {
|
|
|
139
180
|
};
|
|
140
181
|
}
|
|
141
182
|
async function readState(workspaceRoot) {
|
|
142
|
-
const statePath =
|
|
183
|
+
const statePath = path3.join(workspaceRoot, WORKSPACE_DIR, "state.json");
|
|
143
184
|
try {
|
|
144
185
|
return workspaceStateSchema.parse(
|
|
145
186
|
JSON.parse(await readFile2(statePath, "utf8"))
|
|
@@ -151,7 +192,7 @@ async function readState(workspaceRoot) {
|
|
|
151
192
|
}
|
|
152
193
|
}
|
|
153
194
|
async function writeState(workspaceRoot, state) {
|
|
154
|
-
const statePath =
|
|
195
|
+
const statePath = path3.join(workspaceRoot, WORKSPACE_DIR, "state.json");
|
|
155
196
|
await writeFile2(
|
|
156
197
|
statePath,
|
|
157
198
|
`${JSON.stringify(workspaceStateSchema.parse(state), null, 2)}
|
|
@@ -272,7 +313,7 @@ var decisionsTemplate = `# Decisions
|
|
|
272
313
|
|
|
273
314
|
// src/workspace/init.ts
|
|
274
315
|
var directories = [
|
|
275
|
-
|
|
316
|
+
WORKSPACE_DIR,
|
|
276
317
|
"company",
|
|
277
318
|
"tasks/backlog",
|
|
278
319
|
"tasks/ready",
|
|
@@ -292,10 +333,10 @@ var directories = [
|
|
|
292
333
|
];
|
|
293
334
|
async function initializeWorkspace(workspaceRoot, workspaceName) {
|
|
294
335
|
for (const directory of directories) {
|
|
295
|
-
await mkdir2(
|
|
336
|
+
await mkdir2(path4.join(workspaceRoot, directory), { recursive: true });
|
|
296
337
|
}
|
|
297
338
|
await writeFile3(
|
|
298
|
-
|
|
339
|
+
path4.join(workspaceRoot, WORKSPACE_DIR, "config.yaml"),
|
|
299
340
|
YAML.stringify({
|
|
300
341
|
workspace_name: workspaceName,
|
|
301
342
|
schema_version: 0,
|
|
@@ -306,20 +347,20 @@ async function initializeWorkspace(workspaceRoot, workspaceName) {
|
|
|
306
347
|
);
|
|
307
348
|
await writeState(workspaceRoot, initialState());
|
|
308
349
|
await writeFile3(
|
|
309
|
-
|
|
350
|
+
path4.join(workspaceRoot, "company", "mission.md"),
|
|
310
351
|
missionTemplate(workspaceName)
|
|
311
352
|
);
|
|
312
353
|
await writeFile3(
|
|
313
|
-
|
|
354
|
+
path4.join(workspaceRoot, "company", "strategy.md"),
|
|
314
355
|
strategyTemplate
|
|
315
356
|
);
|
|
316
357
|
await writeFile3(
|
|
317
|
-
|
|
358
|
+
path4.join(workspaceRoot, "company", "decisions.md"),
|
|
318
359
|
decisionsTemplate
|
|
319
360
|
);
|
|
320
361
|
for (const agent of defaultAgents) {
|
|
321
362
|
await writeFile3(
|
|
322
|
-
|
|
363
|
+
path4.join(workspaceRoot, "agents", agent.filename),
|
|
323
364
|
stringifyMarkdown(agent.data, agent.body)
|
|
324
365
|
);
|
|
325
366
|
}
|
|
@@ -333,23 +374,8 @@ async function initializeWorkspace(workspaceRoot, workspaceName) {
|
|
|
333
374
|
await appendEvent(workspaceRoot, event);
|
|
334
375
|
}
|
|
335
376
|
|
|
336
|
-
// src/workspace/paths.ts
|
|
337
|
-
import path4 from "path";
|
|
338
|
-
var taskStatusToDirectory = {
|
|
339
|
-
backlog: "backlog",
|
|
340
|
-
ready: "ready",
|
|
341
|
-
in_progress: "in-progress",
|
|
342
|
-
review: "review",
|
|
343
|
-
done: "done",
|
|
344
|
-
blocked: "blocked",
|
|
345
|
-
cancelled: "cancelled"
|
|
346
|
-
};
|
|
347
|
-
function resolveWorkspace(root = process.cwd()) {
|
|
348
|
-
return path4.resolve(root);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
377
|
// src/tasks/task-store.ts
|
|
352
|
-
import { mkdir as mkdir3, readFile as readFile3, rename, writeFile as writeFile4 } from "fs/promises";
|
|
378
|
+
import { mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile4 } from "fs/promises";
|
|
353
379
|
import path5 from "path";
|
|
354
380
|
import fg from "fast-glob";
|
|
355
381
|
function taskFilename(task) {
|
|
@@ -421,16 +447,21 @@ async function writeInboxItem(workspaceRoot, item, content) {
|
|
|
421
447
|
return relativePath;
|
|
422
448
|
}
|
|
423
449
|
async function respondToInboxItem(workspaceRoot, doc, status, response) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
450
|
+
const updatedItem = inboxItemSchema.parse({
|
|
451
|
+
...doc.item,
|
|
452
|
+
status,
|
|
453
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
454
|
+
});
|
|
455
|
+
const baseContent = doc.content.replace(/\n*##\s+CEO Response[\s\S]*$/m, "");
|
|
456
|
+
const nextContent = `${baseContent.trimEnd()}
|
|
428
457
|
|
|
429
458
|
## CEO Response
|
|
430
459
|
|
|
431
460
|
${response}
|
|
432
|
-
|
|
433
|
-
);
|
|
461
|
+
`;
|
|
462
|
+
const absolutePath = path6.join(workspaceRoot, doc.path);
|
|
463
|
+
await mkdir4(path6.dirname(absolutePath), { recursive: true });
|
|
464
|
+
await writeFile5(absolutePath, stringifyMarkdown(updatedItem, nextContent));
|
|
434
465
|
}
|
|
435
466
|
|
|
436
467
|
// src/agents/agent-store.ts
|
|
@@ -916,13 +947,32 @@ import { mkdtemp, readFile as readFile8, rm } from "fs/promises";
|
|
|
916
947
|
import os from "os";
|
|
917
948
|
import path11 from "path";
|
|
918
949
|
import { execa } from "execa";
|
|
950
|
+
function resolveCodexCommand() {
|
|
951
|
+
if (process.env.ARGUS_CODEX_COMMAND) return process.env.ARGUS_CODEX_COMMAND;
|
|
952
|
+
if (process.env.PROACTIVE_CODEX_COMMAND) {
|
|
953
|
+
console.warn(
|
|
954
|
+
"[argus] PROACTIVE_CODEX_COMMAND is deprecated; use ARGUS_CODEX_COMMAND."
|
|
955
|
+
);
|
|
956
|
+
return process.env.PROACTIVE_CODEX_COMMAND;
|
|
957
|
+
}
|
|
958
|
+
return "codex";
|
|
959
|
+
}
|
|
960
|
+
function resolveCodexTimeoutMs() {
|
|
961
|
+
const raw = process.env.ARGUS_CODEX_TIMEOUT_MS ?? process.env.PROACTIVE_CODEX_TIMEOUT_MS;
|
|
962
|
+
if (process.env.PROACTIVE_CODEX_TIMEOUT_MS && !process.env.ARGUS_CODEX_TIMEOUT_MS) {
|
|
963
|
+
console.warn(
|
|
964
|
+
"[argus] PROACTIVE_CODEX_TIMEOUT_MS is deprecated; use ARGUS_CODEX_TIMEOUT_MS."
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
return Number.parseInt(raw ?? "120000", 10);
|
|
968
|
+
}
|
|
919
969
|
var CodexProvider = class {
|
|
920
|
-
constructor(command =
|
|
970
|
+
constructor(command = resolveCodexCommand()) {
|
|
921
971
|
this.command = command;
|
|
922
972
|
}
|
|
923
973
|
command;
|
|
924
974
|
async complete(request) {
|
|
925
|
-
const tempDir = await mkdtemp(path11.join(os.tmpdir(), "
|
|
975
|
+
const tempDir = await mkdtemp(path11.join(os.tmpdir(), "argus-codex-"));
|
|
926
976
|
const outputPath = path11.join(tempDir, "last-message.txt");
|
|
927
977
|
try {
|
|
928
978
|
const result = await execa(
|
|
@@ -943,10 +993,7 @@ Do not inspect files or run commands. Return only the JSON object requested abov
|
|
|
943
993
|
reject: false,
|
|
944
994
|
env: process.env,
|
|
945
995
|
stdin: "ignore",
|
|
946
|
-
timeout:
|
|
947
|
-
process.env.PROACTIVE_CODEX_TIMEOUT_MS ?? "120000",
|
|
948
|
-
10
|
|
949
|
-
)
|
|
996
|
+
timeout: resolveCodexTimeoutMs()
|
|
950
997
|
}
|
|
951
998
|
);
|
|
952
999
|
if (result.exitCode !== 0) {
|
|
@@ -1044,11 +1091,22 @@ function propertyManagementActions(agentId) {
|
|
|
1044
1091
|
|
|
1045
1092
|
// src/cli/index.ts
|
|
1046
1093
|
var program = new Command();
|
|
1047
|
-
program.name("
|
|
1094
|
+
program.name("argus").description(
|
|
1095
|
+
"Argus \u2014 Git-native proactive AI agent organization framework CLI"
|
|
1096
|
+
).version("0.2.0").hook("preAction", async () => {
|
|
1097
|
+
try {
|
|
1098
|
+
await migrateLegacyWorkspaceDir(process.cwd());
|
|
1099
|
+
} catch (error) {
|
|
1100
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1101
|
+
throw new Error(
|
|
1102
|
+
`Failed to migrate legacy .proactive/ workspace to .argus/: ${message}. Resolve the underlying issue (permissions, cross-device, busy file) then re-run. To migrate manually: \`mv .proactive .argus\`.`
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1048
1106
|
program.command("init").argument("<workspace-name>").option("--root <path>", "workspace root; defaults to ./<workspace-name>").action(async (workspaceName, options) => {
|
|
1049
1107
|
const root = path12.resolve(options.root ?? workspaceName);
|
|
1050
1108
|
await initializeWorkspace(root, workspaceName);
|
|
1051
|
-
console.log(`Initialized
|
|
1109
|
+
console.log(`Initialized Argus workspace at ${root}`);
|
|
1052
1110
|
});
|
|
1053
1111
|
program.command("ceo").argument("<instruction>").action(async (instruction) => {
|
|
1054
1112
|
const root = resolveWorkspace();
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trycedar/argus",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "Argus — Git-native proactive AI agent organization framework CLI.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"packageManager": "pnpm@10.25.0",
|
|
7
8
|
"bin": {
|
|
8
|
-
"
|
|
9
|
+
"argus": "dist/index.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist",
|
|
12
13
|
"README.md",
|
|
13
|
-
"CHANGELOG.md"
|
|
14
|
+
"CHANGELOG.md",
|
|
15
|
+
"LICENSE"
|
|
14
16
|
],
|
|
15
17
|
"publishConfig": {
|
|
16
18
|
"access": "public"
|