@tacuchi/agent-workflow-cli 21.10.1 → 21.11.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/dist/application/dev-bootstrap-dsn-service.js +45 -35
- package/dist/application/dev-bootstrap-dsn-service.js.map +1 -1
- package/dist/application/docs-canon-service.js +68 -0
- package/dist/application/docs-canon-service.js.map +1 -0
- package/dist/application/dsn-reader-service.js +53 -2
- package/dist/application/dsn-reader-service.js.map +1 -1
- package/dist/application/mcp-dbhub-launcher.js +193 -34
- package/dist/application/mcp-dbhub-launcher.js.map +1 -1
- package/dist/application/mcp-doctor-service.js +13 -4
- package/dist/application/mcp-doctor-service.js.map +1 -1
- package/dist/application/mcp-test-connection-service.js +5 -11
- package/dist/application/mcp-test-connection-service.js.map +1 -1
- package/dist/application/visibility-doctor-service.js +89 -49
- package/dist/application/visibility-doctor-service.js.map +1 -1
- package/dist/application/workspace-migrate/apply.js +57 -0
- package/dist/application/workspace-migrate/apply.js.map +1 -0
- package/dist/application/workspace-migrate/markers.js +177 -0
- package/dist/application/workspace-migrate/markers.js.map +1 -0
- package/dist/application/workspace-migrate/plan.js +171 -0
- package/dist/application/workspace-migrate/plan.js.map +1 -0
- package/dist/application/workspace-migrate/preview.js +111 -0
- package/dist/application/workspace-migrate/preview.js.map +1 -0
- package/dist/cli/commands/unknown-flags.js +51 -0
- package/dist/cli/commands/unknown-flags.js.map +1 -0
- package/dist/cli/commands/visibility.js +105 -16
- package/dist/cli/commands/visibility.js.map +1 -1
- package/dist/cli/commands/workspace-migrate.js +70 -0
- package/dist/cli/commands/workspace-migrate.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a hub with a legacy session series needs before it can be operated with
|
|
3
|
+
* the same commands as a new one — derived without writing a byte.
|
|
4
|
+
*
|
|
5
|
+
* Three things are broken in such a hub, and none of them announces itself:
|
|
6
|
+
* the project block wears markers of an older namespace and the CLI silently
|
|
7
|
+
* reads a second, empty one it appended itself; the sessions the record calls
|
|
8
|
+
* closed have no `.closed` sentinel on disk, so they show up as active forever;
|
|
9
|
+
* and the numbers of the legacy series live only in folder names, so they
|
|
10
|
+
* vanish from the record the day somebody archives the folders.
|
|
11
|
+
*
|
|
12
|
+
* This is a PUNCTUAL, explicit operation and not a reconciliation some other
|
|
13
|
+
* command performs on the side: it decides what to do by comparing two sources
|
|
14
|
+
* that may disagree, and a disagreement is answered by refusing to touch that
|
|
15
|
+
* session — never by picking the more convenient of the two.
|
|
16
|
+
*/
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { readHistoryRows } from "../history-table.js";
|
|
19
|
+
import { resolveWorkspaceRootFrom } from "../paths-service.js";
|
|
20
|
+
import { CLOSED_MARKER, buildSessionEntry, listSessionFolders, nextSessionCorrelative, parseSessionFolder, sessionNumericCode, sessionsSharingNumber, } from "../session-resolver.js";
|
|
21
|
+
import { planHubMarkers, readHubFiles, } from "./markers.js";
|
|
22
|
+
/** How many writes the plan holds. Zero means the workspace is already current. */
|
|
23
|
+
export function pendingChanges(plan) {
|
|
24
|
+
return plan.markers.length + plan.sentinels.length + plan.rows.length;
|
|
25
|
+
}
|
|
26
|
+
export async function planWorkspaceMigration(fs, paths) {
|
|
27
|
+
const workspace = await resolveWorkspaceRootFrom(fs, paths);
|
|
28
|
+
const markers = planMarkers(await readHubFiles(fs, workspace), paths.blockMarkers());
|
|
29
|
+
const recorded = await readRecord(fs, paths);
|
|
30
|
+
const sentinels = [];
|
|
31
|
+
const rows = [];
|
|
32
|
+
const conflicts = [...markers.conflicts];
|
|
33
|
+
const legacy = [];
|
|
34
|
+
for (const folder of await listSessionFolders(fs, paths.cwdSessionsDir())) {
|
|
35
|
+
const number = legacyNumber(folder.name);
|
|
36
|
+
if (number === null)
|
|
37
|
+
continue; // current-model folder: nothing legacy about it
|
|
38
|
+
legacy.push(folder.name);
|
|
39
|
+
const outcome = await planSession(fs, paths, folder, number, recorded.get(number));
|
|
40
|
+
if (outcome.kind === "sentinel")
|
|
41
|
+
sentinels.push(outcome.seed);
|
|
42
|
+
if (outcome.kind === "row")
|
|
43
|
+
rows.push(outcome.seed);
|
|
44
|
+
if (outcome.kind === "conflict")
|
|
45
|
+
conflicts.push(outcome.conflict);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
workspace,
|
|
49
|
+
markers: markers.rewrites,
|
|
50
|
+
sentinels,
|
|
51
|
+
rows,
|
|
52
|
+
conflicts,
|
|
53
|
+
legacy,
|
|
54
|
+
next_correlative: await nextSessionCorrelative(fs, paths),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function planMarkers(hubs, current) {
|
|
58
|
+
const rewrites = [];
|
|
59
|
+
const conflicts = [];
|
|
60
|
+
for (const hub of hubs) {
|
|
61
|
+
const outcome = planHubMarkers(hub.path, hub.text, current);
|
|
62
|
+
if (outcome.kind === "rewrite")
|
|
63
|
+
rewrites.push(outcome.rewrite);
|
|
64
|
+
if (outcome.kind === "refused") {
|
|
65
|
+
conflicts.push({
|
|
66
|
+
subject: hub.path,
|
|
67
|
+
reason: outcome.refusal.reason,
|
|
68
|
+
detail: outcome.refusal.detail,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { rewrites, conflicts };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* What one legacy session needs, given what the record says about its number.
|
|
76
|
+
*
|
|
77
|
+
* The rule that makes seeding a sentinel safe is the LAYOUT: a `sessionNNN-`
|
|
78
|
+
* folder predates the sentinel model entirely, so the file's absence there is
|
|
79
|
+
* the absence of the model and not a statement about the session. In a
|
|
80
|
+
* current-model folder that same absence MEANS active — `session-resume
|
|
81
|
+
* --reopen` produces exactly it, on purpose — and writing the sentinel back
|
|
82
|
+
* would re-close a session somebody had just reopened. That is why this walks
|
|
83
|
+
* the legacy series and nothing else.
|
|
84
|
+
*/
|
|
85
|
+
async function planSession(fs, paths, folder, number, row) {
|
|
86
|
+
// The record is indexed by number, so a number two folders answer to has ONE
|
|
87
|
+
// row for TWO sessions: whichever we wrote, we would be writing about the
|
|
88
|
+
// other one too.
|
|
89
|
+
const sharing = await sessionsSharingNumber(fs, paths, folder.name);
|
|
90
|
+
if (sharing.length > 1) {
|
|
91
|
+
const folders = sharing.map((candidate) => candidate.folder).join(", ");
|
|
92
|
+
return conflictOf(folder.name, "numero_compartido", `el número ${number} lo comparten ${sharing.length} carpetas (${folders}) y el registro se indexa por número: renombrá la legacy al modelo actual (\`NNN-<slug>\`) y reintentá`);
|
|
93
|
+
}
|
|
94
|
+
const entry = await buildSessionEntry(fs, folder.path, folder.name);
|
|
95
|
+
if (row === undefined) {
|
|
96
|
+
return {
|
|
97
|
+
kind: "row",
|
|
98
|
+
seed: {
|
|
99
|
+
folder: folder.name,
|
|
100
|
+
code: entry.code ?? folder.name,
|
|
101
|
+
name: entry.name,
|
|
102
|
+
state: entry.state,
|
|
103
|
+
date: entry.date ?? null,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const recorded = recordedState(row.state);
|
|
108
|
+
if (recorded === null) {
|
|
109
|
+
return conflictOf(folder.name, "estado_ilegible", `la fila del histórico dice '${row.state}', que no es ni 'active' ni 'closed': corregila a mano y reintentá`);
|
|
110
|
+
}
|
|
111
|
+
if (recorded === entry.state)
|
|
112
|
+
return { kind: "coherente" };
|
|
113
|
+
if (recorded === "active") {
|
|
114
|
+
return conflictOf(folder.name, "estado_divergente", "el histórico la da por activa y la carpeta ya tiene su centinela `.closed`: cuál de las dos quedó atrás no se adivina");
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
kind: "sentinel",
|
|
118
|
+
seed: { folder: folder.name, path: folder.path, date: row.date },
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function conflictOf(subject, reason, detail) {
|
|
122
|
+
return { kind: "conflict", conflict: { subject, reason, detail } };
|
|
123
|
+
}
|
|
124
|
+
/** Where the sentinel of a session goes. */
|
|
125
|
+
export function sentinelPath(seed) {
|
|
126
|
+
return join(seed.path, CLOSED_MARKER);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The record, indexed by NUMBER — the key it is actually written with.
|
|
130
|
+
*
|
|
131
|
+
* Compared as numbers and not as strings for the same reason the upsert does
|
|
132
|
+
* it: `47` and `047` are one session, and `100` is not `1000`.
|
|
133
|
+
*/
|
|
134
|
+
async function readRecord(fs, paths) {
|
|
135
|
+
const path = paths.cwdHistoryFile();
|
|
136
|
+
const byNumber = new Map();
|
|
137
|
+
if (!(await fs.exists(path)))
|
|
138
|
+
return byNumber;
|
|
139
|
+
for (const row of readHistoryRows(await fs.readText(path))) {
|
|
140
|
+
// The SAME reading of "what number does this carry" the resolver and the
|
|
141
|
+
// correlative use: `session047-x`, `047-x` and a bare `047` are one session.
|
|
142
|
+
const digits = sessionNumericCode(row.key);
|
|
143
|
+
if (digits !== null)
|
|
144
|
+
byNumber.set(Number.parseInt(digits, 10), row);
|
|
145
|
+
}
|
|
146
|
+
return byNumber;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The number a LEGACY folder carries, or `null` when the folder is not one.
|
|
150
|
+
*
|
|
151
|
+
* `parseSessionFolder` is the canonical reading of a folder's identity and it
|
|
152
|
+
* answers this without another regex: for the current model it hands back the
|
|
153
|
+
* WHOLE folder name as the code, and only the `sessionNNN-<slug>` layout splits
|
|
154
|
+
* a number off.
|
|
155
|
+
*/
|
|
156
|
+
function legacyNumber(folder) {
|
|
157
|
+
const { code } = parseSessionFolder(folder);
|
|
158
|
+
if (code === null || code === folder)
|
|
159
|
+
return null;
|
|
160
|
+
const parsed = Number.parseInt(code, 10);
|
|
161
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
162
|
+
}
|
|
163
|
+
function recordedState(cell) {
|
|
164
|
+
const value = cell.trim().toLowerCase();
|
|
165
|
+
if (value === "closed")
|
|
166
|
+
return "closed";
|
|
167
|
+
if (value === "active")
|
|
168
|
+
return "active";
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/application/workspace-migrate/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The projection of the plan a caller gets to see — and the same one, in prose,
|
|
3
|
+
* that a person reads before approving it.
|
|
4
|
+
*
|
|
5
|
+
* The rewritten bytes of each hub file stay OUT of it: the payload is what the
|
|
6
|
+
* migration will do, not the file it will produce, and a JSON consumer that had
|
|
7
|
+
* to diff two whole documents to learn "the markers get renamed" would be
|
|
8
|
+
* reading an implementation detail as if it were the answer.
|
|
9
|
+
*/
|
|
10
|
+
import { relpath } from "../paths.js";
|
|
11
|
+
import { pendingChanges } from "./plan.js";
|
|
12
|
+
export function migrationPreview(plan) {
|
|
13
|
+
return {
|
|
14
|
+
workspace: plan.workspace,
|
|
15
|
+
markers: plan.markers.map((hub) => ({
|
|
16
|
+
file: relpath(hub.path, plan.workspace),
|
|
17
|
+
from: hub.from,
|
|
18
|
+
to: hub.to,
|
|
19
|
+
drops_duplicate: hub.drops_duplicate,
|
|
20
|
+
})),
|
|
21
|
+
sentinels: plan.sentinels.map((seed) => ({ folder: seed.folder, date: seed.date })),
|
|
22
|
+
rows: plan.rows.map((seed) => ({
|
|
23
|
+
folder: seed.folder,
|
|
24
|
+
state: seed.state,
|
|
25
|
+
date: seed.date,
|
|
26
|
+
})),
|
|
27
|
+
conflicts: plan.conflicts.map((conflict) => ({
|
|
28
|
+
...conflict,
|
|
29
|
+
subject: relpath(conflict.subject, plan.workspace),
|
|
30
|
+
})),
|
|
31
|
+
legacy: plan.legacy,
|
|
32
|
+
next_correlative: plan.next_correlative,
|
|
33
|
+
pending: pendingChanges(plan),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function renderMigrationPreview(preview) {
|
|
37
|
+
const lines = [
|
|
38
|
+
`Workspace: ${preview.workspace}`,
|
|
39
|
+
`Serie legacy: ${countOf(preview.legacy.length, "carpeta", "carpetas")} · próximo correlativo: ${preview.next_correlative}`,
|
|
40
|
+
];
|
|
41
|
+
if (preview.markers.length > 0) {
|
|
42
|
+
lines.push("", "Marcadores del bloque de proyecto:");
|
|
43
|
+
for (const marker of preview.markers) {
|
|
44
|
+
const duplicate = marker.drops_duplicate
|
|
45
|
+
? " (y elimina el bloque vacío que el CLI había agregado aparte)"
|
|
46
|
+
: "";
|
|
47
|
+
lines.push(` ${marker.file} — ${marker.from} → ${marker.to}${duplicate}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (preview.sentinels.length > 0) {
|
|
51
|
+
lines.push("", "Centinelas de cierre a sembrar, con la fecha del histórico:");
|
|
52
|
+
for (const sentinel of preview.sentinels) {
|
|
53
|
+
lines.push(` ${sentinel.folder} — cerrada el ${sentinel.date || "(fila sin fecha)"}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (preview.rows.length > 0) {
|
|
57
|
+
lines.push("", "Filas a reservar en el histórico, para que el número no se reasigne:");
|
|
58
|
+
for (const row of preview.rows) {
|
|
59
|
+
lines.push(` ${row.folder} — ${row.state}, ${dateNote(row.date)}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (preview.pending === 0) {
|
|
63
|
+
lines.push("", "Nada que migrar: el workspace ya opera con el modelo actual.");
|
|
64
|
+
}
|
|
65
|
+
lines.push(...conflictLines(preview.conflicts));
|
|
66
|
+
if (preview.pending > 0) {
|
|
67
|
+
lines.push("", "Para aplicarlo:", " aw workspace-migrate --apply");
|
|
68
|
+
}
|
|
69
|
+
return lines.join("\n");
|
|
70
|
+
}
|
|
71
|
+
export function renderMigrationApplied(applied) {
|
|
72
|
+
const lines = [`Workspace migrado: ${applied.workspace}`];
|
|
73
|
+
if (applied.markers_renamed.length > 0) {
|
|
74
|
+
const files = applied.markers_renamed.map((path) => relpath(path, applied.workspace));
|
|
75
|
+
lines.push(`Marcadores renombrados: ${files.join(", ")}`);
|
|
76
|
+
}
|
|
77
|
+
if (applied.duplicates_dropped.length > 0) {
|
|
78
|
+
const files = applied.duplicates_dropped.map((path) => relpath(path, applied.workspace));
|
|
79
|
+
lines.push(`Bloques duplicados eliminados: ${files.join(", ")}`);
|
|
80
|
+
}
|
|
81
|
+
if (applied.sentinels_seeded.length > 0) {
|
|
82
|
+
lines.push(`Centinelas sembrados: ${applied.sentinels_seeded.join(", ")}`);
|
|
83
|
+
}
|
|
84
|
+
if (applied.rows_seeded.length > 0) {
|
|
85
|
+
lines.push(`Filas reservadas: ${applied.rows_seeded.join(", ")}`);
|
|
86
|
+
}
|
|
87
|
+
if (applied.rows_dated_today.length > 0) {
|
|
88
|
+
lines.push(`Sin fecha declarada — su fila nació con la de hoy: ${applied.rows_dated_today.join(", ")}`);
|
|
89
|
+
}
|
|
90
|
+
if (lines.length === 1)
|
|
91
|
+
lines.push("No había nada que migrar.");
|
|
92
|
+
lines.push(`Próximo correlativo: ${applied.next_correlative}`);
|
|
93
|
+
lines.push(...conflictLines(applied.conflicts));
|
|
94
|
+
return lines.join("\n");
|
|
95
|
+
}
|
|
96
|
+
function conflictLines(conflicts) {
|
|
97
|
+
if (conflicts.length === 0)
|
|
98
|
+
return [];
|
|
99
|
+
const lines = ["", "Sin tocar, porque el histórico y el disco no dicen lo mismo:"];
|
|
100
|
+
for (const conflict of conflicts) {
|
|
101
|
+
lines.push(` ${conflict.subject} [${conflict.reason}] — ${conflict.detail}`);
|
|
102
|
+
}
|
|
103
|
+
return lines;
|
|
104
|
+
}
|
|
105
|
+
function dateNote(date) {
|
|
106
|
+
return date === null ? "sin fecha declarada: la fila nace con la de hoy" : date;
|
|
107
|
+
}
|
|
108
|
+
function countOf(total, singular, plural) {
|
|
109
|
+
return `${total} ${total === 1 ? singular : plural}`;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/application/workspace-migrate/preview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flags every command tolerates because the RUNTIME reads them, not the
|
|
3
|
+
* command: namespace resolution, output projection and help. `-h` never gets
|
|
4
|
+
* this far (main.ts prints help before dispatching) and is listed anyway, so
|
|
5
|
+
* the set answers for itself instead of relying on the caller's order.
|
|
6
|
+
*/
|
|
7
|
+
const RUNTIME_FLAGS = new Set([
|
|
8
|
+
"namespace",
|
|
9
|
+
"format",
|
|
10
|
+
"json",
|
|
11
|
+
"detail",
|
|
12
|
+
"help",
|
|
13
|
+
"version",
|
|
14
|
+
"h",
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Every flag the invocation carried, whichever map the parser routed it to.
|
|
18
|
+
*
|
|
19
|
+
* A flag with a value lands in `values` (or `valuesMulti`), a bare one in
|
|
20
|
+
* `flags` as `--name`; reading only one of the three is how an unknown flag
|
|
21
|
+
* stays invisible depending on whether the caller gave it a value.
|
|
22
|
+
*/
|
|
23
|
+
function passedFlags(args) {
|
|
24
|
+
const names = new Set();
|
|
25
|
+
for (const name of args.values.keys())
|
|
26
|
+
names.add(name);
|
|
27
|
+
for (const name of args.valuesMulti.keys())
|
|
28
|
+
names.add(name);
|
|
29
|
+
for (const token of args.flags)
|
|
30
|
+
names.add(token.replace(/^--?/, ""));
|
|
31
|
+
return [...names];
|
|
32
|
+
}
|
|
33
|
+
export function reviewFlags(args, contract) {
|
|
34
|
+
const known = new Set(contract.known);
|
|
35
|
+
const retired = new Set(contract.retired ?? []);
|
|
36
|
+
const review = { unknown: [], retired: [] };
|
|
37
|
+
for (const name of passedFlags(args)) {
|
|
38
|
+
if (known.has(name) || RUNTIME_FLAGS.has(name))
|
|
39
|
+
continue;
|
|
40
|
+
(retired.has(name) ? review.retired : review.unknown).push(`--${name}`);
|
|
41
|
+
}
|
|
42
|
+
review.unknown.sort();
|
|
43
|
+
review.retired.sort();
|
|
44
|
+
return review;
|
|
45
|
+
}
|
|
46
|
+
/** The refusal message, naming what the command does accept. */
|
|
47
|
+
export function unknownFlagMessage(review, contract) {
|
|
48
|
+
const accepted = [...contract.known].sort().map((name) => `--${name}`);
|
|
49
|
+
return `${review.unknown.join(", ")} no ${review.unknown.length === 1 ? "es un flag" : "son flags"} de este comando; acepta ${accepted.join(", ")}`;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=unknown-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-flags.js","sourceRoot":"","sources":["../../../src/cli/commands/unknown-flags.ts"],"names":[],"mappings":"AA0BA;;;;;GAKG;AACH,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC;IACjD,WAAW;IACX,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,MAAM;IACN,SAAS;IACT,GAAG;CACJ,CAAC,CAAC;AASH;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,IAAgB;IACnC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAgB,EAAE,QAAsB;IAClE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,MAAM,GAAe,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACxD,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACzD,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACtB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACtB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,MAAkB,EAAE,QAAsB;IAC3E,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACvE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,4BAA4B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACtJ,CAAC"}
|
|
@@ -1,14 +1,26 @@
|
|
|
1
|
-
import { runVisibilityDoctor } from "../../application/visibility-doctor-service.js";
|
|
1
|
+
import { runVisibilityDoctor, } from "../../application/visibility-doctor-service.js";
|
|
2
2
|
import { fail } from "../render.js";
|
|
3
3
|
export const visibilityCommand = {
|
|
4
4
|
name: "visibility",
|
|
5
|
-
describe: "Inspector de visibilidad multi-root del hub. Subcomandos: doctor [--workspace dir] [--global]
|
|
5
|
+
describe: "Inspector de visibilidad multi-root del hub. Subcomandos: doctor [--workspace dir] [--global] " +
|
|
6
|
+
"[--format human|json] [--detail].",
|
|
6
7
|
async execute(args, ctx) {
|
|
7
8
|
const subcommand = args.rest[0];
|
|
8
9
|
if (subcommand === "doctor")
|
|
9
10
|
return runDoctorSub(args, ctx);
|
|
10
11
|
return fail("INVALID_INPUT", "visibility requiere subcomando: doctor");
|
|
11
12
|
},
|
|
13
|
+
/**
|
|
14
|
+
* The human projection of the SAME result the JSON carries: one line per host
|
|
15
|
+
* with its verdict and the file(s) the verdict was read from, plus the paths
|
|
16
|
+
* that are missing or left over. It re-derives nothing.
|
|
17
|
+
*/
|
|
18
|
+
renderHuman(result, context) {
|
|
19
|
+
const data = result.data;
|
|
20
|
+
if (data === undefined)
|
|
21
|
+
return "";
|
|
22
|
+
return renderDoctor(data, context.detail);
|
|
23
|
+
},
|
|
12
24
|
};
|
|
13
25
|
async function runDoctorSub(args, ctx) {
|
|
14
26
|
const workspace = args.values.get("workspace");
|
|
@@ -18,19 +30,96 @@ async function runDoctorSub(args, ctx) {
|
|
|
18
30
|
});
|
|
19
31
|
const totalReports = data.reports.length + data.global_reports.length;
|
|
20
32
|
const okCount = data.summary.ok;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
if (okCount === totalReports)
|
|
34
|
+
return { ok: true, data, exitCode: 0 };
|
|
35
|
+
// Drift stays `ok:false` (exit 1 is the contract scripts already gate on), and
|
|
36
|
+
// the host renders `ok:false` ONLY through the failure projection — so the
|
|
37
|
+
// report travels in `action`, or `--format human` would print a bare count in
|
|
38
|
+
// exactly the case the person needs the per-host diagnosis.
|
|
39
|
+
return fail("VISIBILITY_DRIFT", `${totalReports - okCount}/${totalReports} reports con drift (ver data.reports/global_reports)`, {
|
|
40
|
+
...data,
|
|
41
|
+
// `--detail` is read HERE and not in the renderer because the failure
|
|
42
|
+
// projection never reaches `renderHuman` — and detail is precisely what
|
|
43
|
+
// the person asked for in the only case that prints this text.
|
|
44
|
+
action: `revisá el drift host por host:\n\n${renderDoctor(data, args.flags.has("--detail"))}`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const STATUS_MARK = {
|
|
48
|
+
ok: "✓",
|
|
49
|
+
"missing-paths": "✗",
|
|
50
|
+
"extra-paths": "✗",
|
|
51
|
+
"no-settings": "✗",
|
|
52
|
+
"no-project-block": "✗",
|
|
53
|
+
"global-pollution": "✗",
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Statuses whose `detail` only restates the line it would sit under: `ok` is the
|
|
57
|
+
* line itself, and missing/extra already print the paths one by one. Every other
|
|
58
|
+
* status prints no list, so its `detail` is the only thing that explains it.
|
|
59
|
+
*/
|
|
60
|
+
const REDUNDANT_DETAIL = new Set([
|
|
61
|
+
"ok",
|
|
62
|
+
"missing-paths",
|
|
63
|
+
"extra-paths",
|
|
64
|
+
]);
|
|
65
|
+
const STATUS_WIDTH = Math.max(...Object.keys(STATUS_MARK).map((s) => s.length));
|
|
66
|
+
function renderDoctor(data, detail) {
|
|
67
|
+
const lines = [`Visibilidad multi-root · ${data.workspace_dir}`, ""];
|
|
68
|
+
lines.push(...renderScope("workspace", data.reports, detail));
|
|
69
|
+
if (data.global_reports.length > 0) {
|
|
70
|
+
lines.push("", ...renderScope("global", data.global_reports, detail));
|
|
71
|
+
}
|
|
72
|
+
const total = data.reports.length + data.global_reports.length;
|
|
73
|
+
lines.push("", `${data.summary.ok}/${total} host(s) sin drift`);
|
|
74
|
+
lines.push(...renderFixes([...data.reports, ...data.global_reports]));
|
|
75
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
76
|
+
}
|
|
77
|
+
function renderScope(title, reports, detail) {
|
|
78
|
+
if (reports.length === 0)
|
|
79
|
+
return [];
|
|
80
|
+
const hostWidth = Math.max(...reports.map((r) => r.host.length));
|
|
81
|
+
const lines = [title];
|
|
82
|
+
for (const report of reports) {
|
|
83
|
+
const head = `${report.host.padEnd(hostWidth)} ${report.status.padEnd(STATUS_WIDTH)}`;
|
|
84
|
+
// The file(s) the verdict was actually read from — never a hardcoded name.
|
|
85
|
+
lines.push(` ${STATUS_MARK[report.status]} ${head} ${report.targets.join(" + ")}`);
|
|
86
|
+
if (report.missing.length > 0)
|
|
87
|
+
lines.push(` faltan: ${report.missing.join(", ")}`);
|
|
88
|
+
if (report.extra.length > 0)
|
|
89
|
+
lines.push(` sobran: ${report.extra.join(", ")}`);
|
|
90
|
+
if (report.detail !== undefined && (detail || !REDUNDANT_DETAIL.has(report.status))) {
|
|
91
|
+
lines.push(` ${report.detail}`);
|
|
92
|
+
}
|
|
93
|
+
if (detail && report.declared_paths.length > 0) {
|
|
94
|
+
lines.push(` declarados: ${report.declared_paths.join(", ")}`);
|
|
95
|
+
lines.push(` registrados: ${report.registered_paths.join(", ") || "(ninguno)"}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return lines;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* One command per kind of drift present — never advice for drift nobody has.
|
|
102
|
+
*
|
|
103
|
+
* The trigger is the LIST, not the status: `status` reports only the most severe
|
|
104
|
+
* drift, so a host with paths missing AND left over would otherwise print
|
|
105
|
+
* `sobran:` above and no command to remove them.
|
|
106
|
+
*/
|
|
107
|
+
function renderFixes(reports) {
|
|
108
|
+
const fixes = [];
|
|
109
|
+
if (reports.some((r) => r.missing.length > 0)) {
|
|
110
|
+
fixes.push(" aw attach-multiroot --from-sources registra las fuentes que faltan");
|
|
111
|
+
}
|
|
112
|
+
// Global leftovers are the hub's own sources leaking into ~/: a different
|
|
113
|
+
// command, and `--path` on the workspace scope would not touch them.
|
|
114
|
+
if (reports.some((r) => r.scope === "workspace" && r.extra.length > 0)) {
|
|
115
|
+
fixes.push(" aw detach-multiroot --path <dir> quita las rutas que sobran");
|
|
116
|
+
}
|
|
117
|
+
if (reports.some((r) => r.status === "global-pollution")) {
|
|
118
|
+
fixes.push(" aw detach-multiroot --global --from-sources limpia el scope global");
|
|
119
|
+
}
|
|
120
|
+
if (reports.some((r) => r.status === "no-project-block")) {
|
|
121
|
+
fixes.push(" aw workspace-init --source <alias>:<path> declara las fuentes del workspace");
|
|
122
|
+
}
|
|
123
|
+
return fixes.length === 0 ? [] : ["", "Para corregir:", ...fixes];
|
|
35
124
|
}
|
|
36
125
|
//# sourceMappingURL=visibility.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visibility.js","sourceRoot":"","sources":["../../../src/cli/commands/visibility.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"visibility.js","sourceRoot":"","sources":["../../../src/cli/commands/visibility.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aw workspace-migrate`: bring a hub that carries a legacy session series up to
|
|
3
|
+
* the model the rest of the CLI operates.
|
|
4
|
+
*
|
|
5
|
+
* Read-only by default and explicit by design. It is a PUNCTUAL operation, not
|
|
6
|
+
* a reconciliation another command performs on the side: it decides by
|
|
7
|
+
* comparing the durable record against the disk, the two can disagree, and a
|
|
8
|
+
* disagreement is answered by leaving that session exactly as it was and saying
|
|
9
|
+
* so. Nothing is written until somebody types `--apply`, and what gets written
|
|
10
|
+
* is re-derived under the workspace lock at that moment.
|
|
11
|
+
*/
|
|
12
|
+
import { applyWorkspaceMigration, } from "../../application/workspace-migrate/apply.js";
|
|
13
|
+
import { planWorkspaceMigration } from "../../application/workspace-migrate/plan.js";
|
|
14
|
+
import { migrationPreview, renderMigrationApplied, renderMigrationPreview, } from "../../application/workspace-migrate/preview.js";
|
|
15
|
+
import { failSemantic } from "../render.js";
|
|
16
|
+
import { reviewFlags, unknownFlagMessage } from "./unknown-flags.js";
|
|
17
|
+
// A command born today has no caller that ever passed it a flag of more, so
|
|
18
|
+
// there is nothing to break by refusing one — which is why the rejection can be
|
|
19
|
+
// total here and had to be scoped elsewhere.
|
|
20
|
+
const FLAGS = { known: ["apply"] };
|
|
21
|
+
export const workspaceMigrateCommand = {
|
|
22
|
+
name: "workspace-migrate",
|
|
23
|
+
describe: "Pone al día un workspace con serie legacy: renombra los marcadores del bloque de proyecto al namespace vigente, " +
|
|
24
|
+
"siembra los centinelas de cierre que el histórico ya declara y reserva los números legacy en el registro durable. " +
|
|
25
|
+
"Sin --apply no escribe nada: muestra qué va a pasar. Una sesión sobre la que el histórico y el disco se contradicen " +
|
|
26
|
+
"queda intacta y se reporta. Usage: aw workspace-migrate [--apply].",
|
|
27
|
+
async execute(args, ctx) {
|
|
28
|
+
const review = reviewFlags(args, FLAGS);
|
|
29
|
+
if (review.unknown.length > 0) {
|
|
30
|
+
return failSemantic({
|
|
31
|
+
code: "UNKNOWN_FLAG",
|
|
32
|
+
message: unknownFlagMessage(review, FLAGS),
|
|
33
|
+
action: "corregí el flag y reintentá: `aw workspace-migrate [--apply]`",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (!args.flags.has("--apply")) {
|
|
37
|
+
const plan = await planWorkspaceMigration(ctx.fs, ctx.paths);
|
|
38
|
+
return {
|
|
39
|
+
ok: true,
|
|
40
|
+
data: {
|
|
41
|
+
action: "preview",
|
|
42
|
+
...migrationPreview(plan),
|
|
43
|
+
next: "aw workspace-migrate --apply",
|
|
44
|
+
},
|
|
45
|
+
exitCode: 0,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const applied = await applyWorkspaceMigration(ctx.fs, ctx.paths);
|
|
49
|
+
if ("error" in applied) {
|
|
50
|
+
return failSemantic({
|
|
51
|
+
code: "LOCK_BUSY",
|
|
52
|
+
message: applied.error,
|
|
53
|
+
action: "esperá a que termine la operación en curso y reintentá",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return { ok: true, data: { action: "apply", ...applied }, exitCode: 0 };
|
|
57
|
+
},
|
|
58
|
+
renderHuman(result, context) {
|
|
59
|
+
if (!result.ok || result.data === undefined)
|
|
60
|
+
return "";
|
|
61
|
+
const data = result.data;
|
|
62
|
+
const lines = data.action === "apply" ? [renderMigrationApplied(data)] : [renderMigrationPreview(data)];
|
|
63
|
+
if (context.detail && data.action === "preview") {
|
|
64
|
+
lines.push("", `Serie legacy: ${data.legacy.join(", ") || "(ninguna)"}`);
|
|
65
|
+
}
|
|
66
|
+
// The writer emits this verbatim, so the trailing newline belongs here.
|
|
67
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=workspace-migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-migrate.js","sourceRoot":"","sources":["../../../src/cli/commands/workspace-migrate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tacuchi/agent-workflow-cli",
|
|
3
|
-
"version": "21.
|
|
3
|
+
"version": "21.11.0",
|
|
4
4
|
"description": "Runtime CLI for Workline — the stages + loops + artifacts system for agent work. Bundles the universal `w` skill set under `skills/w/` (slash commands `/w:*`: spec-new/spec-refine, plan-new/plan-exec, quick, persist, workspace-init, export-*); `self install --target <host>` copies SKILL + commands + hooks into the host. Pluggable capability skills via `.workflow/skills.toml`. Multi-empresa parametrization via `profile.json` cascade. Namespace auto-detected from any `.<ns>/sessions/` dir in CWD; default `workflow`.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|