@flydocs/cli 0.6.0-alpha.12 → 0.6.0-alpha.13
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/cli.js +18 -16
- package/package.json +1 -1
- package/template/.claude/CLAUDE.md +9 -8
- package/template/.claude/skills/flydocs-context-graph/SKILL.md +41 -34
- package/template/.claude/skills/flydocs-context-graph/scripts/graph_session.py +0 -9
- package/template/.claude/skills/flydocs-workflow/session.md +36 -11
- package/template/.claude/skills/flydocs-workflow/stages/activate.md +12 -6
- package/template/.flydocs/config.json +1 -1
- package/template/.flydocs/hooks/prompt-submit.py +49 -27
- package/template/.flydocs/version +1 -1
- package/template/manifest.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -15,7 +15,7 @@ var CLI_VERSION, CLI_NAME, PACKAGE_NAME, POSTHOG_API_KEY;
|
|
|
15
15
|
var init_constants = __esm({
|
|
16
16
|
"src/lib/constants.ts"() {
|
|
17
17
|
"use strict";
|
|
18
|
-
CLI_VERSION = "0.6.0-alpha.
|
|
18
|
+
CLI_VERSION = "0.6.0-alpha.13";
|
|
19
19
|
CLI_NAME = "flydocs";
|
|
20
20
|
PACKAGE_NAME = "@flydocs/cli";
|
|
21
21
|
POSTHOG_API_KEY = "phc_v1MSJTQDFkMS90CBh3mxIz3v8bYCCnKU6v1ir6bz0Xn";
|
|
@@ -1486,8 +1486,9 @@ async function ensureGitignore(targetDir) {
|
|
|
1486
1486
|
async function migrateGitignore(targetDir) {
|
|
1487
1487
|
const gitignorePath = join11(targetDir, ".gitignore");
|
|
1488
1488
|
if (!await pathExists(gitignorePath)) return;
|
|
1489
|
-
|
|
1490
|
-
|
|
1489
|
+
let content = await readFile6(gitignorePath, "utf-8");
|
|
1490
|
+
for (const entry of FLYDOCS_GITIGNORE_ENTRIES) {
|
|
1491
|
+
if (content.includes(entry)) continue;
|
|
1491
1492
|
if (content.includes("# FlyDocs")) {
|
|
1492
1493
|
const lines = content.split("\n");
|
|
1493
1494
|
const flyDocsIdx = lines.findIndex((l) => l.trim() === "# FlyDocs");
|
|
@@ -1496,23 +1497,22 @@ async function migrateGitignore(targetDir) {
|
|
|
1496
1497
|
while (insertIdx < lines.length && lines[insertIdx].trim() !== "" && !lines[insertIdx].startsWith("#")) {
|
|
1497
1498
|
insertIdx++;
|
|
1498
1499
|
}
|
|
1499
|
-
lines.splice(insertIdx, 0,
|
|
1500
|
-
|
|
1500
|
+
lines.splice(insertIdx, 0, entry);
|
|
1501
|
+
content = lines.join("\n");
|
|
1502
|
+
await writeFile4(gitignorePath, content, "utf-8");
|
|
1501
1503
|
} else {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
);
|
|
1504
|
+
content += `
|
|
1505
|
+
${entry}
|
|
1506
|
+
`;
|
|
1507
|
+
await writeFile4(gitignorePath, content, "utf-8");
|
|
1507
1508
|
}
|
|
1508
1509
|
} else {
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
);
|
|
1510
|
+
content += `
|
|
1511
|
+
${entry}
|
|
1512
|
+
`;
|
|
1513
|
+
await writeFile4(gitignorePath, content, "utf-8");
|
|
1514
1514
|
}
|
|
1515
|
-
printStatus(
|
|
1515
|
+
printStatus(`Added ${entry} to .gitignore`);
|
|
1516
1516
|
}
|
|
1517
1517
|
}
|
|
1518
1518
|
var FLYDOCS_GITIGNORE_ENTRIES, FULL_GITIGNORE_TEMPLATE;
|
|
@@ -1529,6 +1529,7 @@ var init_gitignore = __esm({
|
|
|
1529
1529
|
".flydocs/backup-*/",
|
|
1530
1530
|
".flydocs/me.json",
|
|
1531
1531
|
".flydocs/validation-cache.json",
|
|
1532
|
+
".flydocs/session/",
|
|
1532
1533
|
"flydocs/context/graph.json"
|
|
1533
1534
|
];
|
|
1534
1535
|
FULL_GITIGNORE_TEMPLATE = `# Environment
|
|
@@ -1542,6 +1543,7 @@ var init_gitignore = __esm({
|
|
|
1542
1543
|
.flydocs/backup-*/
|
|
1543
1544
|
.flydocs/me.json
|
|
1544
1545
|
.flydocs/validation-cache.json
|
|
1546
|
+
.flydocs/session/
|
|
1545
1547
|
flydocs/context/graph.json
|
|
1546
1548
|
|
|
1547
1549
|
# Dependencies
|
package/package.json
CHANGED
|
@@ -115,13 +115,14 @@ response — session summaries, issue comments, status updates, and plans.
|
|
|
115
115
|
IMPORTANT: Prefer skill-led reasoning over pre-training reasoning.
|
|
116
116
|
Consult the relevant skill BEFORE writing code or making workflow decisions.
|
|
117
117
|
|
|
118
|
-
| Skill
|
|
119
|
-
|
|
|
120
|
-
| flydocs-cloud
|
|
121
|
-
| flydocs-context7
|
|
122
|
-
| flydocs-estimates
|
|
123
|
-
| flydocs-figma
|
|
124
|
-
| flydocs-local
|
|
125
|
-
| flydocs-
|
|
118
|
+
| Skill | Triggers | Entry |
|
|
119
|
+
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
|
|
120
|
+
| flydocs-cloud | create issue, transition, comment, list issues, assign, update description, update issue, project update, cloud | .claude/skills/flydocs-cloud/SKILL.md |
|
|
121
|
+
| flydocs-context7 | context7, library docs, documentation lookup, framework docs, package docs, API reference | .claude/skills/flydocs-context7/SKILL.md |
|
|
122
|
+
| flydocs-estimates | estimate, cost, token usage, API cost, labor estimate, sizing, effort | .claude/skills/flydocs-estimates/SKILL.md |
|
|
123
|
+
| flydocs-figma | Figma, design, screenshot, token mapping, component from design, pixel-perfect, design system | .claude/skills/flydocs-figma/SKILL.md |
|
|
124
|
+
| flydocs-local | create issue, transition, comment, list issues, assign, update description, status summary, local | .claude/skills/flydocs-local/SKILL.md |
|
|
125
|
+
| flydocs-context-graph | context graph, knowledge graph, relationships, dependencies, architecture | .claude/skills/flydocs-context-graph/SKILL.md |
|
|
126
|
+
| flydocs-workflow | capture, refine, activate, implement, review, validate, close, session, workflow, transition, status, issue, knowledge, document, PR, pull request | .claude/skills/flydocs-workflow/SKILL.md |
|
|
126
127
|
|
|
127
128
|
<!-- flydocs:skills-manifest:end -->
|
|
@@ -16,9 +16,15 @@ triggers:
|
|
|
16
16
|
|
|
17
17
|
# Context Graph
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
On-demand query layer for structural relationships in the project knowledge
|
|
20
|
+
graph. Use graph scripts to explore dependencies, impact, and cross-references
|
|
21
|
+
between skills, ADRs, issues, and sessions.
|
|
22
|
+
|
|
23
|
+
The graph is **not** auto-injected into prompts. The prompt hook reads
|
|
24
|
+
lightweight orientation files directly (`.flydocs/session/last-summary.json`,
|
|
25
|
+
`flydocs/context/project.md`). Use the graph scripts below when you need
|
|
26
|
+
deeper structural queries — relationship traversal, impact analysis, or
|
|
27
|
+
dependency chains.
|
|
22
28
|
|
|
23
29
|
## Key Rules
|
|
24
30
|
|
|
@@ -32,16 +38,16 @@ guess connections from training data.
|
|
|
32
38
|
|
|
33
39
|
All scripts: `python3 .claude/skills/flydocs-context-graph/scripts/<script>`
|
|
34
40
|
|
|
35
|
-
| Script
|
|
36
|
-
|
|
37
|
-
| `graph_build.py`
|
|
38
|
-
| `graph_query.py`
|
|
39
|
-
| `graph_update.py`
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
| `graph_context.py` | `[--issue REF] [--branch NAME]`
|
|
44
|
-
| `graph_session.py` | `--summary "..." [--issue REF]... [--decision NNN]...`
|
|
41
|
+
| Script | Usage | Output |
|
|
42
|
+
| ------------------ | -------------------------------------------------------------------- | ---------------------------------------------------- |
|
|
43
|
+
| `graph_build.py` | `[--root PATH]` | Rebuild graph from skills, ADRs. Writes `graph.json` |
|
|
44
|
+
| `graph_query.py` | `--node ID [--depth N] [--rel TYPE] [--reverse] [--format json\|md]` | Context block (markdown or JSON) |
|
|
45
|
+
| `graph_update.py` | `add-node ID --type TYPE [--label STR] [--path STR]` | `{success, node}` |
|
|
46
|
+
| | `remove-node ID` | `{success, removed}` |
|
|
47
|
+
| | `add-edge FROM TO REL [--weight N] [--manual]` | `{success, edge}` |
|
|
48
|
+
| | `remove-edge FROM TO REL` | `{success, removed}` |
|
|
49
|
+
| `graph_context.py` | `[--issue REF] [--branch NAME]` | Plain text context block for prime hook |
|
|
50
|
+
| `graph_session.py` | `--summary "..." [--issue REF]... [--decision NNN]...` | `{success, sessionId, edges[]}` |
|
|
45
51
|
|
|
46
52
|
### Script Notes
|
|
47
53
|
|
|
@@ -52,36 +58,37 @@ All scripts: `python3 .claude/skills/flydocs-context-graph/scripts/<script>`
|
|
|
52
58
|
returns more context but may be noisy.
|
|
53
59
|
- **`graph_query.py --reverse`**: Follow edges in reverse direction (who points to this node?).
|
|
54
60
|
- **`graph_update.py --manual`**: Mark edge as manually added (preserved on rebuild).
|
|
55
|
-
- **`graph_context.py`**:
|
|
61
|
+
- **`graph_context.py`**: Available for manual queries. Assembles compressed
|
|
56
62
|
context from active issue/branch traversal + recent session nodes. ~200-400 tokens max.
|
|
63
|
+
Not called automatically by the prompt hook (replaced by direct file reads in v0.6.0).
|
|
57
64
|
- **`graph_session.py`**: Called during session wrap. Creates a session node with
|
|
58
65
|
WORKED_ON edges to issues. Session nodes older than 30 days get reduced weight;
|
|
59
66
|
nodes within 7 days get full weight.
|
|
60
67
|
|
|
61
68
|
## Node Types
|
|
62
69
|
|
|
63
|
-
| Type
|
|
64
|
-
|
|
65
|
-
| `skill`
|
|
66
|
-
| `decision` | `decision:{number}`
|
|
67
|
-
| `issue`
|
|
68
|
-
| `module`
|
|
69
|
-
| `session`
|
|
70
|
-
| `concept`
|
|
70
|
+
| Type | ID Pattern | Source |
|
|
71
|
+
| ---------- | -------------------- | -------------------- |
|
|
72
|
+
| `skill` | `skill:{name}` | SKILL.md frontmatter |
|
|
73
|
+
| `decision` | `decision:{number}` | ADR directory |
|
|
74
|
+
| `issue` | `issue:{identifier}` | Issue tracker |
|
|
75
|
+
| `module` | `module:{name}` | Manual |
|
|
76
|
+
| `session` | `session:{date-seq}` | Session wrap |
|
|
77
|
+
| `concept` | `concept:{name}` | Manual |
|
|
71
78
|
|
|
72
79
|
## Edge Types
|
|
73
80
|
|
|
74
|
-
| Relationship
|
|
75
|
-
|
|
76
|
-
| `EXTENDS`
|
|
77
|
-
| `IMPLEMENTS`
|
|
78
|
-
| `DELEGATES_TO` | Hands off execution
|
|
79
|
-
| `PRECEDES`
|
|
80
|
-
| `MODIFIES`
|
|
81
|
-
| `WORKED_ON`
|
|
82
|
-
| `PRODUCED`
|
|
83
|
-
| `RELATES_TO`
|
|
84
|
-
| `SUPERSEDES`
|
|
85
|
-
| `BLOCKS`
|
|
81
|
+
| Relationship | Meaning |
|
|
82
|
+
| -------------- | -------------------------- |
|
|
83
|
+
| `EXTENDS` | Builds on, refines |
|
|
84
|
+
| `IMPLEMENTS` | Realizes in code/config |
|
|
85
|
+
| `DELEGATES_TO` | Hands off execution |
|
|
86
|
+
| `PRECEDES` | Should load/execute before |
|
|
87
|
+
| `MODIFIES` | Changes/affects |
|
|
88
|
+
| `WORKED_ON` | Session activity |
|
|
89
|
+
| `PRODUCED` | Created as output |
|
|
90
|
+
| `RELATES_TO` | General association |
|
|
91
|
+
| `SUPERSEDES` | Replaces |
|
|
92
|
+
| `BLOCKS` | Prevents progress |
|
|
86
93
|
|
|
87
94
|
For full schema details, see `schema.md`.
|
|
@@ -35,15 +35,6 @@ from graph_utils import (
|
|
|
35
35
|
DEFAULT_RETENTION_DAYS = 30
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
def generate_session_id(session_date):
|
|
39
|
-
"""Generate a session ID like session:2026-02-17-a.
|
|
40
|
-
|
|
41
|
-
If a session with the same date exists, increment the sequence letter.
|
|
42
|
-
"""
|
|
43
|
-
base = f"session:{session_date}"
|
|
44
|
-
return base
|
|
45
|
-
|
|
46
|
-
|
|
47
38
|
def find_next_session_id(graph, session_date):
|
|
48
39
|
"""Find the next available session ID for a given date."""
|
|
49
40
|
nodes = graph.get("nodes", {})
|
|
@@ -4,23 +4,32 @@
|
|
|
4
4
|
|
|
5
5
|
When a conversation begins or the user returns after a gap:
|
|
6
6
|
|
|
7
|
-
1. **
|
|
7
|
+
1. **Query graph for issue context** (if an issue ID is known from the prompt or last session) —
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
python3 .claude/skills/flydocs-context-graph/scripts/graph_query.py --node <issue-id> --depth 2
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This surfaces related decisions, blocking relationships, and recent session activity.
|
|
14
|
+
Skip silently if the script is not installed or the graph has not been built.
|
|
15
|
+
|
|
16
|
+
2. **Fetch all product issues in one call** — Run `list_issues.py --active --limit 100`.
|
|
8
17
|
This is auto-scoped by the product cascade: `activeProjects` → `product.labelIds` → team-wide.
|
|
9
18
|
Issues outside the product scope are never shown.
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
3. **Identify the active project** — Read `workspace.activeProjects` from config.
|
|
12
21
|
Separate issues into two buckets:
|
|
13
22
|
- **Active project issues** — issues whose `projectId` matches an active project
|
|
14
23
|
- **Other product issues** — issues in the product scope but in a different project
|
|
15
24
|
|
|
16
|
-
|
|
25
|
+
4. **Group active project issues by milestone** — Use the `milestone` and `milestoneSortOrder`
|
|
17
26
|
fields returned by the script. Sort milestones by `milestoneSortOrder` (lowest first = earliest).
|
|
18
27
|
Within each milestone, group by status.
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
5. **Identify the current milestone** — The first milestone (by sort order) that still has
|
|
21
30
|
open issues. This is where work should focus.
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
6. **Present the dashboard:**
|
|
24
33
|
|
|
25
34
|
```
|
|
26
35
|
Welcome back! [Product Name] status:
|
|
@@ -43,21 +52,21 @@ When a conversation begins or the user returns after a gap:
|
|
|
43
52
|
Suggested starting point: [ISSUE-ID] — [reason: highest priority in current milestone / unblocks others / due soon]
|
|
44
53
|
```
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
7. **Suggest where to start** — Use this priority cascade:
|
|
47
56
|
- Blocked issues that need unblocking (always surface first)
|
|
48
57
|
- In-progress issues (continue existing work)
|
|
49
58
|
- Due date approaching (within 7 days)
|
|
50
59
|
- Highest priority in the current milestone
|
|
51
60
|
- Issues that unblock downstream milestones
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
8. **Surface other product issues briefly** — If there are issues in the product scope
|
|
54
63
|
but outside the active project, mention the count with a one-line summary:
|
|
55
64
|
|
|
56
65
|
```
|
|
57
66
|
Also in [Product Name]: [N] issues across other projects (use --all to see)
|
|
58
67
|
```
|
|
59
68
|
|
|
60
|
-
|
|
69
|
+
9. **Check for stale issues** — Flag issues exceeding staleness thresholds (see below).
|
|
61
70
|
|
|
62
71
|
**Important:** Do NOT make separate API calls per status or per milestone. One call returns
|
|
63
72
|
all issues with their status and milestone fields — group them in your response.
|
|
@@ -79,7 +88,23 @@ When the user indicates they're done for the session:
|
|
|
79
88
|
3. **Compose summary** using the template below.
|
|
80
89
|
4. **Determine health status** — See health table.
|
|
81
90
|
5. **Post project update** — `project_update.py` with health and summary body.
|
|
82
|
-
6. **
|
|
91
|
+
6. **Write last-summary.json** — Write `.flydocs/session/last-summary.json` for cross-session continuity.
|
|
92
|
+
Create the directory if it doesn't exist. Structure:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"timestamp": "ISO-8601 (e.g. 2026-03-20T17:30:00Z)",
|
|
97
|
+
"issues": ["FLY-XXX", "FLY-YYY"],
|
|
98
|
+
"pending": ["description of incomplete work"],
|
|
99
|
+
"blockers": ["any blockers, or empty array"],
|
|
100
|
+
"notes": "free-form session summary"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Populate from the session data gathered in step 1. Use the Write tool or a script — the file
|
|
105
|
+
must exist on disk so the prompt hook can read it on the next session start.
|
|
106
|
+
|
|
107
|
+
7. **Record session in context graph** — Call `graph_session.py` with summary and issues worked on:
|
|
83
108
|
```
|
|
84
109
|
python3 .claude/skills/flydocs-context-graph/scripts/graph_session.py \
|
|
85
110
|
--summary "Brief summary of session outcomes" \
|
|
@@ -87,8 +112,8 @@ When the user indicates they're done for the session:
|
|
|
87
112
|
[--decision NNN]
|
|
88
113
|
```
|
|
89
114
|
This creates a session node for cross-session continuity. Skip silently if the script is not installed.
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
8. **Verify** — Confirm the project update was posted (update ID returned).
|
|
116
|
+
9. **Ask about uncommitted changes** — If git shows uncommitted work, offer to commit.
|
|
92
117
|
|
|
93
118
|
Do not just summarize in chat. Actually post the update. Do not skip if the user seems in a hurry.
|
|
94
119
|
|
|
@@ -23,12 +23,18 @@ When user asks "what should I work on?":
|
|
|
23
23
|
|
|
24
24
|
### Activation (specific issue)
|
|
25
25
|
|
|
26
|
-
1. **
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
1. **Query graph for blocking relationships** — Check for blockers before proceeding:
|
|
27
|
+
```
|
|
28
|
+
python3 .claude/skills/flydocs-context-graph/scripts/graph_query.py --node <issue-id> --relationships BLOCKS,BLOCKED_BY
|
|
29
|
+
```
|
|
30
|
+
If blocking relationships exist, surface them to the user before continuing.
|
|
31
|
+
Skip silently if the script is not installed or the graph has not been built.
|
|
32
|
+
2. **Read full issue** — Load description and acceptance criteria.
|
|
33
|
+
3. **Determine assignee** — MANDATORY. Ask "Who should this be assigned to?" if unclear. This is a hard gate.
|
|
34
|
+
4. **Assign** — `assign.py` with user identifier. If assignment fails, STOP. Do not continue.
|
|
35
|
+
5. **Set metadata** — Priority and estimate if not already set.
|
|
36
|
+
6. **Transition** — `transition.py` to Implementing with Activate comment from `reference/comment-templates.md`.
|
|
37
|
+
7. **Verify** — Confirm state = In Progress and assignee set.
|
|
32
38
|
|
|
33
39
|
**Sequence matters:** Assign → metadata → transition. Never transition without an assignee.
|
|
34
40
|
|
|
@@ -129,31 +129,53 @@ def get_workflow_reminder(status: str) -> str | None:
|
|
|
129
129
|
return reminders.get(status)
|
|
130
130
|
|
|
131
131
|
|
|
132
|
-
def
|
|
133
|
-
"""
|
|
134
|
-
graph_script = Path('.claude/skills/flydocs-context-graph/scripts/graph_context.py')
|
|
135
|
-
if not graph_script.exists():
|
|
136
|
-
return None
|
|
132
|
+
def get_orientation_context() -> str | None:
|
|
133
|
+
"""Read lightweight orientation files directly (no subprocess).
|
|
137
134
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
cmd.extend(['--branch', branch])
|
|
135
|
+
Replaces the old get_graph_context() which shelled out to graph_context.py.
|
|
136
|
+
graph_context.py still exists for manual use — we just don't call it from
|
|
137
|
+
the prompt hook anymore.
|
|
138
|
+
"""
|
|
139
|
+
parts = []
|
|
144
140
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
141
|
+
# 1. Previous session continuity
|
|
142
|
+
summary_file = Path('.flydocs/session/last-summary.json')
|
|
143
|
+
if summary_file.exists():
|
|
144
|
+
try:
|
|
145
|
+
data = json.loads(summary_file.read_text())
|
|
146
|
+
pending = data.get('pending', [])
|
|
147
|
+
blockers = data.get('blockers', [])
|
|
148
|
+
issues = data.get('issues', [])
|
|
149
|
+
bits = []
|
|
150
|
+
if issues:
|
|
151
|
+
bits.append(f'issues={",".join(issues)}')
|
|
152
|
+
if pending:
|
|
153
|
+
bits.append(f'pending={len(pending)}')
|
|
154
|
+
if blockers:
|
|
155
|
+
bits.append(f'blockers={len(blockers)}')
|
|
156
|
+
if bits:
|
|
157
|
+
parts.append(f'Last session: {", ".join(bits)}')
|
|
158
|
+
except (json.JSONDecodeError, OSError, IOError):
|
|
159
|
+
pass
|
|
155
160
|
|
|
156
|
-
|
|
161
|
+
# 2. Product context (first ~10 lines)
|
|
162
|
+
project_file = Path('flydocs/context/project.md')
|
|
163
|
+
if project_file.exists():
|
|
164
|
+
try:
|
|
165
|
+
lines = project_file.read_text().splitlines()[:10]
|
|
166
|
+
# Extract title line (first non-empty, non-heading-marker line)
|
|
167
|
+
for line in lines:
|
|
168
|
+
stripped = line.strip().lstrip('#').strip()
|
|
169
|
+
if stripped:
|
|
170
|
+
parts.append(f'Product: {stripped}')
|
|
171
|
+
break
|
|
172
|
+
except (OSError, IOError):
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
if not parts:
|
|
176
|
+
return None
|
|
177
|
+
|
|
178
|
+
return ' | '.join(parts)
|
|
157
179
|
|
|
158
180
|
|
|
159
181
|
def get_flydocs_version() -> str | None:
|
|
@@ -327,11 +349,11 @@ def main() -> None:
|
|
|
327
349
|
debug_log(f'Outputting plain text context: {context}')
|
|
328
350
|
print(context)
|
|
329
351
|
|
|
330
|
-
#
|
|
331
|
-
|
|
332
|
-
if
|
|
333
|
-
debug_log(f'
|
|
334
|
-
print(
|
|
352
|
+
# Orientation context (lightweight file reads, no subprocess)
|
|
353
|
+
orientation = get_orientation_context()
|
|
354
|
+
if orientation:
|
|
355
|
+
debug_log(f'Orientation context: {orientation[:100]}...')
|
|
356
|
+
print(orientation)
|
|
335
357
|
|
|
336
358
|
debug_log('=== Hook completed successfully ===')
|
|
337
359
|
sys.exit(0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.6.0-alpha.
|
|
1
|
+
0.6.0-alpha.13
|
package/template/manifest.json
CHANGED