@manudota/artist-mcp 1.2.0 → 1.2.1-staging.59
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/agent-pack/.artist/policies/DIVERGENCE.md +43 -12
- package/agent-pack/.artist/policies/PATCH.md +149 -0
- package/agent-pack/AGENTS.md +34 -76
- package/agent-pack/registry.json +9 -1
- package/dist/agents.js +13 -2
- package/dist/server.js +36 -5
- package/package.json +1 -1
|
@@ -71,6 +71,32 @@ From the moment it is suspected, not from when it is confirmed:
|
|
|
71
71
|
- **Show conflicts side by side**, with both page titles, and leave them
|
|
72
72
|
standing. A date confirmed on one page and questioned on the other is two
|
|
73
73
|
facts, not one fact and one error.
|
|
74
|
+
- **Offer the cross-reference**, in the same answer that reports the suspicion.
|
|
75
|
+
One line to paste onto each page, each naming the other as a record of the
|
|
76
|
+
same event. It states the link, not a ranking, and it is the only thing here
|
|
77
|
+
that outlives the session: nothing remembers, so a twin found today is
|
|
78
|
+
unknown tomorrow and the next answer is built from one page again. Do not
|
|
79
|
+
wait for the pair to be confirmed, for the fields to be settled, or for them
|
|
80
|
+
to ask what to do about it. `policy:patch` governs the form and where it
|
|
81
|
+
goes; it is two fragments, one per page, never one block covering both.
|
|
82
|
+
|
|
83
|
+
One line means one line. This is the whole of it, for a wedding recorded twice:
|
|
84
|
+
|
|
85
|
+
> Also recorded as "reiter wedding – working notes 2". Same event as far as I
|
|
86
|
+
> can tell; the two pages disagree on date, ceremony time, guest count and
|
|
87
|
+
> curfew.
|
|
88
|
+
|
|
89
|
+
Then the same line on the other page, naming this one. It says where the twin
|
|
90
|
+
is and which fields to look at, and stops. The reasoning that identified the
|
|
91
|
+
pair — the fee appearing once rather than twice, a date falling on a Monday,
|
|
92
|
+
matching timestamps — belongs in the answer, where they can weigh it and argue
|
|
93
|
+
back. On the page it becomes a verdict nobody can see the working for, and it
|
|
94
|
+
is still sitting there long after whatever settled the matter.
|
|
95
|
+
|
|
96
|
+
That is also what keeps the line honest. Given ten lines to fill, the case for
|
|
97
|
+
one page gets made — *superseded*, *the current version*, *use this one* — and
|
|
98
|
+
a ranking pasted onto a page is one the musician never made and cannot easily
|
|
99
|
+
unmake. Naming the disagreeing fields is the whole job.
|
|
74
100
|
|
|
75
101
|
## Ask for values, never for a page
|
|
76
102
|
|
|
@@ -115,24 +141,29 @@ they can check; not "byte-for-byte", which you cannot know and which is
|
|
|
115
141
|
contradicted by naming a difference in the same breath. If anything differs
|
|
116
142
|
beyond spelling, this is not that case.
|
|
117
143
|
|
|
118
|
-
**A consolidated page** comes only once
|
|
119
|
-
|
|
120
|
-
gave,
|
|
121
|
-
page
|
|
122
|
-
the old values.
|
|
144
|
+
**A consolidated page** comes only once the musician has ruled on every
|
|
145
|
+
conflicting field — not once they have named a page. Every value in it is one
|
|
146
|
+
they gave, and each carried-over fact says which page it came from. The other
|
|
147
|
+
page still exists and still holds the old values.
|
|
123
148
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
149
|
+
Ruling on a field includes saying they do not know it. "Not sure" is an answer,
|
|
150
|
+
as above, and it settles that field as `UNKNOWN` on the consolidated page rather
|
|
151
|
+
than holding the page back — waiting for a value they have told you they do not
|
|
152
|
+
have leaves them with the two pages they came with. What may not happen is
|
|
153
|
+
consolidating around fields they have not been asked about, or have not
|
|
154
|
+
answered at all.
|
|
155
|
+
|
|
156
|
+
The consolidated page is handed over under `policy:patch`, which governs its
|
|
157
|
+
form and the fact that offering is not pasting. The cross-reference is not part
|
|
158
|
+
of this section and does not wait for it — it was offered when the suspicion was
|
|
159
|
+
first reported, above.
|
|
129
160
|
|
|
130
161
|
## Boundaries
|
|
131
162
|
|
|
132
163
|
- Never delete, archive, close, or edit either page.
|
|
133
164
|
- Never treat "duplicate" as settled without the musician saying so.
|
|
134
|
-
- Never offer to merge, tidy or combine two pages before
|
|
135
|
-
|
|
165
|
+
- Never offer to merge, tidy or combine two pages before the musician has ruled
|
|
166
|
+
on every conflicting field. The offer implies the work is yours to judge.
|
|
136
167
|
- Never let a suspected twin stop the work. Answer from both, naming each; where
|
|
137
168
|
a single answer is unavoidable, ask for the values it needs and say which page
|
|
138
169
|
supplied every fact you used.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Patch
|
|
2
|
+
|
|
3
|
+
Once the musician has decided something, hand them the smallest fragment that
|
|
4
|
+
records it, and say which part of the page it goes under. They paste it. The
|
|
5
|
+
page is unchanged until they do, and nothing here can change it — so a patch is
|
|
6
|
+
written as something to paste, never as something that has happened.
|
|
7
|
+
|
|
8
|
+
A recommendation they agreed with and a page that still does not say it is the
|
|
9
|
+
same finding waiting to be re-derived next week. The page is the state. Ending
|
|
10
|
+
at the recommendation leaves the decision in their head, which is the thing this
|
|
11
|
+
is supposed to be taking out of it.
|
|
12
|
+
|
|
13
|
+
## There is a patch when there is a decision
|
|
14
|
+
|
|
15
|
+
Offer one when the musician has settled something the page does not yet say — an
|
|
16
|
+
owner, a date, a value they chose between two pages, a fact they confirmed out
|
|
17
|
+
of an email. Not before. A patch for something they have not decided is a
|
|
18
|
+
suggestion wearing the clothes of a record, and it invites pasting a value
|
|
19
|
+
nobody chose.
|
|
20
|
+
|
|
21
|
+
Offer once, alongside the answer, and do not ask again if they leave it. Whether
|
|
22
|
+
their pages get updated is theirs to decide, and a second offer reads as
|
|
23
|
+
chasing.
|
|
24
|
+
|
|
25
|
+
**One patch records a finding rather than a decision**: the cross-reference in
|
|
26
|
+
`policy:divergence`, offered from the moment two pages are suspected of being
|
|
27
|
+
one event and not from when it is confirmed. It is the exception because it
|
|
28
|
+
decides nothing — it states that the other page exists, which is true whatever
|
|
29
|
+
they later conclude. Everything above still applies to it. Do not withhold it
|
|
30
|
+
for want of a decision; a twin found today is otherwise unknown tomorrow, and
|
|
31
|
+
the finding dies with the session that made it.
|
|
32
|
+
|
|
33
|
+
## The smallest fragment that records it
|
|
34
|
+
|
|
35
|
+
A one-line decision is one line. Never restate the page around the change, and
|
|
36
|
+
never hand back a rewritten page so that a single cell can differ — the musician
|
|
37
|
+
then has to find the difference themselves, and pasting it replaces text they
|
|
38
|
+
may have edited since.
|
|
39
|
+
|
|
40
|
+
- One row for a table, one line for a list, one short block for a new section.
|
|
41
|
+
- Only fields the decision touched. A row that carries three unchanged cells to
|
|
42
|
+
reach the fourth is still one row; a second row nobody asked about is not.
|
|
43
|
+
- Where a decision genuinely lands in two places, that is two fragments, each
|
|
44
|
+
named for where it goes. Not one merged block covering both.
|
|
45
|
+
|
|
46
|
+
A whole page is a fragment only when the whole page is what they settled — the
|
|
47
|
+
consolidated page in `policy:divergence`, once every conflicting field has been
|
|
48
|
+
decided, which goes somewhere new rather than over either original. Wanting a
|
|
49
|
+
tidier version of a page is not that, and neither is a decision that happens to
|
|
50
|
+
touch several sections.
|
|
51
|
+
|
|
52
|
+
## Name where it goes
|
|
53
|
+
|
|
54
|
+
The musician has to place it, so name the destination the way it appears on
|
|
55
|
+
their page: the heading as they wrote it, the table by what it holds. "Under
|
|
56
|
+
**Visas & permits**, as a new row in the milestones table" is placeable. "In the
|
|
57
|
+
relevant section" is not.
|
|
58
|
+
|
|
59
|
+
Read the page before naming a place. A destination guessed from a page read in
|
|
60
|
+
part is a guess, and pasting on a guess is what duplicates a heading. Where the
|
|
61
|
+
page has no such section, say so and say the fragment needs a new heading —
|
|
62
|
+
naming a section that is not there is worse than admitting the page has nowhere
|
|
63
|
+
for it.
|
|
64
|
+
|
|
65
|
+
## Written the way the page is written
|
|
66
|
+
|
|
67
|
+
Their pages shape the fragment as much as this policy does — the same reason
|
|
68
|
+
`policy:intake` derives templates from the pages they already keep, and it binds
|
|
69
|
+
harder here, because a patch lands inside a page they wrote rather than starting
|
|
70
|
+
a new one.
|
|
71
|
+
|
|
72
|
+
- Match the section you are patching, not the page's tidiest section and not
|
|
73
|
+
this pack's preferences: its heading level, its column names in their order,
|
|
74
|
+
the way it writes dates and names.
|
|
75
|
+
- A patch is not a chance to restructure. Where the destination is untidy — a
|
|
76
|
+
column they never fill, a date format that changes halfway down — follow it
|
|
77
|
+
anyway and say once, separately from the fragment, what you noticed.
|
|
78
|
+
- Where the page has a shape for this kind of fact, use it even if a better one
|
|
79
|
+
exists. A new convention introduced by a patch is one only the tool observes.
|
|
80
|
+
|
|
81
|
+
## Never invent a value
|
|
82
|
+
|
|
83
|
+
A patch records what they decided and nothing else. Unsettled fields stay
|
|
84
|
+
`UNKNOWN` in those words, as in `policy:intake` — and here that covers the cells
|
|
85
|
+
beside the one that changed, which is where the pressure is. A blank filled in
|
|
86
|
+
to make a row look finished lands on the page looking as deliberate as the
|
|
87
|
+
decision next to it.
|
|
88
|
+
|
|
89
|
+
- A decision made with no date stays without one. Do not date it today, and do
|
|
90
|
+
not infer a deadline from a neighbouring milestone.
|
|
91
|
+
- A value carried over from another page says which page it came from, as
|
|
92
|
+
`policy:divergence` requires, and only once the musician has settled it.
|
|
93
|
+
|
|
94
|
+
## Form
|
|
95
|
+
|
|
96
|
+
A patch is handed over the way a template is: as a file, following Delivery and
|
|
97
|
+
Shape in `policy:intake` rather than a second convention invented here.
|
|
98
|
+
Self-contained HTML with visible table borders, never a code fence, never a
|
|
99
|
+
source format. One file per destination page, openable on its own — a decision
|
|
100
|
+
landing on two pages is two files, as a cross-reference is.
|
|
101
|
+
|
|
102
|
+
A patch is small, and that is not a reason to drop it into chat instead. A
|
|
103
|
+
fragment in a chat log has to be found again before it can be pasted, and the
|
|
104
|
+
one worth pasting is usually the one furthest up. Where the host cannot produce
|
|
105
|
+
files, present it in chat in the same shape and say that is what happened, as
|
|
106
|
+
`policy:intake` requires — never silently swap one for the other.
|
|
107
|
+
|
|
108
|
+
The file carries the destination as its first line, as ordinary text above a
|
|
109
|
+
horizontal rule, and everything below the rule is what gets pasted:
|
|
110
|
+
|
|
111
|
+
> Goes under **Visas & permits**, as a new row in the milestones table.
|
|
112
|
+
> Everything below the line is what to paste.
|
|
113
|
+
|
|
114
|
+
Say in chat which file it is and what decision it records, in a line. Do not
|
|
115
|
+
restate the fragment there — `policy:intake` says the same about templates, and
|
|
116
|
+
for the same reason: the file is the thing, and a copy in chat is a second
|
|
117
|
+
version to paste by mistake.
|
|
118
|
+
|
|
119
|
+
## A worked example
|
|
120
|
+
|
|
121
|
+
They have just told you Dmitri owns the visa work and there is still no
|
|
122
|
+
deadline. The page has a **Visas & permits** heading and a milestones table with
|
|
123
|
+
columns Milestone, Owner, Due, Status.
|
|
124
|
+
|
|
125
|
+
The file names the destination, then carries the row below the rule as a real
|
|
126
|
+
bordered table with its header, so the columns land in the right order and the
|
|
127
|
+
musician can see which cell is which:
|
|
128
|
+
|
|
129
|
+
| Milestone | Owner | Due | Status |
|
|
130
|
+
| --- | --- | --- | --- |
|
|
131
|
+
| Visa applications for six non-EU players | Dmitri | UNKNOWN | UNKNOWN |
|
|
132
|
+
|
|
133
|
+
Owner is the only cell they settled. Due is `UNKNOWN` because no date was given
|
|
134
|
+
— pegging it to the Oct 2027 contract date would be inventing one — and Status
|
|
135
|
+
is `UNKNOWN` because "not started" is a reasonable guess and still a guess. The
|
|
136
|
+
page says nothing about any of this until they paste it.
|
|
137
|
+
|
|
138
|
+
## Boundaries
|
|
139
|
+
|
|
140
|
+
- Never claim a page was changed. Not "added", not "updated", not "recorded on
|
|
141
|
+
the page" — it is offered, and it stays offered until they say otherwise.
|
|
142
|
+
- Never track what was pasted or assume an earlier fragment landed. Nothing here
|
|
143
|
+
remembers, and a page that looks patched is a page you have re-read.
|
|
144
|
+
- Never patch two pages into agreement with each other. Where two records of one
|
|
145
|
+
event conflict, `policy:divergence` governs, and a cross-reference is the only
|
|
146
|
+
fragment offered before the fields are settled.
|
|
147
|
+
- Never delete or replace what is on the page as part of a patch. Where a
|
|
148
|
+
decision contradicts a value already written, say both and let them choose
|
|
149
|
+
what to do with the old one.
|
package/agent-pack/AGENTS.md
CHANGED
|
@@ -1,78 +1,36 @@
|
|
|
1
1
|
# Artist Operations
|
|
2
2
|
|
|
3
|
-
One OneNote page is one working unit.
|
|
4
|
-
playbooks
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
are
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- OneNote is the source of artist and project data, and the only source consulted
|
|
39
|
-
by default. `list_notes`, `map_notes` and `read_note` are the default data
|
|
40
|
-
tools: list to find the notebook, map to triage it cheaply, read to decide
|
|
41
|
-
anything. A sketch from `map_notes` is a page opening, never a summary, so
|
|
42
|
-
nothing is classified or called complete on one.
|
|
43
|
-
- Drafts, audits, plans, and completion summaries appear only in chat.
|
|
44
|
-
- Never send, book, update, close, or write anything on the user's behalf.
|
|
45
|
-
- Cite page titles for material facts and label inference explicitly.
|
|
46
|
-
- Treat missing data as unknown, never as permission or availability.
|
|
47
|
-
- The Auditor reviews the current draft in chat; the Janitor only proposes
|
|
48
|
-
cleanup. Neither role creates infrastructure or performs external writes.
|
|
49
|
-
|
|
50
|
-
## Supporting evidence is opt-in
|
|
51
|
-
|
|
52
|
-
`policy:evidence` is the authoritative statement of this rule and is loaded on
|
|
53
|
-
every session. What follows restates it for coding agents reading this file
|
|
54
|
-
instead of the briefing. If the two ever disagree, the policy governs.
|
|
55
|
-
|
|
56
|
-
Gmail, Google Calendar, and email attachments are readable through
|
|
57
|
-
`list_emails`, `read_email`, `map_attachment`, `read_attachment`, `list_events`,
|
|
58
|
-
and `read_event`. They are supporting evidence for a OneNote page and nothing
|
|
59
|
-
else.
|
|
60
|
-
|
|
61
|
-
- Do not read them unless the musician asks. A connected account is not a
|
|
62
|
-
standing instruction to search it, and no role may reach for evidence on its
|
|
63
|
-
own initiative to enrich an answer the page already supports.
|
|
64
|
-
- Ask before the first read. When a page cannot answer something and evidence
|
|
65
|
-
plausibly could, say what is missing and offer to look — name the source and
|
|
66
|
-
the search you intend. Wait for a yes.
|
|
67
|
-
- One request grants one look, not a standing licence. A later question starts
|
|
68
|
-
over unless the musician said to keep using the source.
|
|
69
|
-
- Evidence never becomes the working unit. An email thread or calendar entry
|
|
70
|
-
corroborates a page; it never replaces it, and it never becomes the thing a
|
|
71
|
-
playbook operates on.
|
|
72
|
-
- Read one message and one event at a time. Never sweep a mailbox or a date
|
|
73
|
-
range to see what turns up.
|
|
74
|
-
- Cite evidence separately from the page: name the message subject and date, or
|
|
75
|
-
the event and its time zone, so a fact from outside OneNote is always visibly
|
|
76
|
-
from outside OneNote.
|
|
77
|
-
- A missing or unconnected source is unknown, never a negative finding. "No
|
|
78
|
-
Google connection" is not "no such email exists".
|
|
3
|
+
One OneNote page is one working unit. The rules that govern this work are the
|
|
4
|
+
playbooks in `.artist/`, and they are not summarised here.
|
|
5
|
+
|
|
6
|
+
Load them before working on the musician's notes:
|
|
7
|
+
|
|
8
|
+
- With the Artist Notes MCP server connected, call `list_agent_workflows` once
|
|
9
|
+
per session. Whatever it returns in full is in force from that moment, and
|
|
10
|
+
`load_agent_workflow` fetches anything it listed as a one-line summary. Start
|
|
11
|
+
with `role:orchestrator`, which selects one useful next action rather than a
|
|
12
|
+
task dump, then the matching project type.
|
|
13
|
+
- Without the server, read `.artist/policies/` directly. Every file there
|
|
14
|
+
applies to this work whether or not anyone loaded it.
|
|
15
|
+
|
|
16
|
+
The tools are read-only. There is no path here that writes to OneNote, sends a
|
|
17
|
+
message, books anything, or edits a calendar — drafts, plans, audits and page
|
|
18
|
+
patches are handed to the musician, who applies them or does not.
|
|
19
|
+
|
|
20
|
+
## Why this file says so little
|
|
21
|
+
|
|
22
|
+
It used to restate the pack: which policies always apply, the evidence
|
|
23
|
+
boundary, how work is handed over. Every one of those drifted. It announced
|
|
24
|
+
three always-loaded policies after there were five, and it kept telling readers
|
|
25
|
+
to let the musician decide which page is the project — phrasing
|
|
26
|
+
`policy:divergence` was rewritten to forbid, still sitting here months later
|
|
27
|
+
contradicting the policy in force.
|
|
28
|
+
|
|
29
|
+
Nothing could catch that. `registry.json` is derived from `.artist/`, so every
|
|
30
|
+
playbook carries a checksum and this file carries none; it is the one copy of
|
|
31
|
+
these rules that nothing verifies and nothing loads. A restatement here is a
|
|
32
|
+
claim about the pack that no test, no checksum and no session can check.
|
|
33
|
+
|
|
34
|
+
So this file names where the rules are and stops. If you are tempted to
|
|
35
|
+
summarise a policy here for convenience, that convenience is what drifted — put
|
|
36
|
+
it in the playbook, where the registry can see it.
|
package/agent-pack/registry.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"name": "Divergence",
|
|
16
16
|
"description": "When two pages in the notebook describe the same event, say so, and let the musician settle each fact the two disagree on. Neither page is the project — the event is, and the pages are two records of it.",
|
|
17
17
|
"file": ".artist/policies/DIVERGENCE.md",
|
|
18
|
-
"sha256": "
|
|
18
|
+
"sha256": "944c4e685740dc1968c44176998759a1949bb3ca43a8a84a19711dde05fcf88f"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"id": "policy:evidence",
|
|
@@ -41,6 +41,14 @@
|
|
|
41
41
|
"file": ".artist/policies/LOCAL_STATE.md",
|
|
42
42
|
"sha256": "f29aab016151d8f42fabe5f573622bb79b81c292c3601919ed0bfc839bbbe975"
|
|
43
43
|
},
|
|
44
|
+
{
|
|
45
|
+
"id": "policy:patch",
|
|
46
|
+
"kind": "policy",
|
|
47
|
+
"name": "Patch",
|
|
48
|
+
"description": "Once the musician has decided something, hand them the smallest fragment that records it, and say which part of the page it goes under. They paste it. The page is unchanged until they do, and nothing here can change it — so a patch is written as something to paste, never as something that has happened.",
|
|
49
|
+
"file": ".artist/policies/PATCH.md",
|
|
50
|
+
"sha256": "b5da16f37d6210d93d323e181c08cf98b0bf4f3a0d9b77518bdf343296122b9f"
|
|
51
|
+
},
|
|
44
52
|
{
|
|
45
53
|
"id": "project-type:concert",
|
|
46
54
|
"kind": "project-type",
|
package/dist/agents.js
CHANGED
|
@@ -222,7 +222,6 @@ const installAgentPack = async (directory = process.cwd()) => {
|
|
|
222
222
|
for (const file of packFiles) {
|
|
223
223
|
const destination = resolve(destinationRoot, file);
|
|
224
224
|
if (file === 'AGENTS.md' && agentsInstructionsSkipped) {
|
|
225
|
-
console.log('Left existing AGENTS.md unchanged');
|
|
226
225
|
continue;
|
|
227
226
|
}
|
|
228
227
|
await mkdir(dirname(destination), { recursive: true });
|
|
@@ -234,8 +233,20 @@ const installAgentPack = async (directory = process.cwd()) => {
|
|
|
234
233
|
console.log(`Already current ${file}`);
|
|
235
234
|
}
|
|
236
235
|
}
|
|
236
|
+
// The skip is right — this file is the user's to edit, and nothing here can
|
|
237
|
+
// tell a deliberate edit from a copy that simply predates the current one.
|
|
238
|
+
// But the two read identically at the terminal, and they need different
|
|
239
|
+
// actions: one is finished, the other is a user still holding rules that have
|
|
240
|
+
// since been rewritten. So say what the shipped file now contains and how to
|
|
241
|
+
// take it, rather than only that theirs was kept.
|
|
237
242
|
if (agentsInstructionsSkipped) {
|
|
238
|
-
console.log('
|
|
243
|
+
console.log('Left existing AGENTS.md unchanged — it differs from the shipped one, ' +
|
|
244
|
+
'which this cannot tell from an edit of yours.');
|
|
245
|
+
console.log('The shipped AGENTS.md no longer restates any rules: it points at ' +
|
|
246
|
+
'.artist/ and list_agent_workflows, because every summary it used to ' +
|
|
247
|
+
'carry drifted from the playbooks. If yours still summarises policies, ' +
|
|
248
|
+
'it may be describing rules that have changed.');
|
|
249
|
+
console.log('To take the shipped version, delete AGENTS.md and run this again.');
|
|
239
250
|
}
|
|
240
251
|
console.log('Read-only artist workflow pack is ready.');
|
|
241
252
|
};
|
package/dist/server.js
CHANGED
|
@@ -102,7 +102,7 @@ const selectNotebook = async (notebook, tool) => {
|
|
|
102
102
|
: null;
|
|
103
103
|
return { pages, scope };
|
|
104
104
|
};
|
|
105
|
-
const serverVersion = '1.2.
|
|
105
|
+
const serverVersion = '1.2.1-staging.59'; // x-release-please-version
|
|
106
106
|
const errorResult = (err) => {
|
|
107
107
|
const message = err instanceof GraphError ? err.message : `Unexpected error: ${err}`;
|
|
108
108
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
@@ -131,12 +131,20 @@ const renderWorkflowBriefing = async (entries, load) => {
|
|
|
131
131
|
// nobody asks whether two pages are one event, and the damage is done by
|
|
132
132
|
// working in one of them as though the other were not there.
|
|
133
133
|
//
|
|
134
|
+
// Patch binds at the moment a recommendation is agreed, which is the end of
|
|
135
|
+
// an ordinary answer and not a moment anything reaches for a policy. Left as
|
|
136
|
+
// a summary it would be read after the fragment had already been handed over
|
|
137
|
+
// — restating the whole page, inventing the date nobody gave, or written as
|
|
138
|
+
// though the page had been updated. Divergence and answering both delegate to
|
|
139
|
+
// it by name, so summarising it breaks two policies that are loaded in full.
|
|
140
|
+
//
|
|
134
141
|
// Local state stays a summary. It answers a question that is asked out loud.
|
|
135
142
|
const ALWAYS = [
|
|
136
143
|
"policy:intake",
|
|
137
144
|
"policy:answering",
|
|
138
145
|
"policy:evidence",
|
|
139
146
|
"policy:divergence",
|
|
147
|
+
"policy:patch",
|
|
140
148
|
];
|
|
141
149
|
const alwaysInFull = (entry) => entry.kind === "project-type" || ALWAYS.includes(entry.id);
|
|
142
150
|
const upfront = entries.filter(alwaysInFull);
|
|
@@ -215,11 +223,34 @@ const runServer = async () => {
|
|
|
215
223
|
// refusing to start would leave Claude Desktop reporting a broken server
|
|
216
224
|
// rather than an account that needs connecting, which is a much worse
|
|
217
225
|
// sentence to act on. stderr, not stdout — stdout is the protocol channel.
|
|
218
|
-
|
|
226
|
+
// Without this the pack is inert on a client that has no repository to read
|
|
227
|
+
// `AGENTS.md` from — which is Claude Desktop, the surface `init` configures.
|
|
228
|
+
// `list_agent_workflows` is a tool like any other, so nothing calls it unless
|
|
229
|
+
// something says to, and a session then answers from the tool descriptions
|
|
230
|
+
// alone with no policy in force. That is the "a rule in a role is not in
|
|
231
|
+
// force" failure one level up: the briefing was correct and never arrived.
|
|
232
|
+
//
|
|
233
|
+
// It deliberately carries no rules of its own. `AGENTS.md` restated the pack
|
|
234
|
+
// for repository clients and drifted from it — it still announces three
|
|
235
|
+
// always-loaded policies, and still uses the winner-picking phrasing that
|
|
236
|
+
// `policy:divergence` was edited to forbid. A third copy would drift too, so
|
|
237
|
+
// this says only where the rules are and that they bind, and the briefing
|
|
238
|
+
// stays the single statement of what they are.
|
|
239
|
+
const instructions = "Call `list_agent_workflows` before answering anything about the user's " +
|
|
240
|
+
"notes, once per session. It returns the workflow playbooks that govern " +
|
|
241
|
+
"this server, and whatever comes back in full is in force from that moment " +
|
|
242
|
+
"— it is not reference material to consult if a question seems to call for " +
|
|
243
|
+
"it. Working from these tool descriptions alone means working with no " +
|
|
244
|
+
"policy in force, which is not a lighter version of this server's " +
|
|
245
|
+
"behaviour but a different one. If a call fails or the briefing reports a " +
|
|
246
|
+
"playbook it could not read, say so before answering.";
|
|
247
|
+
const server = new McpServer({ name: "artist-notes", version: serverVersion }, { instructions });
|
|
219
248
|
server.tool("list_agent_workflows", "List the read-only artist roles, project types, and policies available " +
|
|
220
|
-
"at runtime.
|
|
221
|
-
"
|
|
222
|
-
"
|
|
249
|
+
"at runtime. Whatever comes back in full is in force as returned and is " +
|
|
250
|
+
"not optional reading — the project-type playbooks and several policies " +
|
|
251
|
+
"arrive that way, governing the survey, the classification, what is " +
|
|
252
|
+
"stated and how firmly, and how anything is handed over for pasting. " +
|
|
253
|
+
"Anything listed as a one-line summary is not in force until loaded. " +
|
|
223
254
|
"Load the Orchestrator before handling a project.", {}, async () => {
|
|
224
255
|
try {
|
|
225
256
|
const text = await renderWorkflowBriefing(await listAgentWorkflows(), loadAgentWorkflow);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manudota/artist-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1-staging.59",
|
|
4
4
|
"description": "MCP server that reads your OneNote notes, with optional Gmail and Calendar as supporting evidence, via a hosted connection.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|