@doriandev/devcc 0.2.0 → 0.3.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 +39 -9
- package/bin/devcc.mjs +2 -2
- package/dist/devcc/agents/agents.d.ts +7 -0
- package/dist/devcc/agents/agents.d.ts.map +1 -1
- package/dist/devcc/agents/agents.js +3 -0
- package/dist/devcc/agents/agents.js.map +1 -1
- package/dist/devcc/app/App.d.ts +8 -0
- package/dist/devcc/app/App.d.ts.map +1 -1
- package/dist/devcc/app/App.js +125 -2
- package/dist/devcc/app/App.js.map +1 -1
- package/dist/devcc/app/controlPlaneCommands.d.ts.map +1 -1
- package/dist/devcc/app/controlPlaneCommands.js +25 -0
- package/dist/devcc/app/controlPlaneCommands.js.map +1 -1
- package/dist/devcc/app/keymap.d.ts.map +1 -1
- package/dist/devcc/app/keymap.js +1 -0
- package/dist/devcc/app/keymap.js.map +1 -1
- package/dist/devcc/automation.d.ts +21 -0
- package/dist/devcc/automation.d.ts.map +1 -1
- package/dist/devcc/automation.js +138 -1
- package/dist/devcc/automation.js.map +1 -1
- package/dist/devcc/cli.d.ts.map +1 -1
- package/dist/devcc/cli.js +30 -3
- package/dist/devcc/cli.js.map +1 -1
- package/dist/devcc/core/commands.d.ts +8 -0
- package/dist/devcc/core/commands.d.ts.map +1 -1
- package/dist/devcc/core/commands.js.map +1 -1
- package/dist/devcc/core/config.d.ts +2 -0
- package/dist/devcc/core/config.d.ts.map +1 -1
- package/dist/devcc/core/config.js +4 -0
- package/dist/devcc/core/config.js.map +1 -1
- package/dist/devcc/index.d.ts +4 -2
- package/dist/devcc/index.d.ts.map +1 -1
- package/dist/devcc/index.js +4 -2
- package/dist/devcc/index.js.map +1 -1
- package/dist/devcc/init/detect.d.ts +55 -0
- package/dist/devcc/init/detect.d.ts.map +1 -0
- package/dist/devcc/init/detect.js +207 -0
- package/dist/devcc/init/detect.js.map +1 -0
- package/dist/devcc/init/prompt.d.ts +25 -0
- package/dist/devcc/init/prompt.d.ts.map +1 -0
- package/dist/devcc/init/prompt.js +156 -0
- package/dist/devcc/init/prompt.js.map +1 -0
- package/dist/devcc/services/node.d.ts +11 -0
- package/dist/devcc/services/node.d.ts.map +1 -1
- package/dist/devcc/services/node.js +20 -18
- package/dist/devcc/services/node.js.map +1 -1
- package/dist/devcc/views/OverviewView.d.ts.map +1 -1
- package/dist/devcc/views/OverviewView.js +3 -1
- package/dist/devcc/views/OverviewView.js.map +1 -1
- package/package.json +1 -1
- package/src/devcc/agents/agents.ts +10 -0
- package/src/devcc/app/App.ts +153 -2
- package/src/devcc/app/controlPlaneCommands.ts +30 -0
- package/src/devcc/app/keymap.ts +1 -0
- package/src/devcc/automation.ts +168 -1
- package/src/devcc/cli.ts +35 -3
- package/src/devcc/core/commands.ts +8 -0
- package/src/devcc/core/config.ts +4 -0
- package/src/devcc/index.ts +10 -1
- package/src/devcc/init/detect.ts +268 -0
- package/src/devcc/init/prompt.ts +179 -0
- package/src/devcc/services/node.ts +17 -14
- package/src/devcc/views/OverviewView.ts +8 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ project. Built with [OpenTUI](https://opentui.com).
|
|
|
11
11
|
```bash
|
|
12
12
|
npm i -g @doriandev/devcc # or: pnpm add -g @doriandev/devcc
|
|
13
13
|
cd ~/code/example.com
|
|
14
|
+
devcc init --agent claude # optional: let an agent write .devcc.ts (or: devcc init)
|
|
14
15
|
devcc
|
|
15
16
|
```
|
|
16
17
|
|
|
@@ -118,15 +119,20 @@ devcc -C ~/code/example.com
|
|
|
118
119
|
| `devcc verify [--json]` | Run the project's verification steps; exit 0 only if all pass |
|
|
119
120
|
| `devcc worktree list [--json]` | List git worktrees |
|
|
120
121
|
| `devcc env [--json]` | Report installed tools, mise runtimes and direnv status |
|
|
121
|
-
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
129
|
-
|
|
122
|
+
| `devcc init` | Write a starter `.devcc.ts` from what devcc detects |
|
|
123
|
+
| `devcc init --agent <id>` | Let Claude Code or Codex inspect the project and set it up |
|
|
124
|
+
| `devcc init --prompt` | Print that setup prompt for any other agent |
|
|
125
|
+
| `devcc config check [--json]` | Validate the config; exit 0 only when it has no issues |
|
|
126
|
+
|
|
127
|
+
| Option | Description |
|
|
128
|
+
| ------------------- | -------------------------------------------------------- |
|
|
129
|
+
| `-C`, `--cwd <dir>` | Project directory (default: nearest project root) |
|
|
130
|
+
| `--json` | One JSON document on stdout, no colour or escape codes |
|
|
131
|
+
| `--force` | `init`: replace an existing `.devcc.ts` with the starter |
|
|
132
|
+
| `-h`, `--help` | Show usage |
|
|
133
|
+
| `-v`, `--version` | Show the version |
|
|
134
|
+
|
|
135
|
+
`verify`, `worktree list`, `env`, `init` and `config check` do not load the dashboard, so they run on any Node ≥ 20 without Bun,
|
|
130
136
|
which is what you want in CI or inside an agent's sandbox.
|
|
131
137
|
|
|
132
138
|
```bash
|
|
@@ -275,6 +281,30 @@ detected automatically.
|
|
|
275
281
|
|
|
276
282
|
## Configuration
|
|
277
283
|
|
|
284
|
+
### Setting up a project
|
|
285
|
+
|
|
286
|
+
devcc works without a config file, but a good `.devcc.ts` is what makes processes, verification and the
|
|
287
|
+
palette useful. There are three ways to get one:
|
|
288
|
+
|
|
289
|
+
- **`devcc init`** writes a starter from what it can read without running anything: the package manager,
|
|
290
|
+
a `dev` script and its framework's port, and verify steps from existing scripts (format check, lint,
|
|
291
|
+
typecheck, tests, build). Scripts that watch, write files or are npm's placeholder are left out. Rust
|
|
292
|
+
and Go projects get their toolchain's standard checks.
|
|
293
|
+
- **`devcc init --agent claude`** (or `codex`) opens that agent in your terminal with a setup prompt
|
|
294
|
+
built for this project: what devcc detected, the starter as a draft, the full config reference, and
|
|
295
|
+
firm rules (never invent commands or ports, never add secrets or hostnames, keep verify
|
|
296
|
+
non-interactive, confirm anything destructive). The agent reads the README, CI workflows and framework
|
|
297
|
+
configs, writes `.devcc.ts`, and runs `devcc config check` until it is clean. You watch and approve its
|
|
298
|
+
edits as usual. `devcc init --prompt` prints the same prompt for any other agent.
|
|
299
|
+
- **In the dashboard**, a project without config shows a hint. The palette offers "Project: set up
|
|
300
|
+
.devcc.ts from detected scripts", and "Project: set up .devcc.ts with Claude Code / Codex" (also for
|
|
301
|
+
improving an existing config). The dashboard's agent runs headless and cannot edit files, so it prints
|
|
302
|
+
its proposal; devcc validates it, saves it to `.devcc/proposed.devcc.ts` for review, and writes it
|
|
303
|
+
only after you confirm. The project then reloads with the new config.
|
|
304
|
+
|
|
305
|
+
Nothing is set up automatically, and an existing config is never replaced without `--force` or a
|
|
306
|
+
confirmation.
|
|
307
|
+
|
|
278
308
|
### Without a config file
|
|
279
309
|
|
|
280
310
|
Run `devcc` in a project with no configuration and it detects all of this, so Overview, Scripts, Git,
|
package/bin/devcc.mjs
CHANGED
|
@@ -23,7 +23,7 @@ const nodeSupportsFfi =
|
|
|
23
23
|
|
|
24
24
|
// `devcc verify`, `devcc worktree list` and `devcc env` never load the TUI, so
|
|
25
25
|
// they run right here on any Node - important for CI and coding agents.
|
|
26
|
-
const AUTOMATION_COMMANDS = new Set(["verify", "worktree", "env"])
|
|
26
|
+
const AUTOMATION_COMMANDS = new Set(["verify", "worktree", "env", "init", "config"])
|
|
27
27
|
const runsWithoutTui = AUTOMATION_COMMANDS.has(firstPositional(process.argv.slice(2)) ?? "")
|
|
28
28
|
|
|
29
29
|
if (isBun || nodeSupportsFfi || (runsWithoutTui && existsSync(distEntry))) {
|
|
@@ -81,7 +81,7 @@ function hasCommand(command) {
|
|
|
81
81
|
function firstPositional(argv) {
|
|
82
82
|
for (let index = 0; index < argv.length; index += 1) {
|
|
83
83
|
const arg = argv[index]
|
|
84
|
-
if (arg === "-C" || arg === "--cwd") index += 1
|
|
84
|
+
if (arg === "-C" || arg === "--cwd" || arg === "--agent") index += 1
|
|
85
85
|
else if (!arg.startsWith("-")) return arg
|
|
86
86
|
}
|
|
87
87
|
return undefined
|
|
@@ -32,6 +32,11 @@ export interface AgentAdapter {
|
|
|
32
32
|
* cannot be read as an option. Tasks starting with `-` are refused otherwise.
|
|
33
33
|
*/
|
|
34
34
|
separatesPrompt: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* argv to start the agent's interactive session with `prompt` as the first
|
|
37
|
+
* message. Only for agents known to support it (the built-ins).
|
|
38
|
+
*/
|
|
39
|
+
interactiveArgs?: (prompt: string) => string[];
|
|
35
40
|
}
|
|
36
41
|
export interface AgentConfig {
|
|
37
42
|
/** Display name (defaults per built-in, or to the id). */
|
|
@@ -63,6 +68,8 @@ interface BuiltinAgent {
|
|
|
63
68
|
command: string;
|
|
64
69
|
/** Where the prompt goes relative to the user's extra args. */
|
|
65
70
|
args: (extra: string[], prompt: string) => string[];
|
|
71
|
+
/** Interactive session opened with `prompt` as the first message. */
|
|
72
|
+
interactiveArgs: (extra: string[], prompt: string) => string[];
|
|
66
73
|
}
|
|
67
74
|
/**
|
|
68
75
|
* Non-interactive invocations: `claude -p -- <prompt>` and `codex exec -- <prompt>`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/devcc/agents/agents.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACrG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAEpE,OAAO,EAAQ,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD;;;;;;;GAOG;AAEH,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9B,kDAAkD;IAClD,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;IAClC;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/devcc/agents/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,11 +13,13 @@ export const BUILTIN_AGENTS = {
|
|
|
13
13
|
name: "Claude Code",
|
|
14
14
|
command: "claude",
|
|
15
15
|
args: (extra, prompt) => [...extra, "-p", "--", prompt],
|
|
16
|
+
interactiveArgs: (extra, prompt) => [...extra, "--", prompt],
|
|
16
17
|
},
|
|
17
18
|
codex: {
|
|
18
19
|
name: "Codex",
|
|
19
20
|
command: "codex",
|
|
20
21
|
args: (extra, prompt) => ["exec", ...extra, "--", prompt],
|
|
22
|
+
interactiveArgs: (extra, prompt) => [...extra, "--", prompt],
|
|
21
23
|
},
|
|
22
24
|
};
|
|
23
25
|
/**
|
|
@@ -48,6 +50,7 @@ export function createAgentAdapters(config = {}, run = exec) {
|
|
|
48
50
|
// option's value, e.g. `--message`), so they cannot take a `--` guard.
|
|
49
51
|
args: (prompt) => (builtin ? builtin.args(extra, prompt) : [...extra, prompt]),
|
|
50
52
|
separatesPrompt: builtin !== undefined,
|
|
53
|
+
interactiveArgs: builtin ? (prompt) => builtin.interactiveArgs(extra, prompt) : undefined,
|
|
51
54
|
});
|
|
52
55
|
}
|
|
53
56
|
return adapters;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/devcc/agents/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,QAAQ,EAA8C,MAAM,gCAAgC,CAAA;AAErG,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAqC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/devcc/agents/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/devcc/app/App.d.ts
CHANGED
|
@@ -170,6 +170,14 @@ export declare class App {
|
|
|
170
170
|
*/
|
|
171
171
|
private runVerify;
|
|
172
172
|
private processStepExecutor;
|
|
173
|
+
private setUpConfig;
|
|
174
|
+
/**
|
|
175
|
+
* The setup agent exited: take the config it printed, validate it from a
|
|
176
|
+
* scratch file under .devcc/, and write it only if the user agrees.
|
|
177
|
+
*/
|
|
178
|
+
private finishConfigSetup;
|
|
179
|
+
/** Rebuild the active project's session so a changed config takes effect. */
|
|
180
|
+
private reloadConfig;
|
|
173
181
|
/** Update a single package, gated by a confirmation (it rewrites the lockfile). */
|
|
174
182
|
private updateDependency;
|
|
175
183
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/devcc/app/App.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,WAAW,EAAiB,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/devcc/app/App.ts"],"names":[],"mappings":"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"}
|
package/dist/devcc/app/App.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { BoxRenderable, createCliRenderer } from "@opentui/core";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { basename, join, resolve } from "node:path";
|
|
4
4
|
import { AgentManager, createAgentAdapters } from "../agents/agents.js";
|
|
5
|
+
import { configProblems } from "../automation.js";
|
|
6
|
+
import { detectProject, renderStarterConfig } from "../init/detect.js";
|
|
7
|
+
import { buildSetupPrompt, extractConfigFromOutput } from "../init/prompt.js";
|
|
5
8
|
import { ConfirmDialog, PromptDialog } from "../components/ConfirmDialog.js";
|
|
6
9
|
import { Footer } from "../components/Footer.js";
|
|
7
10
|
import { Header } from "../components/Header.js";
|
|
@@ -10,7 +13,7 @@ import { Sidebar } from "../components/Sidebar.js";
|
|
|
10
13
|
import { CommandPalette } from "../components/CommandPalette.js";
|
|
11
14
|
import { ProjectPicker } from "../components/ProjectPicker.js";
|
|
12
15
|
import { CommandRegistry } from "../core/commands.js";
|
|
13
|
-
import { loadConfig } from "../core/config.js";
|
|
16
|
+
import { loadConfig, loadConfigFile } from "../core/config.js";
|
|
14
17
|
import { EnvironmentService } from "../environment/EnvironmentService.js";
|
|
15
18
|
import { Subscriptions } from "../core/events.js";
|
|
16
19
|
import { createInitialSelection, createInitialState, NARROW_WIDTH, setSelection, shallowArrayEqual, Store, updateUi, VIEW_IDS, } from "../core/state.js";
|
|
@@ -250,6 +253,7 @@ export class App {
|
|
|
250
253
|
verify: { configured: resolvedVerify.steps.length, running: false, steps: [] },
|
|
251
254
|
verifyIssues: [...loaded.issues.filter(isVerifyIssue), ...resolvedVerify.issues],
|
|
252
255
|
verifyAbort: null,
|
|
256
|
+
setupAgentSessionId: null,
|
|
253
257
|
scripts,
|
|
254
258
|
scriptRuns: {},
|
|
255
259
|
wiring: new Subscriptions(),
|
|
@@ -271,6 +275,9 @@ export class App {
|
|
|
271
275
|
for (const issue of this.session.project.configIssues) {
|
|
272
276
|
this.pushNotification("warn", `Config: ${issue}`);
|
|
273
277
|
}
|
|
278
|
+
if (!this.session.project.configPath) {
|
|
279
|
+
this.pushNotification("info", "No .devcc.ts yet: press / and run “Project: set up .devcc.ts”");
|
|
280
|
+
}
|
|
274
281
|
}
|
|
275
282
|
// ---------------------------------------------------------------------
|
|
276
283
|
// UI construction
|
|
@@ -385,6 +392,8 @@ export class App {
|
|
|
385
392
|
processes.on("process:exit", (process) => {
|
|
386
393
|
this.finishScriptRun(session, process.id, process.exitCode ?? 0);
|
|
387
394
|
syncProcesses();
|
|
395
|
+
if (process.id === session.setupAgentSessionId)
|
|
396
|
+
void this.finishConfigSetup(session, process);
|
|
388
397
|
});
|
|
389
398
|
processes.on("process:error", (error) => notify("error", error.message, error.detail));
|
|
390
399
|
processes.on("process:retry", (managed, delayMs) => {
|
|
@@ -958,6 +967,8 @@ export class App {
|
|
|
958
967
|
runVerify: () => this.runVerify(),
|
|
959
968
|
remoteMachines: () => this.config.remoteMachines,
|
|
960
969
|
sshTo: (machineId) => this.sshTo(machineId),
|
|
970
|
+
setUpConfig: (how) => this.setUpConfig(how),
|
|
971
|
+
reloadConfig: () => this.reloadConfig(),
|
|
961
972
|
quit: () => void this.quit(),
|
|
962
973
|
};
|
|
963
974
|
// Session services are swapped out on a project switch, so expose them as
|
|
@@ -1454,6 +1465,118 @@ export class App {
|
|
|
1454
1465
|
};
|
|
1455
1466
|
}
|
|
1456
1467
|
// ---------------------------------------------------------------------
|
|
1468
|
+
// Project setup (.devcc.ts)
|
|
1469
|
+
// ---------------------------------------------------------------------
|
|
1470
|
+
async setUpConfig(how) {
|
|
1471
|
+
const session = this.session;
|
|
1472
|
+
const facts = detectProject(session.rootDir);
|
|
1473
|
+
if (how === "starter") {
|
|
1474
|
+
if (facts.configPath) {
|
|
1475
|
+
const replace = await this.askConfirm("Replace the existing config with a starter?", `${tildify(facts.configPath)} will be overwritten with what devcc detects. Consider setting it up with an agent instead, which keeps what is still right.`);
|
|
1476
|
+
if (!replace)
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
const target = join(session.rootDir, ".devcc.ts");
|
|
1480
|
+
writeFileSync(target, renderStarterConfig(facts), "utf8");
|
|
1481
|
+
this.pushNotification("success", `Created ${tildify(target)}`);
|
|
1482
|
+
await this.reloadConfig();
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1485
|
+
const adapter = this.agents.get(how);
|
|
1486
|
+
if (!adapter) {
|
|
1487
|
+
this.pushNotification("warn", `Unknown agent "${how}"`);
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
if (session.setupAgentSessionId && session.processes.isRunning(session.setupAgentSessionId)) {
|
|
1491
|
+
this.pushNotification("warn", "An agent is already setting up .devcc.ts");
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
try {
|
|
1495
|
+
const agentSession = await this.agents.launch(how, {
|
|
1496
|
+
cwd: session.rootDir,
|
|
1497
|
+
prompt: buildSetupPrompt(facts, "print"),
|
|
1498
|
+
});
|
|
1499
|
+
session.setupAgentSessionId = agentSession.id;
|
|
1500
|
+
updateUi(this.store, { logSource: agentSession.id });
|
|
1501
|
+
this.pushNotification("info", `${adapter.name} is reading the project; devcc will offer its .devcc.ts when it finishes`);
|
|
1502
|
+
}
|
|
1503
|
+
catch (error) {
|
|
1504
|
+
const devccError = toDevccError(error, "process");
|
|
1505
|
+
this.pushNotification("error", devccError.message, devccError.detail);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* The setup agent exited: take the config it printed, validate it from a
|
|
1510
|
+
* scratch file under .devcc/, and write it only if the user agrees.
|
|
1511
|
+
*/
|
|
1512
|
+
async finishConfigSetup(session, agent) {
|
|
1513
|
+
session.setupAgentSessionId = null;
|
|
1514
|
+
const name = session.project.name;
|
|
1515
|
+
if (agent.exitCode !== 0) {
|
|
1516
|
+
this.pushNotification("error", `[${name}] Config setup agent exited with code ${agent.exitCode ?? "?"}; see its logs`);
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
const output = (session.logs.get(agent.id)?.toArray() ?? [])
|
|
1520
|
+
.filter((entry) => entry.stream !== "system")
|
|
1521
|
+
.map((entry) => entry.text)
|
|
1522
|
+
.join("\n");
|
|
1523
|
+
const proposal = extractConfigFromOutput(output);
|
|
1524
|
+
if (!proposal) {
|
|
1525
|
+
this.pushNotification("warn", `[${name}] The agent did not print a .devcc.ts; see its logs`);
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
const scratchDir = join(session.rootDir, ".devcc");
|
|
1529
|
+
const proposedPath = join(scratchDir, "proposed.devcc.ts");
|
|
1530
|
+
mkdirSync(scratchDir, { recursive: true });
|
|
1531
|
+
writeFileSync(proposedPath, proposal, "utf8");
|
|
1532
|
+
const loaded = await loadConfigFile(proposedPath);
|
|
1533
|
+
const problems = configProblems(session.rootDir, loaded);
|
|
1534
|
+
const { config } = loaded;
|
|
1535
|
+
const current = session.project.configPath;
|
|
1536
|
+
const target = current && !current.endsWith(".json") ? current : join(session.rootDir, ".devcc.ts");
|
|
1537
|
+
const summary = [
|
|
1538
|
+
`${config.processes.length} process(es), ${config.commands.length} command(s), verify: ${config.verify.map((entry) => (typeof entry === "string" ? entry : entry.id)).join(", ") || "none"}.`,
|
|
1539
|
+
problems.length > 0 ? `${problems.length} issue(s): ${problems[0] ?? ""}` : "It validates cleanly.",
|
|
1540
|
+
`Review it first in ${tildify(proposedPath)}.`,
|
|
1541
|
+
].join(" ");
|
|
1542
|
+
const write = await this.askConfirm(`Write ${current ? "the updated" : "the proposed"} ${tildify(target)}?`, summary);
|
|
1543
|
+
if (!write) {
|
|
1544
|
+
this.pushNotification("info", `Kept the proposal at ${tildify(proposedPath)}`);
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
writeFileSync(target, proposal, "utf8");
|
|
1548
|
+
this.pushNotification("success", `Wrote ${tildify(target)}`);
|
|
1549
|
+
if (session === this.session)
|
|
1550
|
+
await this.reloadConfig();
|
|
1551
|
+
else
|
|
1552
|
+
this.pushNotification("info", `Switch to ${name} and reload its config to use it`);
|
|
1553
|
+
}
|
|
1554
|
+
/** Rebuild the active project's session so a changed config takes effect. */
|
|
1555
|
+
async reloadConfig() {
|
|
1556
|
+
const previous = this.session;
|
|
1557
|
+
const running = previous.processes.list().filter((entry) => isActive(entry.status));
|
|
1558
|
+
if (running.length > 0) {
|
|
1559
|
+
const confirmed = await this.askConfirm(`Reload the config and stop ${running.length} running process(es)?`, `${running.map((entry) => entry.name).join(", ")} will be stopped; start them again afterwards.`);
|
|
1560
|
+
if (!confirmed)
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
this.stopSessionBackground(previous);
|
|
1564
|
+
previous.verifyAbort?.abort();
|
|
1565
|
+
await previous.processes.stopAll();
|
|
1566
|
+
previous.wiring.dispose();
|
|
1567
|
+
try {
|
|
1568
|
+
const next = await this.createSession(previous.rootDir);
|
|
1569
|
+
this.sessions.set(next.rootDir, next);
|
|
1570
|
+
this.wireSession(next);
|
|
1571
|
+
this.activateSession(next);
|
|
1572
|
+
this.reportConfigIssues();
|
|
1573
|
+
this.pushNotification("success", `Reloaded ${next.project.configPath ? basename(next.project.configPath) : "config"}`);
|
|
1574
|
+
}
|
|
1575
|
+
catch (error) {
|
|
1576
|
+
this.pushNotification("error", `Could not reload the config: ${errorMessage(error)}`);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
// ---------------------------------------------------------------------
|
|
1457
1580
|
// Dependencies
|
|
1458
1581
|
// ---------------------------------------------------------------------
|
|
1459
1582
|
/** Update a single package, gated by a confirmation (it rewrites the lockfile). */
|