@basou/core 0.30.0 → 0.32.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/index.d.ts +398 -105
- package/dist/index.js +248 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schemas/approval.schema.json +3 -2
- package/schemas/event.schema.json +21 -21
- package/schemas/manifest.schema.json +2 -12
- package/schemas/session-import.schema.json +25 -23
- package/schemas/session.schema.json +13 -7
- package/schemas/status.schema.json +1 -1
- package/schemas/task.schema.json +5 -3
package/dist/index.js
CHANGED
|
@@ -910,7 +910,10 @@ import { z as z2 } from "zod";
|
|
|
910
910
|
|
|
911
911
|
// src/schemas/shared.schema.ts
|
|
912
912
|
import { z } from "zod";
|
|
913
|
-
var SchemaVersionSchema = z.
|
|
913
|
+
var SchemaVersionSchema = z.string().regex(/^0\.\d+\.\d+$/, {
|
|
914
|
+
message: "unsupported .basou format version: this basou reads format major 0 (0.x.y). If this workspace was written by a newer basou, upgrade basou to open it."
|
|
915
|
+
});
|
|
916
|
+
var CacheVersionSchema = z.literal("0.1.0");
|
|
914
917
|
var IsoTimestampSchema = z.string().datetime({ offset: true });
|
|
915
918
|
var createPrefixedIdSchema = (prefix) => {
|
|
916
919
|
const refiner = (value) => isValidPrefixedId(value) && value.startsWith(`${prefix}_`);
|
|
@@ -930,14 +933,14 @@ var EventSourceSchema = z.string().min(1);
|
|
|
930
933
|
|
|
931
934
|
// src/schemas/approval.schema.ts
|
|
932
935
|
var ApprovalStatusSchema = z2.enum(["pending", "approved", "rejected", "expired"]);
|
|
933
|
-
var ApprovalSchema = z2.
|
|
936
|
+
var ApprovalSchema = z2.looseObject({
|
|
934
937
|
schema_version: SchemaVersionSchema,
|
|
935
938
|
id: ApprovalIdSchema,
|
|
936
939
|
session_id: SessionIdSchema,
|
|
937
940
|
created_at: IsoTimestampSchema,
|
|
938
941
|
status: ApprovalStatusSchema,
|
|
939
942
|
risk_level: RiskLevelSchema,
|
|
940
|
-
action: z2.
|
|
943
|
+
action: z2.looseObject({ kind: z2.string() }).passthrough(),
|
|
941
944
|
reason: z2.string(),
|
|
942
945
|
expires_at: IsoTimestampSchema.nullable().default(null),
|
|
943
946
|
// The four fields below are null while `status === "pending"` and set
|
|
@@ -1590,7 +1593,7 @@ var SessionSourceKindSchema = z4.enum([
|
|
|
1590
1593
|
"import",
|
|
1591
1594
|
"terminal"
|
|
1592
1595
|
]);
|
|
1593
|
-
var SessionSourceSchema = z4.
|
|
1596
|
+
var SessionSourceSchema = z4.looseObject({
|
|
1594
1597
|
kind: SessionSourceKindSchema,
|
|
1595
1598
|
version: z4.literal("0.1.0"),
|
|
1596
1599
|
// Optional id of the originating session in the SOURCE tool's own
|
|
@@ -1606,20 +1609,20 @@ var SessionSourceSchema = z4.object({
|
|
|
1606
1609
|
// fresh import or `--force`).
|
|
1607
1610
|
source_size_bytes: z4.number().int().nonnegative().optional()
|
|
1608
1611
|
});
|
|
1609
|
-
var InvocationSchema = z4.
|
|
1612
|
+
var InvocationSchema = z4.looseObject({
|
|
1610
1613
|
command: z4.string().min(1),
|
|
1611
1614
|
args: z4.array(z4.string()).default([]),
|
|
1612
1615
|
// Nullable to record signal-terminated runs where the child has no exit
|
|
1613
1616
|
// code; the same nullability is mirrored in CommandExecutedEventSchema.
|
|
1614
1617
|
exit_code: z4.number().int().nullable()
|
|
1615
1618
|
});
|
|
1616
|
-
var SessionMetricsSchema = z4.
|
|
1619
|
+
var SessionMetricsSchema = z4.looseObject({
|
|
1617
1620
|
output_tokens: z4.number().int().nonnegative().optional(),
|
|
1618
1621
|
input_tokens: z4.number().int().nonnegative().optional(),
|
|
1619
1622
|
cached_input_tokens: z4.number().int().nonnegative().optional(),
|
|
1620
1623
|
reasoning_output_tokens: z4.number().int().nonnegative().optional(),
|
|
1621
1624
|
active_time_ms: z4.number().int().nonnegative().optional(),
|
|
1622
|
-
active_intervals: z4.array(z4.
|
|
1625
|
+
active_intervals: z4.array(z4.looseObject({ start: IsoTimestampSchema, end: IsoTimestampSchema })).optional(),
|
|
1623
1626
|
active_gap_cap_ms: z4.number().int().nonnegative().optional(),
|
|
1624
1627
|
active_time_method: z4.string().optional(),
|
|
1625
1628
|
machine_active_time_ms: z4.number().int().nonnegative().optional()
|
|
@@ -1628,7 +1631,7 @@ var SessionIntegritySchema = z4.object({
|
|
|
1628
1631
|
head_hash: z4.string(),
|
|
1629
1632
|
event_count: z4.number().int().nonnegative()
|
|
1630
1633
|
}).strict();
|
|
1631
|
-
var SessionInnerSchema = z4.
|
|
1634
|
+
var SessionInnerSchema = z4.looseObject({
|
|
1632
1635
|
id: SessionIdSchema,
|
|
1633
1636
|
label: z4.string().optional(),
|
|
1634
1637
|
task_id: TaskIdSchema.nullable().optional(),
|
|
@@ -1646,7 +1649,7 @@ var SessionInnerSchema = z4.object({
|
|
|
1646
1649
|
metrics: SessionMetricsSchema.optional(),
|
|
1647
1650
|
integrity: SessionIntegritySchema.optional()
|
|
1648
1651
|
});
|
|
1649
|
-
var SessionSchema = z4.
|
|
1652
|
+
var SessionSchema = z4.looseObject({
|
|
1650
1653
|
schema_version: SchemaVersionSchema,
|
|
1651
1654
|
session: SessionInnerSchema
|
|
1652
1655
|
});
|
|
@@ -2146,12 +2149,16 @@ import * as fsp from "fs/promises";
|
|
|
2146
2149
|
// src/schemas/status.schema.ts
|
|
2147
2150
|
import { z as z5 } from "zod";
|
|
2148
2151
|
var StatusSchema = z5.object({
|
|
2149
|
-
|
|
2152
|
+
// status.json is a rebuildable cache: exact-match-or-rebuild, not the
|
|
2153
|
+
// durable forward-compat gate.
|
|
2154
|
+
schema_version: CacheVersionSchema,
|
|
2150
2155
|
generated_at: IsoTimestampSchema,
|
|
2151
2156
|
workspace: z5.object({
|
|
2152
2157
|
id: WorkspaceIdSchema,
|
|
2153
2158
|
name: z5.string().min(1),
|
|
2154
|
-
basou_version
|
|
2159
|
+
// Mirrors the manifest's basou_version, so it uses the same
|
|
2160
|
+
// forward-compatible format gate (accept 0.x.y) rather than a literal.
|
|
2161
|
+
basou_version: SchemaVersionSchema
|
|
2155
2162
|
}).strict(),
|
|
2156
2163
|
directories_present: z5.object({
|
|
2157
2164
|
sessions: z5.boolean(),
|
|
@@ -2511,7 +2518,7 @@ import { z as z8 } from "zod";
|
|
|
2511
2518
|
// src/schemas/task.schema.ts
|
|
2512
2519
|
import { z as z6 } from "zod";
|
|
2513
2520
|
var TaskStatusSchema = z6.enum(["planned", "in_progress", "done", "cancelled"]);
|
|
2514
|
-
var TaskInnerSchema = z6.
|
|
2521
|
+
var TaskInnerSchema = z6.looseObject({
|
|
2515
2522
|
id: TaskIdSchema,
|
|
2516
2523
|
title: z6.string().min(1),
|
|
2517
2524
|
label: z6.string().min(1).optional(),
|
|
@@ -2540,7 +2547,7 @@ var TaskInnerSchema = z6.object({
|
|
|
2540
2547
|
*/
|
|
2541
2548
|
linked_sessions: z6.array(SessionIdSchema).default([])
|
|
2542
2549
|
});
|
|
2543
|
-
var TaskSchema = z6.
|
|
2550
|
+
var TaskSchema = z6.looseObject({
|
|
2544
2551
|
schema_version: SchemaVersionSchema,
|
|
2545
2552
|
task: TaskInnerSchema
|
|
2546
2553
|
});
|
|
@@ -2790,7 +2797,8 @@ var TaskIndexEntrySchema = z7.object({
|
|
|
2790
2797
|
updated_at: IsoTimestampSchema
|
|
2791
2798
|
}).strict();
|
|
2792
2799
|
var TaskIndexSchema = z7.object({
|
|
2793
|
-
|
|
2800
|
+
// Rebuildable cache: exact-match-or-rebuild, not the durable forward-compat gate.
|
|
2801
|
+
schema_version: CacheVersionSchema,
|
|
2794
2802
|
tasks: z7.array(TaskIndexEntrySchema),
|
|
2795
2803
|
last_rebuilt_at: IsoTimestampSchema
|
|
2796
2804
|
}).strict();
|
|
@@ -4728,8 +4736,7 @@ import { lstat as lstat3 } from "fs/promises";
|
|
|
4728
4736
|
import { z as z9 } from "zod";
|
|
4729
4737
|
var ProjectSchema = z9.looseObject({
|
|
4730
4738
|
name: z9.string().optional(),
|
|
4731
|
-
description: z9.string().optional()
|
|
4732
|
-
repository_url: z9.string().nullable().optional()
|
|
4739
|
+
description: z9.string().optional()
|
|
4733
4740
|
});
|
|
4734
4741
|
var CapabilitiesSchema = z9.looseObject({
|
|
4735
4742
|
enabled: z9.array(z9.string())
|
|
@@ -4787,7 +4794,11 @@ var WorkspaceMetaSchema = z9.looseObject({
|
|
|
4787
4794
|
});
|
|
4788
4795
|
var ManifestSchema = z9.looseObject({
|
|
4789
4796
|
schema_version: SchemaVersionSchema,
|
|
4790
|
-
|
|
4797
|
+
// Same forward-compatible format gate as schema_version (accept 0.x.y, gate a
|
|
4798
|
+
// higher major with an upgrade error) rather than a hard literal. `basou_version`
|
|
4799
|
+
// is a format stamp, not the npm/product version; consolidating it with
|
|
4800
|
+
// schema_version is a candidate cleanup for the M4 freeze pass.
|
|
4801
|
+
basou_version: SchemaVersionSchema,
|
|
4791
4802
|
workspace: WorkspaceMetaSchema,
|
|
4792
4803
|
project: ProjectSchema,
|
|
4793
4804
|
capabilities: CapabilitiesSchema,
|
|
@@ -4811,8 +4822,7 @@ function createManifest(input) {
|
|
|
4811
4822
|
const workspaceId = input.workspaceId ?? prefixedUlid("ws");
|
|
4812
4823
|
const project = {
|
|
4813
4824
|
...input.projectName !== void 0 ? { name: input.projectName } : {},
|
|
4814
|
-
...input.projectDescription !== void 0 ? { description: input.projectDescription } : {}
|
|
4815
|
-
...input.repositoryUrl !== void 0 ? { repository_url: input.repositoryUrl } : {}
|
|
4825
|
+
...input.projectDescription !== void 0 ? { description: input.projectDescription } : {}
|
|
4816
4826
|
};
|
|
4817
4827
|
const manifest = {
|
|
4818
4828
|
schema_version: "0.1.0",
|
|
@@ -4842,6 +4852,7 @@ function createManifest(input) {
|
|
|
4842
4852
|
async function writeManifest(paths, manifest, options) {
|
|
4843
4853
|
const force = options?.force === true;
|
|
4844
4854
|
const validated = ManifestSchema.parse(manifest);
|
|
4855
|
+
delete validated.project.repository_url;
|
|
4845
4856
|
if (!force) {
|
|
4846
4857
|
let existed = false;
|
|
4847
4858
|
try {
|
|
@@ -5470,6 +5481,65 @@ function shortId(id) {
|
|
|
5470
5481
|
return id.slice(0, sep + 1) + id.slice(sep + 1, sep + 1 + 10);
|
|
5471
5482
|
}
|
|
5472
5483
|
|
|
5484
|
+
// src/project/anchor-starter.ts
|
|
5485
|
+
function renderAnchorStarter(input) {
|
|
5486
|
+
const lines = [];
|
|
5487
|
+
const title = input.projectName ?? input.anchorName;
|
|
5488
|
+
lines.push(`# AGENTS.md (${input.anchorName})`);
|
|
5489
|
+
lines.push("");
|
|
5490
|
+
lines.push(
|
|
5491
|
+
`> \u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306F **${title} \u306E planning master(anchor)** \u3067\u3059\u3002\u3053\u3053\u3067\u4F5C\u696D\u3059\u308B AI \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306F\u3001\u307E\u305A\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u3093\u3067\u304F\u3060\u3055\u3044\u3002`
|
|
5492
|
+
);
|
|
5493
|
+
lines.push(">");
|
|
5494
|
+
lines.push(
|
|
5495
|
+
"> \u3053\u306E\u30D5\u30A1\u30A4\u30EB\u306F `basou project derive` \u304C greenfield \u7ACB\u3061\u4E0A\u3052\u6642\u306B **\u4E00\u5EA6\u3060\u3051\u751F\u6210\u3057\u305F starter** \u3067\u3059\u3002\u4EE5\u5F8C\u306F\u624B\u7BA1\u7406\u3057\u3066\u304F\u3060\u3055\u3044 \u2014 basou \u306F\u518D\u751F\u6210\u3082\u4E0A\u66F8\u304D\u3082\u3057\u307E\u305B\u3093(BASOU:GENERATED \u30DE\u30FC\u30AB\u30FC\u306F\u7121\u304F\u3001\u81EA\u7531\u306B\u7DE8\u96C6\u3067\u304D\u307E\u3059)\u3002"
|
|
5496
|
+
);
|
|
5497
|
+
lines.push("");
|
|
5498
|
+
lines.push("## \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u57FA\u672C\u60C5\u5831");
|
|
5499
|
+
lines.push("");
|
|
5500
|
+
lines.push("<!-- TODO: manifest \u304B\u3089\u306F\u5C0E\u51FA\u3067\u304D\u306A\u3044\u9805\u76EE\u3067\u3059\u3002\u57CB\u3081\u3066\u304F\u3060\u3055\u3044\u3002 -->");
|
|
5501
|
+
lines.push("");
|
|
5502
|
+
lines.push("```text");
|
|
5503
|
+
lines.push(`Product name: ${input.projectName ?? "<!-- TODO -->"}`);
|
|
5504
|
+
lines.push("Domain: <!-- TODO -->");
|
|
5505
|
+
lines.push("GitHub Organization: <!-- TODO -->");
|
|
5506
|
+
lines.push("Public repository: <!-- TODO -->");
|
|
5507
|
+
lines.push("Planning repository: <!-- TODO -->");
|
|
5508
|
+
lines.push("License: <!-- TODO -->");
|
|
5509
|
+
lines.push("```");
|
|
5510
|
+
lines.push("");
|
|
5511
|
+
lines.push("## \u3069\u3053\u3067 commit \u3059\u308B\u304B");
|
|
5512
|
+
lines.push("");
|
|
5513
|
+
lines.push("- **\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA(planning master)**: \u69CB\u60F3\u30FB\u8A08\u753B\u30FB\u8A2D\u8A08\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3002");
|
|
5514
|
+
lines.push("- **\u5404\u5B9F\u88C5 repo**: \u5B9F\u88C5\u30B3\u30FC\u30C9\u3002\u5FC5\u305A\u5BFE\u8C61 repo \u306B `cd` \u3057\u3066\u304B\u3089 commit \u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5515
|
+
lines.push("- **workspace view**: git \u7BA1\u7406\u5916\u3002view \u3067\u306F commit \u3067\u304D\u307E\u305B\u3093\u3002");
|
|
5516
|
+
lines.push("");
|
|
5517
|
+
lines.push("## \u5FC5\u305A\u8AAD\u3080\u3079\u304D\u898F\u7D04");
|
|
5518
|
+
lines.push("");
|
|
5519
|
+
lines.push("\u4F5C\u696D\u898F\u7D04\u306F\u5404 repo \u306E AGENTS.md \u306B\u3042\u308A\u307E\u3059\u3002\u4EE5\u4E0B\u3092\u8AAD\u3093\u3067\u304B\u3089\u4F5C\u696D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5520
|
+
lines.push("");
|
|
5521
|
+
for (const r of input.repos) {
|
|
5522
|
+
if (r.anchor === true) continue;
|
|
5523
|
+
lines.push(`- ${r.name}/AGENTS.md`);
|
|
5524
|
+
}
|
|
5525
|
+
if (input.viewName !== void 0) {
|
|
5526
|
+
lines.push(
|
|
5527
|
+
`- ${input.viewName}/AGENTS.md(workspace view\u30FBbasou \u304C\u751F\u6210)\u2014 **\u6700\u65B0\u306E repo \u69CB\u6210(roster)\u306F\u3053\u3053\u3092\u6B63\u3068\u3059\u308B**`
|
|
5528
|
+
);
|
|
5529
|
+
}
|
|
5530
|
+
lines.push("");
|
|
5531
|
+
lines.push("## \u4F5C\u696D\u65B9\u91DD(\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u56FA\u6709\u4E8B\u9805)");
|
|
5532
|
+
lines.push("");
|
|
5533
|
+
lines.push("<!-- TODO: \u4EE5\u4E0B\u3092\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u5408\u308F\u305B\u3066\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5534
|
+
lines.push(" - \u73FE\u5728\u306E\u30D5\u30A7\u30FC\u30BA / \u91CD\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8");
|
|
5535
|
+
lines.push(" - \u6A5F\u5BC6\u60C5\u5831\u306E\u6271\u3044(\u3069\u3053\u306B\u66F8\u304B\u306A\u3044\u304B)");
|
|
5536
|
+
lines.push(" - \u8A00\u8A9E\u30DD\u30EA\u30B7\u30FC(commit / \u30B3\u30E1\u30F3\u30C8 / \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u8A00\u8A9E)");
|
|
5537
|
+
lines.push(" - commit \u904B\u7528(\u6DF7\u5728\u30B3\u30DF\u30C3\u30C8\u3092\u907F\u3051\u308B \u7B49)");
|
|
5538
|
+
lines.push("-->");
|
|
5539
|
+
return `${lines.join("\n")}
|
|
5540
|
+
`;
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5473
5543
|
// src/project/relative-path.ts
|
|
5474
5544
|
function normalizeRelativePath(p) {
|
|
5475
5545
|
const trimmed = p.trim();
|
|
@@ -5646,10 +5716,69 @@ function renderPresetBlock(repo) {
|
|
|
5646
5716
|
}
|
|
5647
5717
|
return lines.join("\n");
|
|
5648
5718
|
}
|
|
5719
|
+
function visibilityShortLabel(v) {
|
|
5720
|
+
return v ?? "\u672A\u8A2D\u5B9A";
|
|
5721
|
+
}
|
|
5722
|
+
function languageShortLabel(l) {
|
|
5723
|
+
return l ?? "\u672A\u8A2D\u5B9A";
|
|
5724
|
+
}
|
|
5725
|
+
function instructionsLabel(repo) {
|
|
5726
|
+
if (repo.anchor === true) return "anchor(\u624B\u7BA1\u7406)";
|
|
5727
|
+
return repo.self === true ? "self(repo \u304C\u81EA\u5DF1\u7BA1\u7406)" : "hub(basou \u304C\u751F\u6210)";
|
|
5728
|
+
}
|
|
5729
|
+
function renderViewPresetBlock(input) {
|
|
5730
|
+
const lines = [];
|
|
5731
|
+
lines.push("## workspace view \u69CB\u6210(basou \u304C\u751F\u6210 \u2014 manifest \u304C\u6B63\u672C)");
|
|
5732
|
+
lines.push("");
|
|
5733
|
+
lines.push(
|
|
5734
|
+
"\u3053\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u306F `.basou/manifest.yaml` \u306E\u5BA3\u8A00\u304B\u3089 `basou project preset` \u304C\u751F\u6210\u3057\u307E\u3059\u3002\u7DE8\u96C6\u306F manifest \u5074\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044(\u30DE\u30FC\u30AB\u30FC\u5916\u306E\u8A18\u8FF0\u306F\u4FDD\u6301\u3055\u308C\u307E\u3059)\u3002"
|
|
5735
|
+
);
|
|
5736
|
+
lines.push(
|
|
5737
|
+
`\u3053\u306E AGENTS.md \u81EA\u8EAB\u3082 basou \u306E\u751F\u6210\u7269\u3067\u3059(\u5B9F\u4F53: \`agents/${input.viewName}/AGENTS.md\`\u3001\u30DE\u30FC\u30AB\u30FC\u5916\u306E\u8A18\u8FF0\u306F\u4FDD\u6301\u3055\u308C\u307E\u3059)\u3002`
|
|
5738
|
+
);
|
|
5739
|
+
lines.push("");
|
|
5740
|
+
lines.push(
|
|
5741
|
+
`\u3053\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u3001\u5BA3\u8A00\u3055\u308C\u305F ${input.repos.length} \u500B\u306E repo \u3092 symlink \u3067\u96C6\u7D04\u3059\u308B **view** \u3067\u3059\u3002\u5B9F\u4F53\u3092\u6301\u305F\u305A\u3001git \u7BA1\u7406\u5916\u3067\u3059\u3002`
|
|
5742
|
+
);
|
|
5743
|
+
lines.push("");
|
|
5744
|
+
lines.push("### \u96C6\u7D04\u3057\u3066\u3044\u308B repo");
|
|
5745
|
+
lines.push("");
|
|
5746
|
+
lines.push("| repo | \u53EF\u8996\u6027 | \u8A00\u8A9E | \u6307\u793A\u66F8 |");
|
|
5747
|
+
lines.push("|---|---|---|---|");
|
|
5748
|
+
for (const r of input.repos) {
|
|
5749
|
+
lines.push(
|
|
5750
|
+
`| ${r.name} | ${visibilityShortLabel(r.visibility)} | ${languageShortLabel(r.language)} | ${instructionsLabel(r)} |`
|
|
5751
|
+
);
|
|
5752
|
+
}
|
|
5753
|
+
lines.push("");
|
|
5754
|
+
lines.push("### \u3069\u3053\u3067 commit \u3059\u308B\u304B");
|
|
5755
|
+
lines.push("");
|
|
5756
|
+
lines.push(
|
|
5757
|
+
"view \u3067\u306F commit \u3067\u304D\u307E\u305B\u3093(git \u7BA1\u7406\u5916)\u3002\u5909\u66F4\u306F\u5FC5\u305A\u5B9F\u4F53\u306E repo \u306B `cd` \u3057\u3066\u304B\u3089 commit \u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
5758
|
+
);
|
|
5759
|
+
lines.push("");
|
|
5760
|
+
for (const r of input.repos) {
|
|
5761
|
+
lines.push(`- ${r.name} \u2192 \`cd ${r.name}\``);
|
|
5762
|
+
}
|
|
5763
|
+
lines.push("");
|
|
5764
|
+
lines.push("### \u5FC5\u305A\u8AAD\u3080\u3079\u304D\u898F\u7D04");
|
|
5765
|
+
lines.push("");
|
|
5766
|
+
lines.push("\u4F5C\u696D\u898F\u7D04\u306F\u5404 repo \u306E AGENTS.md \u306B\u3042\u308A\u307E\u3059\u3002\u4EE5\u4E0B\u3092\u8AAD\u3093\u3067\u304B\u3089\u4F5C\u696D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5767
|
+
lines.push("");
|
|
5768
|
+
for (const r of input.repos) {
|
|
5769
|
+
lines.push(`- ${r.name}/AGENTS.md`);
|
|
5770
|
+
}
|
|
5771
|
+
lines.push("");
|
|
5772
|
+
lines.push("### \u91CD\u8981\u539F\u5247");
|
|
5773
|
+
lines.push("");
|
|
5774
|
+
lines.push("- \u3053\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u72B6\u614B\u3092\u6301\u305F\u306A\u3044(git \u7BA1\u7406\u5916)");
|
|
5775
|
+
lines.push("- \u91CD\u8981\u306A\u30D5\u30A1\u30A4\u30EB\u3092\u3053\u3053\u306B\u76F4\u63A5\u7F6E\u304B\u306A\u3044(\u5B9F\u4F53\u306F\u5404 repo \u306B\u7F6E\u304F)");
|
|
5776
|
+
return lines.join("\n");
|
|
5777
|
+
}
|
|
5649
5778
|
function normalizeBlock(s) {
|
|
5650
5779
|
return s.replace(/\r\n/g, "\n").replace(/\n+$/, "");
|
|
5651
5780
|
}
|
|
5652
|
-
function summarizePresetPlan(facts) {
|
|
5781
|
+
function summarizePresetPlan(facts, opts) {
|
|
5653
5782
|
const deduped = [];
|
|
5654
5783
|
const seenPath = /* @__PURE__ */ new Set();
|
|
5655
5784
|
for (const f of facts) {
|
|
@@ -5669,8 +5798,9 @@ function summarizePresetPlan(facts) {
|
|
|
5669
5798
|
const collisions = [];
|
|
5670
5799
|
const collidingPaths = /* @__PURE__ */ new Set();
|
|
5671
5800
|
for (const [canonicalName, repos] of byCanonical) {
|
|
5672
|
-
|
|
5673
|
-
|
|
5801
|
+
const viewCollision = opts?.viewCanonicalName !== void 0 && canonicalName === opts.viewCanonicalName;
|
|
5802
|
+
if (repos.length > 1 || viewCollision) {
|
|
5803
|
+
collisions.push({ canonicalName, repos, ...viewCollision ? { view: true } : {} });
|
|
5674
5804
|
for (const r of repos) collidingPaths.add(r);
|
|
5675
5805
|
}
|
|
5676
5806
|
}
|
|
@@ -5835,6 +5965,8 @@ function classifyRetrofit(facts) {
|
|
|
5835
5965
|
if (facts.agentsState === "symlink")
|
|
5836
5966
|
return { ...base, action: "skip", reason: "already-symlink" };
|
|
5837
5967
|
if (facts.agentsState === "absent") return { ...base, action: "skip", reason: "absent" };
|
|
5968
|
+
if (facts.viewCanonicalName !== void 0 && facts.canonicalName === facts.viewCanonicalName)
|
|
5969
|
+
return { ...base, action: "refuse", reason: "view-collision" };
|
|
5838
5970
|
if (facts.canonicalExists) return { ...base, action: "refuse", reason: "canonical-exists" };
|
|
5839
5971
|
return {
|
|
5840
5972
|
...base,
|
|
@@ -5931,7 +6063,7 @@ function summarizeSymlinkPlan(facts) {
|
|
|
5931
6063
|
const selfAgentsMissing = [];
|
|
5932
6064
|
const unreachable = [];
|
|
5933
6065
|
for (const f of deduped) {
|
|
5934
|
-
if (f.isAnchor) continue;
|
|
6066
|
+
if (f.isAnchor && !f.canonicalPresent) continue;
|
|
5935
6067
|
if (!f.reachable) {
|
|
5936
6068
|
unreachable.push(f.path);
|
|
5937
6069
|
continue;
|
|
@@ -6010,6 +6142,68 @@ function summarizeWiring(facts) {
|
|
|
6010
6142
|
};
|
|
6011
6143
|
}
|
|
6012
6144
|
|
|
6145
|
+
// src/project/wiring-drift.ts
|
|
6146
|
+
function summarizeWiringDrift(input) {
|
|
6147
|
+
const plan = summarizeSymlinkPlan(input.repos);
|
|
6148
|
+
const missingCanonicals = [
|
|
6149
|
+
...plan.missingCanonical.map((path2) => ({ target: "repo-hub", name: path2 })),
|
|
6150
|
+
...plan.selfAgentsMissing.map(
|
|
6151
|
+
(path2) => ({ target: "repo-self", name: path2 })
|
|
6152
|
+
)
|
|
6153
|
+
];
|
|
6154
|
+
const incompleteWiring = plan.plans.map((p) => ({
|
|
6155
|
+
target: "repo",
|
|
6156
|
+
path: p.path,
|
|
6157
|
+
files: p.toCreate.map((c) => c.name)
|
|
6158
|
+
}));
|
|
6159
|
+
const conflicts = plan.conflicts.map((c) => ({
|
|
6160
|
+
target: "repo",
|
|
6161
|
+
path: c.repo,
|
|
6162
|
+
file: c.file,
|
|
6163
|
+
reason: c.reason,
|
|
6164
|
+
...c.actualTarget !== void 0 ? { actualTarget: c.actualTarget } : {}
|
|
6165
|
+
}));
|
|
6166
|
+
const collisions = plan.collisions.map((c) => ({
|
|
6167
|
+
canonicalName: c.canonicalName,
|
|
6168
|
+
repos: c.repos
|
|
6169
|
+
}));
|
|
6170
|
+
const view = input.view;
|
|
6171
|
+
if (view.kind === "collision") {
|
|
6172
|
+
collisions.push({ canonicalName: view.viewName, repos: [view.repoPath], view: true });
|
|
6173
|
+
} else if (view.kind === "missing-canonical") {
|
|
6174
|
+
missingCanonicals.push({ target: "view", name: view.viewName });
|
|
6175
|
+
} else if (view.kind === "gathered") {
|
|
6176
|
+
const missingSpokes = [];
|
|
6177
|
+
for (const f of view.files) {
|
|
6178
|
+
if (f.state === "missing") {
|
|
6179
|
+
missingSpokes.push(f.name);
|
|
6180
|
+
} else if (f.state === "mismatch" || f.state === "occupied" || f.state === "blocked") {
|
|
6181
|
+
conflicts.push({
|
|
6182
|
+
target: "view",
|
|
6183
|
+
path: view.viewName,
|
|
6184
|
+
file: f.name,
|
|
6185
|
+
reason: f.state,
|
|
6186
|
+
...f.actualTarget !== void 0 ? { actualTarget: f.actualTarget } : {}
|
|
6187
|
+
});
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6190
|
+
if (missingSpokes.length > 0) {
|
|
6191
|
+
incompleteWiring.push({ target: "view", path: view.viewName, files: missingSpokes });
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
return {
|
|
6195
|
+
missingCanonicals,
|
|
6196
|
+
incompleteWiring,
|
|
6197
|
+
conflicts,
|
|
6198
|
+
collisions,
|
|
6199
|
+
unreachable: plan.unreachable,
|
|
6200
|
+
// `unreachable` is intentionally NOT part of `ok`: a declared repo that is not
|
|
6201
|
+
// cloned on this machine is an advisory fact (partial checkout), not drift the
|
|
6202
|
+
// operator must fix here. Only actionable drift denies `ok`.
|
|
6203
|
+
ok: missingCanonicals.length === 0 && incompleteWiring.length === 0 && conflicts.length === 0 && collisions.length === 0
|
|
6204
|
+
};
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6013
6207
|
// src/project/workspace-view.ts
|
|
6014
6208
|
function planWorkspaceView(facts, existing = [], rosterNames = []) {
|
|
6015
6209
|
const deduped = [];
|
|
@@ -7534,6 +7728,33 @@ ${normalized}${markers.end}${section.after}`;
|
|
|
7534
7728
|
throw new Error(`Markers mismatched in ${fileLabel}`);
|
|
7535
7729
|
}
|
|
7536
7730
|
}
|
|
7731
|
+
function seedMarkers(existing, generated, fileLabel, markers = DEFAULT_MARKERS) {
|
|
7732
|
+
const normalized = generated.endsWith("\n") ? generated : `${generated}
|
|
7733
|
+
`;
|
|
7734
|
+
if (existing === null) {
|
|
7735
|
+
return `${markers.start}
|
|
7736
|
+
${normalized}${markers.end}
|
|
7737
|
+
`;
|
|
7738
|
+
}
|
|
7739
|
+
const section = parseMarkers(existing, markers);
|
|
7740
|
+
switch (section.kind) {
|
|
7741
|
+
case "ok":
|
|
7742
|
+
return renderWithMarkers(existing, generated, fileLabel, markers);
|
|
7743
|
+
case "no_markers": {
|
|
7744
|
+
const bom = existing.charCodeAt(0) === 65279 ? "\uFEFF" : "";
|
|
7745
|
+
const body = bom === "" ? existing : existing.slice(1);
|
|
7746
|
+
return `${bom}${markers.start}
|
|
7747
|
+
${normalized}${markers.end}
|
|
7748
|
+
|
|
7749
|
+
${body}`;
|
|
7750
|
+
}
|
|
7751
|
+
case "missing_start":
|
|
7752
|
+
case "missing_end":
|
|
7753
|
+
case "multiple_pairs":
|
|
7754
|
+
case "wrong_order":
|
|
7755
|
+
throw new Error(`Markers mismatched in ${fileLabel}`);
|
|
7756
|
+
}
|
|
7757
|
+
}
|
|
7537
7758
|
function removeMarkerSection(existing, fileLabel, markers = DEFAULT_MARKERS) {
|
|
7538
7759
|
const section = parseMarkers(existing, markers);
|
|
7539
7760
|
switch (section.kind) {
|
|
@@ -8102,11 +8323,13 @@ export {
|
|
|
8102
8323
|
reimportPreservingId,
|
|
8103
8324
|
removeMarkerSection,
|
|
8104
8325
|
removeStopHook,
|
|
8326
|
+
renderAnchorStarter,
|
|
8105
8327
|
renderDecisions,
|
|
8106
8328
|
renderHandoff,
|
|
8107
8329
|
renderOrientation,
|
|
8108
8330
|
renderPresetBlock,
|
|
8109
8331
|
renderReport,
|
|
8332
|
+
renderViewPresetBlock,
|
|
8110
8333
|
renderWithMarkers,
|
|
8111
8334
|
replayEvents,
|
|
8112
8335
|
resolveBasouRepositoryRoot,
|
|
@@ -8119,6 +8342,7 @@ export {
|
|
|
8119
8342
|
sanitizePath,
|
|
8120
8343
|
sanitizeRelatedFiles,
|
|
8121
8344
|
sanitizeWorkingDirectory,
|
|
8345
|
+
seedMarkers,
|
|
8122
8346
|
serializeEventLine,
|
|
8123
8347
|
serializeJsonSchema,
|
|
8124
8348
|
sessionWorkStatsFromEvents,
|
|
@@ -8128,6 +8352,7 @@ export {
|
|
|
8128
8352
|
summarizeRosterDrift,
|
|
8129
8353
|
summarizeSymlinkPlan,
|
|
8130
8354
|
summarizeWiring,
|
|
8355
|
+
summarizeWiringDrift,
|
|
8131
8356
|
tryRemoteUrl,
|
|
8132
8357
|
ulid,
|
|
8133
8358
|
unknownManifestKeys,
|