@grifhinz/logics-manager 2.0.2 → 2.0.5
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 +6 -3
- package/VERSION +1 -1
- package/logics_manager/assist.py +386 -12
- package/logics_manager/bootstrap.py +28 -21
- package/logics_manager/cli.py +146 -37
- package/logics_manager/flow.py +570 -1
- package/logics_manager/sync.py +138 -0
- package/logics_manager/termstyle.py +75 -0
- package/package.json +2 -1
- package/pyproject.toml +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/AlexAgo83/logics-manager/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
|
@@ -35,6 +35,9 @@ Install the npm package with:
|
|
|
35
35
|
npm install -g @grifhinz/logics-manager
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
To update that CLI later, run `logics-manager self-update`.
|
|
39
|
+
The command uses `pip` when the Python package is installed and falls back to `npm` for the global npm package.
|
|
40
|
+
|
|
38
41
|
For the editor client, build and install the VSIX:
|
|
39
42
|
|
|
40
43
|
```bash
|
|
@@ -163,7 +166,7 @@ Windows notes:
|
|
|
163
166
|
|
|
164
167
|
### Install from Marketplace
|
|
165
168
|
|
|
166
|
-
https://marketplace.visualstudio.com/items?itemName=cdx-logics.logics-
|
|
169
|
+
https://marketplace.visualstudio.com/items?itemName=cdx-logics.cdx-logics-vscode
|
|
167
170
|
|
|
168
171
|
### Install from VSIX (recommended for users)
|
|
169
172
|
|
|
@@ -267,7 +270,7 @@ Contract:
|
|
|
267
270
|
- `Environment` can also surface direct remediation actions when the plugin detects a stale runtime, an incomplete bootstrap, a missing global publication, or missing environment placeholders.
|
|
268
271
|
- `Environment` now uses a clearer hierarchy with summary, recommended actions, current status, and technical details, plus hybrid assist runtime state, backend availability, degraded reasons, Claude-bridge presence, and the shared Windows-safe runtime entrypoint.
|
|
269
272
|
- `Check Environment` can be promoted into `Recommended` when the current repo state actually warrants operator attention.
|
|
270
|
-
- repo-local refresh now watches `logics/**/*`, `logics.yaml`, and
|
|
273
|
+
- repo-local refresh now watches `logics/**/*`, `logics.yaml`, and `.git/HEAD`; external global runtime state still requires an explicit refresh because it lives outside the workspace.
|
|
271
274
|
- `Launch Codex` starts Codex using the globally published Logics runtime when the shared runtime is healthy.
|
|
272
275
|
- `AI Runtime Status` probes the shared `logics.py flow assist runtime-status` surface and reports ready providers, flagged providers, cooldown or credential issues, and bounded backend provenance.
|
|
273
276
|
- `AI Provider Insights` opens a dedicated plugin panel backed by `logics.py flow assist roi-report`, with provider mix, execution-path breakdowns, derived rates, estimated ROI proxies, and recent audit drill-down over the shared runtime output.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.0.
|
|
1
|
+
2.0.5
|
package/logics_manager/assist.py
CHANGED
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
import json
|
|
5
|
+
import os
|
|
5
6
|
from collections import Counter
|
|
6
7
|
from datetime import datetime, timedelta, timezone
|
|
7
8
|
import re
|
|
@@ -13,6 +14,7 @@ from typing import Any
|
|
|
13
14
|
from .config import ConfigError, find_repo_root, load_repo_config
|
|
14
15
|
from .doctor import doctor_payload
|
|
15
16
|
from .lint import lint_payload
|
|
17
|
+
from .termstyle import colorize_help
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
DEFAULT_HYBRID_AUDIT_LOG = "logics/.cache/hybrid_assist_audit.jsonl"
|
|
@@ -20,6 +22,7 @@ DEFAULT_HYBRID_MEASUREMENT_LOG = "logics/.cache/hybrid_assist_measurements.jsonl
|
|
|
20
22
|
DEFAULT_HYBRID_ROI_RECENT_LIMIT = 8
|
|
21
23
|
DEFAULT_HYBRID_ROI_WINDOW_DAYS = 14
|
|
22
24
|
DEFAULT_ESTIMATED_REMOTE_TOKENS_PER_LOCAL_RUN = 1200
|
|
25
|
+
HELP_FLAGS = ("-h", "--help")
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
CLAUDE_BRIDGE_VARIANTS: tuple[dict[str, object], ...] = (
|
|
@@ -1283,7 +1286,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1283
1286
|
|
|
1284
1287
|
claude_bridges = sub.add_parser(
|
|
1285
1288
|
"claude-bridges",
|
|
1286
|
-
help="Render the canonical Claude
|
|
1289
|
+
help="Render the canonical Claude runtime publication manifest and prompts derived from the integrated runtime.",
|
|
1287
1290
|
)
|
|
1288
1291
|
claude_bridges.add_argument("--format", choices=("text", "json"), default="text")
|
|
1289
1292
|
claude_bridges.add_argument("--dry-run", action="store_true")
|
|
@@ -1346,10 +1349,375 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1346
1349
|
return parser
|
|
1347
1350
|
|
|
1348
1351
|
|
|
1349
|
-
def
|
|
1352
|
+
def _build_help() -> str:
|
|
1353
|
+
return "\n".join(
|
|
1354
|
+
[
|
|
1355
|
+
"Logics Assist CLI",
|
|
1356
|
+
"Inspect runtime signals and build context bundles.",
|
|
1357
|
+
"",
|
|
1358
|
+
"Usage:",
|
|
1359
|
+
" logics-manager assist <command> [args...]",
|
|
1360
|
+
"",
|
|
1361
|
+
"Runtime and diagnostics:",
|
|
1362
|
+
" runtime-status",
|
|
1363
|
+
" Report local assist runtime readiness.",
|
|
1364
|
+
" Flags: --backend, --model-profile, --model, --ollama-host, --timeout, --format {text,json}, --out, --dry-run",
|
|
1365
|
+
" diff-risk",
|
|
1366
|
+
" Classify the current git diff using deterministic heuristics.",
|
|
1367
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1368
|
+
" commit-plan",
|
|
1369
|
+
" Draft a minimal commit plan from the current git diff.",
|
|
1370
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1371
|
+
" changed-surface-summary",
|
|
1372
|
+
" Summarize the current changed repository surface.",
|
|
1373
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1374
|
+
"",
|
|
1375
|
+
"Review and governance:",
|
|
1376
|
+
" doc-consistency",
|
|
1377
|
+
" Review workflow docs for consistency issues without mutating them.",
|
|
1378
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1379
|
+
" review-checklist",
|
|
1380
|
+
" Generate a bounded review checklist for the current change surface.",
|
|
1381
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1382
|
+
" validation-checklist",
|
|
1383
|
+
" Generate a deterministic validation checklist from the current change surface.",
|
|
1384
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1385
|
+
" validation-summary",
|
|
1386
|
+
" Summarize lint, doctor, and validation impact signals.",
|
|
1387
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1388
|
+
" test-impact-summary",
|
|
1389
|
+
" Summarize the likely test impact of the current change surface.",
|
|
1390
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1391
|
+
" roi-report",
|
|
1392
|
+
" Summarize hybrid assist ROI from local audit and measurement logs.",
|
|
1393
|
+
" Flags: --audit-log, --measurement-log, --recent-limit, --window-days, --format {text,json}, --out, --dry-run",
|
|
1394
|
+
"",
|
|
1395
|
+
"Context and prompts:",
|
|
1396
|
+
" claude-bridges",
|
|
1397
|
+
" Render the canonical Claude runtime publication manifest and prompts.",
|
|
1398
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1399
|
+
" context <flow_name> [ref]",
|
|
1400
|
+
" Build a shared assist context bundle for a flow.",
|
|
1401
|
+
" Flags: --context-mode {summary-only,diff-first,full}, --profile {tiny,normal,deep}, --include-graph, --include-registry, --include-doctor, --format {text,json}, --out, --dry-run",
|
|
1402
|
+
" claude-instructions",
|
|
1403
|
+
" Render the canonical assistant instructions derived from the integrated runtime.",
|
|
1404
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1405
|
+
" next-step [ref]",
|
|
1406
|
+
" Suggest the next bounded Logics step for a target doc.",
|
|
1407
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1408
|
+
" request-draft",
|
|
1409
|
+
" Draft a bounded request doc from an intent.",
|
|
1410
|
+
" Flags: --intent, --format {text,json}, --execution-mode {suggestion-only,execute}, --dry-run",
|
|
1411
|
+
" spec-first-pass <ref>",
|
|
1412
|
+
" Draft a first-pass spec outline from a backlog item.",
|
|
1413
|
+
" Flags: --format {text,json}, --execution-mode {suggestion-only,execute}, --dry-run",
|
|
1414
|
+
" backlog-groom <ref>",
|
|
1415
|
+
" Draft a bounded backlog proposal from a request doc.",
|
|
1416
|
+
" Flags: --format {text,json}, --execution-mode {suggestion-only,execute}, --dry-run",
|
|
1417
|
+
" closure-summary [ref]",
|
|
1418
|
+
" Summarize a delivered request, backlog item, or task.",
|
|
1419
|
+
" Flags: --format {text,json}, --dry-run",
|
|
1420
|
+
"",
|
|
1421
|
+
"Examples:",
|
|
1422
|
+
" logics-manager assist runtime-status --format json",
|
|
1423
|
+
" logics-manager assist context request req_001_my_request --profile deep",
|
|
1424
|
+
" logics-manager assist request-draft --intent \"Improve onboarding\"",
|
|
1425
|
+
]
|
|
1426
|
+
)
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
def _build_command_help(command: str) -> str:
|
|
1430
|
+
if command == "runtime-status":
|
|
1431
|
+
return "\n".join(
|
|
1432
|
+
[
|
|
1433
|
+
"Logics Assist Runtime Status",
|
|
1434
|
+
"Report local assist runtime readiness.",
|
|
1435
|
+
"",
|
|
1436
|
+
"Usage:",
|
|
1437
|
+
" logics-manager assist runtime-status [args...]",
|
|
1438
|
+
"",
|
|
1439
|
+
"Flags:",
|
|
1440
|
+
" --backend",
|
|
1441
|
+
" --model-profile",
|
|
1442
|
+
" --model",
|
|
1443
|
+
" --ollama-host",
|
|
1444
|
+
" --timeout",
|
|
1445
|
+
" --format {text,json}",
|
|
1446
|
+
" --out",
|
|
1447
|
+
" --dry-run",
|
|
1448
|
+
]
|
|
1449
|
+
)
|
|
1450
|
+
if command == "context":
|
|
1451
|
+
return "\n".join(
|
|
1452
|
+
[
|
|
1453
|
+
"Logics Assist Context",
|
|
1454
|
+
"Build a shared assist context bundle for a flow.",
|
|
1455
|
+
"",
|
|
1456
|
+
"Usage:",
|
|
1457
|
+
" logics-manager assist context <flow_name> [ref] [args...]",
|
|
1458
|
+
"",
|
|
1459
|
+
"Flags:",
|
|
1460
|
+
" --context-mode {summary-only,diff-first,full}",
|
|
1461
|
+
" --profile {tiny,normal,deep}",
|
|
1462
|
+
" --include-graph",
|
|
1463
|
+
" --include-registry",
|
|
1464
|
+
" --include-doctor",
|
|
1465
|
+
" --format {text,json}",
|
|
1466
|
+
" --out",
|
|
1467
|
+
" --dry-run",
|
|
1468
|
+
]
|
|
1469
|
+
)
|
|
1470
|
+
if command == "request-draft":
|
|
1471
|
+
return "\n".join(
|
|
1472
|
+
[
|
|
1473
|
+
"Logics Assist Request Draft",
|
|
1474
|
+
"Draft a bounded request doc from an intent.",
|
|
1475
|
+
"",
|
|
1476
|
+
"Usage:",
|
|
1477
|
+
" logics-manager assist request-draft [args...]",
|
|
1478
|
+
"",
|
|
1479
|
+
"Flags:",
|
|
1480
|
+
" --intent",
|
|
1481
|
+
" --format {text,json}",
|
|
1482
|
+
" --execution-mode {suggestion-only,execute}",
|
|
1483
|
+
" --dry-run",
|
|
1484
|
+
]
|
|
1485
|
+
)
|
|
1486
|
+
if command == "spec-first-pass":
|
|
1487
|
+
return "\n".join(
|
|
1488
|
+
[
|
|
1489
|
+
"Logics Assist Spec First Pass",
|
|
1490
|
+
"Draft a first-pass spec outline from a backlog item.",
|
|
1491
|
+
"",
|
|
1492
|
+
"Usage:",
|
|
1493
|
+
" logics-manager assist spec-first-pass <ref> [args...]",
|
|
1494
|
+
"",
|
|
1495
|
+
"Flags:",
|
|
1496
|
+
" --format {text,json}",
|
|
1497
|
+
" --execution-mode {suggestion-only,execute}",
|
|
1498
|
+
" --dry-run",
|
|
1499
|
+
]
|
|
1500
|
+
)
|
|
1501
|
+
if command == "backlog-groom":
|
|
1502
|
+
return "\n".join(
|
|
1503
|
+
[
|
|
1504
|
+
"Logics Assist Backlog Groom",
|
|
1505
|
+
"Draft a bounded backlog proposal from a request doc.",
|
|
1506
|
+
"",
|
|
1507
|
+
"Usage:",
|
|
1508
|
+
" logics-manager assist backlog-groom <ref> [args...]",
|
|
1509
|
+
"",
|
|
1510
|
+
"Flags:",
|
|
1511
|
+
" --format {text,json}",
|
|
1512
|
+
" --execution-mode {suggestion-only,execute}",
|
|
1513
|
+
" --dry-run",
|
|
1514
|
+
]
|
|
1515
|
+
)
|
|
1516
|
+
if command == "closure-summary":
|
|
1517
|
+
return "\n".join(
|
|
1518
|
+
[
|
|
1519
|
+
"Logics Assist Closure Summary",
|
|
1520
|
+
"Summarize a delivered request, backlog item, or task.",
|
|
1521
|
+
"",
|
|
1522
|
+
"Usage:",
|
|
1523
|
+
" logics-manager assist closure-summary [ref] [args...]",
|
|
1524
|
+
"",
|
|
1525
|
+
"Flags:",
|
|
1526
|
+
" --format {text,json}",
|
|
1527
|
+
" --dry-run",
|
|
1528
|
+
]
|
|
1529
|
+
)
|
|
1530
|
+
if command == "roi-report":
|
|
1531
|
+
return "\n".join(
|
|
1532
|
+
[
|
|
1533
|
+
"Logics Assist ROI Report",
|
|
1534
|
+
"Summarize hybrid assist ROI from local audit and measurement logs.",
|
|
1535
|
+
"",
|
|
1536
|
+
"Usage:",
|
|
1537
|
+
" logics-manager assist roi-report [args...]",
|
|
1538
|
+
"",
|
|
1539
|
+
"Flags:",
|
|
1540
|
+
" --audit-log",
|
|
1541
|
+
" --measurement-log",
|
|
1542
|
+
" --recent-limit",
|
|
1543
|
+
" --window-days",
|
|
1544
|
+
" --format {text,json}",
|
|
1545
|
+
" --out",
|
|
1546
|
+
" --dry-run",
|
|
1547
|
+
]
|
|
1548
|
+
)
|
|
1549
|
+
if command == "diff-risk":
|
|
1550
|
+
return "\n".join(
|
|
1551
|
+
[
|
|
1552
|
+
"Logics Assist Diff Risk",
|
|
1553
|
+
"Classify the current git diff using deterministic heuristics.",
|
|
1554
|
+
"",
|
|
1555
|
+
"Usage:",
|
|
1556
|
+
" logics-manager assist diff-risk [args...]",
|
|
1557
|
+
"",
|
|
1558
|
+
"Flags:",
|
|
1559
|
+
" --format {text,json}",
|
|
1560
|
+
" --dry-run",
|
|
1561
|
+
]
|
|
1562
|
+
)
|
|
1563
|
+
if command == "commit-plan":
|
|
1564
|
+
return "\n".join(
|
|
1565
|
+
[
|
|
1566
|
+
"Logics Assist Commit Plan",
|
|
1567
|
+
"Draft a minimal commit plan from the current git diff.",
|
|
1568
|
+
"",
|
|
1569
|
+
"Usage:",
|
|
1570
|
+
" logics-manager assist commit-plan [args...]",
|
|
1571
|
+
"",
|
|
1572
|
+
"Flags:",
|
|
1573
|
+
" --format {text,json}",
|
|
1574
|
+
" --dry-run",
|
|
1575
|
+
]
|
|
1576
|
+
)
|
|
1577
|
+
if command == "changed-surface-summary":
|
|
1578
|
+
return "\n".join(
|
|
1579
|
+
[
|
|
1580
|
+
"Logics Assist Changed Surface Summary",
|
|
1581
|
+
"Summarize the current changed repository surface.",
|
|
1582
|
+
"",
|
|
1583
|
+
"Usage:",
|
|
1584
|
+
" logics-manager assist changed-surface-summary [args...]",
|
|
1585
|
+
"",
|
|
1586
|
+
"Flags:",
|
|
1587
|
+
" --format {text,json}",
|
|
1588
|
+
" --dry-run",
|
|
1589
|
+
]
|
|
1590
|
+
)
|
|
1591
|
+
if command == "doc-consistency":
|
|
1592
|
+
return "\n".join(
|
|
1593
|
+
[
|
|
1594
|
+
"Logics Assist Doc Consistency",
|
|
1595
|
+
"Review workflow docs for consistency issues without mutating them.",
|
|
1596
|
+
"",
|
|
1597
|
+
"Usage:",
|
|
1598
|
+
" logics-manager assist doc-consistency [args...]",
|
|
1599
|
+
"",
|
|
1600
|
+
"Flags:",
|
|
1601
|
+
" --format {text,json}",
|
|
1602
|
+
" --dry-run",
|
|
1603
|
+
]
|
|
1604
|
+
)
|
|
1605
|
+
if command == "review-checklist":
|
|
1606
|
+
return "\n".join(
|
|
1607
|
+
[
|
|
1608
|
+
"Logics Assist Review Checklist",
|
|
1609
|
+
"Generate a bounded review checklist for the current change surface.",
|
|
1610
|
+
"",
|
|
1611
|
+
"Usage:",
|
|
1612
|
+
" logics-manager assist review-checklist [args...]",
|
|
1613
|
+
"",
|
|
1614
|
+
"Flags:",
|
|
1615
|
+
" --format {text,json}",
|
|
1616
|
+
" --dry-run",
|
|
1617
|
+
]
|
|
1618
|
+
)
|
|
1619
|
+
if command == "validation-checklist":
|
|
1620
|
+
return "\n".join(
|
|
1621
|
+
[
|
|
1622
|
+
"Logics Assist Validation Checklist",
|
|
1623
|
+
"Generate a deterministic validation checklist from the current change surface.",
|
|
1624
|
+
"",
|
|
1625
|
+
"Usage:",
|
|
1626
|
+
" logics-manager assist validation-checklist [args...]",
|
|
1627
|
+
"",
|
|
1628
|
+
"Flags:",
|
|
1629
|
+
" --format {text,json}",
|
|
1630
|
+
" --dry-run",
|
|
1631
|
+
]
|
|
1632
|
+
)
|
|
1633
|
+
if command == "validation-summary":
|
|
1634
|
+
return "\n".join(
|
|
1635
|
+
[
|
|
1636
|
+
"Logics Assist Validation Summary",
|
|
1637
|
+
"Summarize lint, doctor, and validation impact signals.",
|
|
1638
|
+
"",
|
|
1639
|
+
"Usage:",
|
|
1640
|
+
" logics-manager assist validation-summary [args...]",
|
|
1641
|
+
"",
|
|
1642
|
+
"Flags:",
|
|
1643
|
+
" --format {text,json}",
|
|
1644
|
+
" --dry-run",
|
|
1645
|
+
]
|
|
1646
|
+
)
|
|
1647
|
+
if command == "test-impact-summary":
|
|
1648
|
+
return "\n".join(
|
|
1649
|
+
[
|
|
1650
|
+
"Logics Assist Test Impact Summary",
|
|
1651
|
+
"Summarize the likely test impact of the current change surface.",
|
|
1652
|
+
"",
|
|
1653
|
+
"Usage:",
|
|
1654
|
+
" logics-manager assist test-impact-summary [args...]",
|
|
1655
|
+
"",
|
|
1656
|
+
"Flags:",
|
|
1657
|
+
" --format {text,json}",
|
|
1658
|
+
" --dry-run",
|
|
1659
|
+
]
|
|
1660
|
+
)
|
|
1661
|
+
if command == "claude-bridges":
|
|
1662
|
+
return "\n".join(
|
|
1663
|
+
[
|
|
1664
|
+
"Logics Assist Claude Bridges",
|
|
1665
|
+
"Render the canonical Claude runtime publication manifest and prompts.",
|
|
1666
|
+
"",
|
|
1667
|
+
"Usage:",
|
|
1668
|
+
" logics-manager assist claude-bridges [args...]",
|
|
1669
|
+
"",
|
|
1670
|
+
"Flags:",
|
|
1671
|
+
" --format {text,json}",
|
|
1672
|
+
" --dry-run",
|
|
1673
|
+
]
|
|
1674
|
+
)
|
|
1675
|
+
if command == "claude-instructions":
|
|
1676
|
+
return "\n".join(
|
|
1677
|
+
[
|
|
1678
|
+
"Logics Assist Claude Instructions",
|
|
1679
|
+
"Render the canonical assistant instructions derived from the integrated runtime.",
|
|
1680
|
+
"",
|
|
1681
|
+
"Usage:",
|
|
1682
|
+
" logics-manager assist claude-instructions [args...]",
|
|
1683
|
+
"",
|
|
1684
|
+
"Flags:",
|
|
1685
|
+
" --format {text,json}",
|
|
1686
|
+
" --dry-run",
|
|
1687
|
+
]
|
|
1688
|
+
)
|
|
1689
|
+
if command == "next-step":
|
|
1690
|
+
return "\n".join(
|
|
1691
|
+
[
|
|
1692
|
+
"Logics Assist Next Step",
|
|
1693
|
+
"Suggest the next bounded Logics step for a target doc.",
|
|
1694
|
+
"",
|
|
1695
|
+
"Usage:",
|
|
1696
|
+
" logics-manager assist next-step [ref] [args...]",
|
|
1697
|
+
"",
|
|
1698
|
+
"Flags:",
|
|
1699
|
+
" --format {text,json}",
|
|
1700
|
+
" --dry-run",
|
|
1701
|
+
]
|
|
1702
|
+
)
|
|
1703
|
+
return _build_help()
|
|
1704
|
+
|
|
1705
|
+
|
|
1706
|
+
def _print_help(text: str) -> None:
|
|
1707
|
+
print(colorize_help(text))
|
|
1708
|
+
|
|
1709
|
+
|
|
1710
|
+
def _get_global_claude_home() -> Path:
|
|
1711
|
+
return Path(os.environ.get("LOGICS_CLAUDE_GLOBAL_HOME") or (Path.home() / ".claude")).resolve()
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
def _claude_bridge_status(_repo_root: Path) -> dict[str, object]:
|
|
1715
|
+
global_home = _get_global_claude_home()
|
|
1350
1716
|
detected_variants: list[str] = []
|
|
1351
1717
|
for variant in CLAUDE_BRIDGE_VARIANTS:
|
|
1352
|
-
|
|
1718
|
+
command_path = global_home / str(variant["command_path"]).replace(".claude/", "")
|
|
1719
|
+
agent_path = global_home / str(variant["agent_path"]).replace(".claude/", "")
|
|
1720
|
+
if command_path.is_file() and agent_path.is_file():
|
|
1353
1721
|
detected_variants.append(variant["id"])
|
|
1354
1722
|
return {
|
|
1355
1723
|
"available": bool(detected_variants),
|
|
@@ -1368,7 +1736,7 @@ def _render_claude_bridge_lines(variant: dict[str, object], prompt: str) -> tupl
|
|
|
1368
1736
|
command_lines = [
|
|
1369
1737
|
f"# {title}",
|
|
1370
1738
|
"",
|
|
1371
|
-
f"Use the
|
|
1739
|
+
f"Use the published global {title.lower()} bridge for this project.",
|
|
1372
1740
|
"",
|
|
1373
1741
|
"Primary prompt:",
|
|
1374
1742
|
prompt,
|
|
@@ -1377,7 +1745,7 @@ def _render_claude_bridge_lines(variant: dict[str, object], prompt: str) -> tupl
|
|
|
1377
1745
|
agent_lines = [
|
|
1378
1746
|
f"# {title} Agent",
|
|
1379
1747
|
"",
|
|
1380
|
-
f"Use the
|
|
1748
|
+
f"Use the published global {title.lower()} agent for this project.",
|
|
1381
1749
|
"",
|
|
1382
1750
|
"Default prompt:",
|
|
1383
1751
|
prompt,
|
|
@@ -1433,8 +1801,8 @@ def _build_claude_instructions(repo_root: Path) -> dict[str, object]:
|
|
|
1433
1801
|
"- `python3 -m logics_manager lint --require-status`",
|
|
1434
1802
|
"- `python3 -m logics_manager audit --legacy-cutoff-version 1.1.0 --group-by-doc`",
|
|
1435
1803
|
"",
|
|
1436
|
-
"
|
|
1437
|
-
"Do not edit
|
|
1804
|
+
"Claude runtime artifacts are generated outside the repository from the integrated runtime.",
|
|
1805
|
+
"Do not edit generated runtime artifacts by hand unless you are deliberately repairing a generated artifact.",
|
|
1438
1806
|
"",
|
|
1439
1807
|
"Do not edit indicator lines or workflow links by hand.",
|
|
1440
1808
|
"",
|
|
@@ -1454,8 +1822,8 @@ def _select_backend(requested_backend: str | None, bridge_status: dict[str, obje
|
|
|
1454
1822
|
if requested_backend and requested_backend != "auto":
|
|
1455
1823
|
return requested_backend, []
|
|
1456
1824
|
if bridge_status.get("available"):
|
|
1457
|
-
return "codex", ["
|
|
1458
|
-
return "deterministic", ["no
|
|
1825
|
+
return "codex", ["global Claude runtime published"]
|
|
1826
|
+
return "deterministic", ["no global Claude runtime published"]
|
|
1459
1827
|
|
|
1460
1828
|
|
|
1461
1829
|
def cmd_claude_bridges(args: argparse.Namespace) -> dict[str, object]:
|
|
@@ -1953,9 +2321,9 @@ def cmd_runtime_status(args: argparse.Namespace) -> dict[str, object]:
|
|
|
1953
2321
|
print(f"- selected backend: {selected_backend}")
|
|
1954
2322
|
print(f"- model profile: {default_profile}")
|
|
1955
2323
|
print(f"- model: {resolved_model}")
|
|
1956
|
-
print(f"-
|
|
2324
|
+
print(f"- global Claude runtime available: {'yes' if bridge_status['available'] else 'no'}")
|
|
1957
2325
|
if bridge_status["preferred_variant"]:
|
|
1958
|
-
print(f"-
|
|
2326
|
+
print(f"- runtime variant: {bridge_status['preferred_variant']}")
|
|
1959
2327
|
return payload
|
|
1960
2328
|
|
|
1961
2329
|
|
|
@@ -2200,11 +2568,17 @@ def cmd_context(args: argparse.Namespace) -> dict[str, object]:
|
|
|
2200
2568
|
print(f"- ref: {args.ref or '<flow-default>'}")
|
|
2201
2569
|
print(f"- mode: {context_mode}")
|
|
2202
2570
|
print(f"- profile: {profile}")
|
|
2203
|
-
print(f"-
|
|
2571
|
+
print(f"- global Claude runtime available: {'yes' if bridge_status['available'] else 'no'}")
|
|
2204
2572
|
return payload
|
|
2205
2573
|
|
|
2206
2574
|
|
|
2207
2575
|
def main(argv: list[str]) -> int:
|
|
2576
|
+
if not argv or argv[0] in HELP_FLAGS:
|
|
2577
|
+
_print_help(_build_help())
|
|
2578
|
+
return 0
|
|
2579
|
+
if argv[0] in {"runtime-status", "context", "request-draft", "spec-first-pass", "backlog-groom", "closure-summary", "roi-report", "diff-risk", "commit-plan", "changed-surface-summary", "doc-consistency", "review-checklist", "validation-checklist", "validation-summary", "test-impact-summary", "claude-bridges", "claude-instructions", "next-step"} and len(argv) > 1 and argv[1] in HELP_FLAGS:
|
|
2580
|
+
_print_help(_build_command_help(argv[0]))
|
|
2581
|
+
return 0
|
|
2208
2582
|
parser = build_parser()
|
|
2209
2583
|
args = parser.parse_args(argv)
|
|
2210
2584
|
payload = args.func(args)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import shutil
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
6
|
-
from .assist import
|
|
7
|
+
from .assist import _build_claude_instructions
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
WORKFLOW_DIRS: tuple[str, ...] = ("request", "backlog", "tasks", "specs", "product", "architecture", "external", ".cache")
|
|
@@ -13,14 +14,34 @@ def _workflow_directories(repo_root: Path) -> list[Path]:
|
|
|
13
14
|
return [repo_root / "logics" / name for name in WORKFLOW_DIRS]
|
|
14
15
|
|
|
15
16
|
|
|
17
|
+
def _legacy_runtime_paths(repo_root: Path) -> list[Path]:
|
|
18
|
+
return [repo_root / ".claude", repo_root / "logics" / "skills"]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _remove_legacy_runtime_paths(repo_root: Path, *, check: bool) -> list[str]:
|
|
22
|
+
removed_paths: list[str] = []
|
|
23
|
+
for target in _legacy_runtime_paths(repo_root):
|
|
24
|
+
if not target.exists():
|
|
25
|
+
continue
|
|
26
|
+
removed_paths.append(target.relative_to(repo_root).as_posix() + ("/" if target.is_dir() else ""))
|
|
27
|
+
if not check:
|
|
28
|
+
if target.is_dir():
|
|
29
|
+
shutil.rmtree(target)
|
|
30
|
+
else:
|
|
31
|
+
target.unlink()
|
|
32
|
+
return removed_paths
|
|
33
|
+
|
|
34
|
+
|
|
16
35
|
def bootstrap_payload(repo_root: Path, *, check: bool) -> dict[str, object]:
|
|
17
36
|
logics_root = repo_root / "logics"
|
|
18
|
-
bridge_manifest = _build_claude_bridge_manifest(repo_root)
|
|
19
37
|
instructions_manifest = _build_claude_instructions(repo_root)
|
|
20
38
|
directory_actions: list[dict[str, object]] = []
|
|
21
39
|
created_paths: list[str] = []
|
|
40
|
+
removed_paths: list[str] = []
|
|
22
41
|
missing_paths: list[str] = []
|
|
23
42
|
|
|
43
|
+
removed_paths.extend(_remove_legacy_runtime_paths(repo_root, check=check))
|
|
44
|
+
|
|
24
45
|
if not logics_root.exists():
|
|
25
46
|
missing_paths.append("logics/")
|
|
26
47
|
elif not logics_root.is_dir():
|
|
@@ -71,24 +92,6 @@ def bootstrap_payload(repo_root: Path, *, check: bool) -> dict[str, object]:
|
|
|
71
92
|
instructions_path.write_text(instructions_content, encoding="utf-8")
|
|
72
93
|
created_paths.append("logics/instructions.md")
|
|
73
94
|
|
|
74
|
-
for bridge in bridge_manifest["bridges"]:
|
|
75
|
-
for rel_path, content in (
|
|
76
|
-
(str(bridge["command_path"]), str(bridge["command_content"])),
|
|
77
|
-
(str(bridge["agent_path"]), str(bridge["agent_content"])),
|
|
78
|
-
):
|
|
79
|
-
bridge_path = repo_root / rel_path
|
|
80
|
-
if bridge_path.exists():
|
|
81
|
-
try:
|
|
82
|
-
if bridge_path.read_text(encoding="utf-8") == content:
|
|
83
|
-
continue
|
|
84
|
-
except Exception:
|
|
85
|
-
pass
|
|
86
|
-
missing_paths.append(rel_path)
|
|
87
|
-
if not check:
|
|
88
|
-
bridge_path.parent.mkdir(parents=True, exist_ok=True)
|
|
89
|
-
bridge_path.write_text(content, encoding="utf-8")
|
|
90
|
-
created_paths.append(rel_path)
|
|
91
|
-
|
|
92
95
|
ok = not missing_paths if check else True
|
|
93
96
|
return {
|
|
94
97
|
"command": "bootstrap",
|
|
@@ -97,8 +100,8 @@ def bootstrap_payload(repo_root: Path, *, check: bool) -> dict[str, object]:
|
|
|
97
100
|
"ok": ok,
|
|
98
101
|
"missing_paths": missing_paths,
|
|
99
102
|
"created_paths": created_paths,
|
|
103
|
+
"removed_paths": removed_paths,
|
|
100
104
|
"directory_actions": directory_actions,
|
|
101
|
-
"claude_bridge_count": bridge_manifest["bridge_count"],
|
|
102
105
|
"claude_instruction_line_count": instructions_manifest["line_count"],
|
|
103
106
|
}
|
|
104
107
|
|
|
@@ -114,6 +117,10 @@ def render_bootstrap(payload: dict[str, object], *, output_format: str) -> str:
|
|
|
114
117
|
lines.append(f"- missing: {path}")
|
|
115
118
|
return "\n".join(lines)
|
|
116
119
|
lines = ["Bootstrap: OK"]
|
|
120
|
+
if payload.get("removed_paths"):
|
|
121
|
+
lines.append("- removed:")
|
|
122
|
+
for path in payload["removed_paths"]:
|
|
123
|
+
lines.append(f" - {path}")
|
|
117
124
|
if payload["created_paths"]:
|
|
118
125
|
lines.append("- created:")
|
|
119
126
|
for path in payload["created_paths"]:
|