dsh-plugin-jules 0.1.0 → 0.1.1
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 +35 -7
- package/lib/index.d.ts +17 -2
- package/lib/index.js +48 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# dsh-plugin-jules
|
|
2
2
|
|
|
3
3
|
[](https://github.com/rbviz/dsh-plugin-jules/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-plugin-jules)
|
|
4
5
|
|
|
5
6
|
Google [Jules](https://jules.google.com) as a [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) capability.
|
|
6
7
|
|
|
@@ -33,22 +34,49 @@ It talks to the documented Jules v1alpha REST API directly and has **no runtime
|
|
|
33
34
|
|
|
34
35
|
## Install
|
|
35
36
|
|
|
36
|
-
The package declares `dsh.bundle`, so it installs as an ordinary profile bundle.
|
|
37
|
-
|
|
37
|
+
The package declares `dsh.bundle`, so it installs as an ordinary profile bundle. `dsh plugin`
|
|
38
|
+
forwards its arguments to pnpm in the profile directory, so `add`, `update`, and `remove` are the
|
|
39
|
+
ordinary verbs. If the profile does not exist yet, the first command creates it.
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
node scripts/link-dsh-deps.mjs # once, and after changing peerDependencies
|
|
41
|
-
npm run build # compiles src/ to lib/
|
|
41
|
+
### From npm
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
```sh
|
|
44
|
+
dsh plugin --profile <your-profile> add dsh-plugin-jules
|
|
44
45
|
```
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
Nothing compiles on your machine: `lib/` ships prebuilt, so there is no `prepare` script and no
|
|
48
|
+
`allowBuilds` permission to grant. The `@deepseek-ai/*` peer dependencies come from the harness
|
|
49
|
+
installation's own module fallback, so there is nothing else to install — this plugin adds no
|
|
50
|
+
runtime dependencies of its own.
|
|
51
|
+
|
|
52
|
+
**Restart the harness.** A running process keeps the bundle set it started with; an `add`, `update`,
|
|
53
|
+
or `remove` is picked up at the next start. Then confirm the layer composed:
|
|
47
54
|
|
|
48
55
|
```sh
|
|
49
56
|
dsh --profile <your-profile> --dump-config | grep -A 3 'id: jules'
|
|
50
57
|
```
|
|
51
58
|
|
|
59
|
+
Upgrading and removing are the same passthrough, each followed by the same restart:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
dsh plugin --profile <your-profile> update dsh-plugin-jules
|
|
63
|
+
dsh plugin --profile <your-profile> remove dsh-plugin-jules
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### From a checkout
|
|
67
|
+
|
|
68
|
+
To run your own build of the sources:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
node scripts/link-dsh-deps.mjs # once, and after changing peerDependencies
|
|
72
|
+
npm run build # compiles src/ to lib/
|
|
73
|
+
|
|
74
|
+
dsh plugin --profile <your-profile> add /path/to/jules-plugin
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The path spec is anchored to the directory you invoke from, so `add .` works from the checkout root.
|
|
78
|
+
Restart, then confirm as above.
|
|
79
|
+
|
|
52
80
|
### From GitHub
|
|
53
81
|
|
|
54
82
|
```sh
|
package/lib/index.d.ts
CHANGED
|
@@ -97,8 +97,23 @@ export interface Config {
|
|
|
97
97
|
}
|
|
98
98
|
/** Schemastery configuration for loader defaults and the generated config catalog. */
|
|
99
99
|
export declare const Config: z<Config>;
|
|
100
|
-
/**
|
|
101
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Model guidance for the Jules tool family.
|
|
102
|
+
*
|
|
103
|
+
* Written as an instruction and scoped to policy, like every in-box tool
|
|
104
|
+
* section: what each tool does is the tool description's job, so this says when
|
|
105
|
+
* to reach for the family and what not to do with it. The earlier draft opened
|
|
106
|
+
* by describing Jules instead, and spent most of its length restating the tool
|
|
107
|
+
* descriptions.
|
|
108
|
+
*
|
|
109
|
+
* The waiting half is conditional because `enableWatch: false` removes
|
|
110
|
+
* `jules_watch` from the composition entirely, and guidance naming a tool the
|
|
111
|
+
* model cannot call is worse than guidance that says less. `tool:web_search`
|
|
112
|
+
* sets the same precedent for its optional `web_fetch` companion.
|
|
113
|
+
* @param watchAvailable - whether `jules_watch` is registered in this scope.
|
|
114
|
+
* @returns the section text.
|
|
115
|
+
*/
|
|
116
|
+
export declare function julesGuidance(watchAvailable: boolean): string;
|
|
102
117
|
/**
|
|
103
118
|
* Register the Jules tool family and its model guidance.
|
|
104
119
|
* @param ctx - plugin context supplying the tool registry and credential seam.
|
package/lib/index.js
CHANGED
|
@@ -80,22 +80,39 @@ export const Config = z.object({
|
|
|
80
80
|
retryBaseDelayMs: z.number().step(1).min(1).default(DEFAULT_RETRY_BASE_DELAY_MS),
|
|
81
81
|
retryMaxDelayMs: z.number().step(1).min(1).default(DEFAULT_RETRY_MAX_DELAY_MS),
|
|
82
82
|
});
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Model guidance for the Jules tool family.
|
|
85
|
+
*
|
|
86
|
+
* Written as an instruction and scoped to policy, like every in-box tool
|
|
87
|
+
* section: what each tool does is the tool description's job, so this says when
|
|
88
|
+
* to reach for the family and what not to do with it. The earlier draft opened
|
|
89
|
+
* by describing Jules instead, and spent most of its length restating the tool
|
|
90
|
+
* descriptions.
|
|
91
|
+
*
|
|
92
|
+
* The waiting half is conditional because `enableWatch: false` removes
|
|
93
|
+
* `jules_watch` from the composition entirely, and guidance naming a tool the
|
|
94
|
+
* model cannot call is worse than guidance that says less. `tool:web_search`
|
|
95
|
+
* sets the same precedent for its optional `web_fetch` companion.
|
|
96
|
+
* @param watchAvailable - whether `jules_watch` is registered in this scope.
|
|
97
|
+
* @returns the section text.
|
|
98
|
+
*/
|
|
99
|
+
export function julesGuidance(watchAvailable) {
|
|
100
|
+
const waiting = watchAvailable
|
|
101
|
+
? 'jules_watch registers a background watch and returns a job id; then END YOUR TURN, and the harness wakes you with a notice when '
|
|
102
|
+
+ 'the session finishes, fails, needs a plan decision, or posts a message. DO NOT POLL: a status call that returns what you '
|
|
103
|
+
+ 'already saw has cost a turn and bought nothing. jules_wait holds that same wait open in the foreground, so reach for it only '
|
|
104
|
+
+ 'when nothing else can proceed meanwhile.'
|
|
105
|
+
: 'jules_wait holds the turn open until the session finishes, fails, needs a plan decision, or posts a message. DO NOT POLL: a '
|
|
106
|
+
+ 'status call that returns what you already saw has cost a turn and bought nothing.';
|
|
107
|
+
return 'Use the jules_* tools to delegate a coding task to Jules, a remote agent that works asynchronously in the cloud on its own '
|
|
108
|
+
+ 'clone of a repository, so the session keeps working after your turn ends. jules_create returns a session id immediately. '
|
|
109
|
+
+ waiting + ' '
|
|
110
|
+
+ 'jules_status is for confirming an action you just took, following up a watch notice, or answering the user about a session — '
|
|
111
|
+
+ 'never for waiting. '
|
|
112
|
+
+ 'Ask for requirePlanApproval when a task will change existing code, then read the plan before jules_approve_plan releases it. '
|
|
113
|
+
+ 'Prefer finishing small work here; delegate a task that is long, independent, or better done in a clean checkout, and do not '
|
|
114
|
+
+ 'open several sessions for one task because the service throttles concurrent creation.';
|
|
115
|
+
}
|
|
99
116
|
/**
|
|
100
117
|
* Complete every optional field and reject combinations the schema cannot express.
|
|
101
118
|
* @param config - the validated configuration section.
|
|
@@ -225,10 +242,23 @@ export function apply(ctx, config) {
|
|
|
225
242
|
// positions owned by particular tool families, and Jules is the same kind of
|
|
226
243
|
// thing a subagent is — a delegation target — so its guidance belongs beside
|
|
227
244
|
// those instructions rather than in an unrelated slot. Equal orders fall back
|
|
228
|
-
// to name order, which is stable.
|
|
245
|
+
// to name order, which is stable. The system-prompt README documents the
|
|
246
|
+
// alternative for out-of-tree packages — "external contributions may use any
|
|
247
|
+
// finite order" — but a borrowed allocated position cannot collide with a
|
|
248
|
+
// future in-box slot, while a hand-picked number can.
|
|
229
249
|
order: ctx.systemPrompt.getSectionOrder('TOOL_SUBAGENT'),
|
|
230
250
|
// Evaluated per assembly, so the orphan note appears the moment the plugin
|
|
231
251
|
// loads after a restart and disappears as watches are re-armed.
|
|
232
|
-
|
|
252
|
+
//
|
|
253
|
+
// Empty text is dropped before rendering, so an agent whose scope excludes
|
|
254
|
+
// the family is never told about tools it cannot call — the same gate
|
|
255
|
+
// `tool:read` and `tool:subagent` apply. `jules_create` stands in for the
|
|
256
|
+
// family: it registers unconditionally and is the entry point this guidance
|
|
257
|
+
// is about. Gating ahead of the note also stops an agent without Jules tools
|
|
258
|
+
// from being handed a list of watches to re-arm.
|
|
259
|
+
text: ({ scope }) => ctx.tools.get('jules_create', scope) === undefined
|
|
260
|
+
? ''
|
|
261
|
+
: julesGuidance(ctx.tools.get('jules_watch', scope) !== undefined)
|
|
262
|
+
+ orphanNote((journal?.pending() ?? []).filter(record => !live.has(record.session))),
|
|
233
263
|
});
|
|
234
264
|
}
|