@method-ai-hq/sdk 0.0.0-stage → 0.14.2
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/LICENSE +21 -0
- package/README.md +23 -2
- package/dist/packages/contracts/src/identity.d.ts +16 -0
- package/dist/packages/contracts/src/identity.js +41 -0
- package/dist/packages/contracts/src/method-package.d.ts +71 -0
- package/dist/packages/contracts/src/method-package.js +22 -0
- package/dist/packages/method-document/src/conversion-report.d.ts +138 -0
- package/dist/packages/method-document/src/conversion-report.js +23 -0
- package/dist/packages/sdk/examples/daily-briefing/README.md +31 -0
- package/dist/packages/sdk/examples/daily-briefing/TASK.md +3 -0
- package/dist/packages/sdk/examples/daily-briefing/approved-report.md +138 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_artifacts.py +39 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_check_inputs.py +47 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_files.py +31 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_manifest.py +23 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_markdown.py +67 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_progress.py +18 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_render.py +71 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_sessions.py +37 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_times.py +158 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_validation.py +101 -0
- package/dist/packages/sdk/examples/daily-briefing/briefing_website.py +215 -0
- package/dist/packages/sdk/examples/daily-briefing/checks.json +19 -0
- package/dist/packages/sdk/examples/daily-briefing/daily-briefing.method +158 -0
- package/dist/packages/sdk/examples/daily-briefing/inputs.json +1 -0
- package/dist/packages/sdk/examples/daily-briefing/package-lock.json +10 -0
- package/dist/packages/sdk/examples/daily-briefing/package.json +4 -0
- package/dist/packages/sdk/examples/daily-briefing/pyproject.toml +8 -0
- package/dist/packages/sdk/examples/daily-briefing/reader/reader.css +35 -0
- package/dist/packages/sdk/examples/daily-briefing/reader/reader.js +42 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/context.json +1 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/documents/document-001.md +219 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/media.json +1 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/metadata/documents.json +39 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0001.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0002.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0003.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0004.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0005.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0006.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0007.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0008.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0009.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0010.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0011.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0012.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0013.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0014.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0015.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0016.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0017.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0018.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0019.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0020.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0021.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0022.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0023.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0024.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0025.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0026.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0027.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0028.json +49 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/sessions.json +1 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/timeline.jsonl +28 -0
- package/dist/packages/sdk/examples/daily-briefing/sample/untimed.jsonl +0 -0
- package/dist/packages/sdk/examples/daily-briefing/sample-output.zip +0 -0
- package/dist/packages/sdk/examples/daily-briefing/sample-report.md +51 -0
- package/dist/packages/sdk/examples/daily-briefing/uv.lock +128 -0
- package/dist/packages/sdk/examples/daily-briefing/vendor/marked-LICENSE.md +44 -0
- package/dist/packages/sdk/examples/daily-briefing/vendor/marked.mjs +77 -0
- package/dist/packages/sdk/examples/files.json +126 -0
- package/dist/packages/sdk/examples/message-routing/README.md +23 -0
- package/dist/packages/sdk/examples/message-routing/TASK.md +5 -0
- package/dist/packages/sdk/examples/message-routing/choose-destination.mjs +10 -0
- package/dist/packages/sdk/examples/message-routing/create-ticket.mjs +15 -0
- package/dist/packages/sdk/examples/message-routing/inputs.json +1 -0
- package/dist/packages/sdk/examples/message-routing/message-routing.method +45 -0
- package/dist/packages/sdk/examples/message-routing/result.fixture.json +6 -0
- package/dist/packages/sdk/examples/message-routing/routing.mjs +29 -0
- package/dist/packages/sdk/examples/message-routing/routing.test.mjs +27 -0
- package/dist/packages/sdk/examples/message-routing/ticket.method +88 -0
- package/dist/packages/sdk/examples/message-routing/ticket.test.mjs +64 -0
- package/dist/packages/sdk/examples/notes-summary/README.md +23 -0
- package/dist/packages/sdk/examples/notes-summary/TASK.md +3 -0
- package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/case.json +36 -0
- package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/examples.json +16 -0
- package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/files/0 +10 -0
- package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/recording.json +195 -0
- package/dist/packages/sdk/examples/notes-summary/notes/2026-10-05-standup.md +4 -0
- package/dist/packages/sdk/examples/notes-summary/notes/2026-10-07-planning.md +3 -0
- package/dist/packages/sdk/examples/notes-summary/notes-summary.method +54 -0
- package/dist/packages/sdk/examples/notes-summary/out/.keep +0 -0
- package/dist/packages/sdk/examples/notes-summary/read-notes.mjs +4 -0
- package/dist/packages/sdk/examples/notes-summary/save.mjs +7 -0
- package/dist/packages/sdk/examples/outbound-management/README.md +119 -0
- package/dist/packages/sdk/examples/outbound-management/TASK.md +5 -0
- package/dist/packages/sdk/examples/outbound-management/check_plan.py +16 -0
- package/dist/packages/sdk/examples/outbound-management/check_sources.py +14 -0
- package/dist/packages/sdk/examples/outbound-management/crm.py +153 -0
- package/dist/packages/sdk/examples/outbound-management/crm_test.py +141 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/README.md +15 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/crm.json +54 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/day-1/messages.json +29 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/day-2/messages.json +38 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/observations.json +12 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/plan.json +69 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/receipt.json +1 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/state.json +99 -0
- package/dist/packages/sdk/examples/outbound-management/fixtures/tasks.md +16 -0
- package/dist/packages/sdk/examples/outbound-management/inputs.json +4 -0
- package/dist/packages/sdk/examples/outbound-management/outbound.method +277 -0
- package/dist/packages/sdk/examples/outbound-management/read_crm.py +4 -0
- package/dist/packages/sdk/examples/outbound-management/save_day.py +4 -0
- package/dist/packages/sdk/examples/outbound-management/starter/crm.json +11 -0
- package/dist/packages/sdk/examples/social-briefing/README.md +41 -0
- package/dist/packages/sdk/examples/social-briefing/TASK.md +5 -0
- package/dist/packages/sdk/examples/social-briefing/inputs.json +5 -0
- package/dist/packages/sdk/examples/social-briefing/result.fixture.json +14 -0
- package/dist/packages/sdk/examples/social-briefing/social-briefing.method +110 -0
- package/dist/packages/sdk/examples/support-triage/README.md +77 -0
- package/dist/packages/sdk/examples/support-triage/TASK.md +3 -0
- package/dist/packages/sdk/examples/support-triage/cases/double-charge-to-billing/case.json +40 -0
- package/dist/packages/sdk/examples/support-triage/cases/double-charge-to-billing/recording.json +460 -0
- package/dist/packages/sdk/examples/support-triage/fake-helpdesk.mjs +38 -0
- package/dist/packages/sdk/examples/support-triage/helpdesk.mjs +33 -0
- package/dist/packages/sdk/examples/support-triage/inputs.json +1 -0
- package/dist/packages/sdk/examples/support-triage/read-ticket.mjs +8 -0
- package/dist/packages/sdk/examples/support-triage/route.mjs +4 -0
- package/dist/packages/sdk/examples/support-triage/sample-tickets.json +5 -0
- package/dist/packages/sdk/examples/support-triage/set-ticket.mjs +9 -0
- package/dist/packages/sdk/examples/support-triage/support-triage.method +165 -0
- package/dist/packages/sdk/examples/support-triage/triage.mjs +38 -0
- package/dist/packages/sdk/examples/support-triage/triage.test.mjs +68 -0
- package/dist/packages/sdk/observers/mail.delivery/fetch.mjs +87 -0
- package/dist/packages/sdk/observers/mail.delivery/fixtures/bounce-by-recipient.json +1 -0
- package/dist/packages/sdk/observers/mail.delivery/fixtures/bounce.json +1 -0
- package/dist/packages/sdk/observers/mail.delivery/fixtures/delayed.json +1 -0
- package/dist/packages/sdk/observers/mail.delivery/fixtures/delivered.json +1 -0
- package/dist/packages/sdk/observers/mail.delivery/fixtures/empty.json +1 -0
- package/dist/packages/sdk/observers/mail.delivery/fixtures/other-message.json +1 -0
- package/dist/packages/sdk/observers/mail.delivery/judge.mjs +13 -0
- package/dist/packages/sdk/observers/mail.delivery/observer.json +14 -0
- package/dist/packages/sdk/package.json +232 -0
- package/dist/packages/sdk/src/authoring-example.d.ts +91 -0
- package/dist/packages/sdk/src/authoring-example.js +50 -0
- package/dist/packages/sdk/src/authoring-instructions.d.ts +20 -0
- package/dist/packages/sdk/src/authoring-instructions.js +151 -0
- package/dist/packages/sdk/src/authoring-prompt.d.ts +2 -0
- package/dist/packages/sdk/src/authoring-prompt.js +8 -0
- package/dist/packages/sdk/src/authoring.d.ts +10 -0
- package/dist/packages/sdk/src/authoring.js +287 -0
- package/dist/packages/sdk/src/bindings.d.ts +4 -0
- package/dist/packages/sdk/src/bindings.js +124 -0
- package/dist/packages/sdk/src/bridge.d.ts +2 -0
- package/dist/packages/sdk/src/bridge.js +23 -0
- package/dist/packages/sdk/src/browser-runtime/pyproject.toml +5 -0
- package/dist/packages/sdk/src/browser-runtime/tools.json +189 -0
- package/dist/packages/sdk/src/browser-runtime/uv.lock +3894 -0
- package/dist/packages/sdk/src/browser-service.py +127 -0
- package/dist/packages/sdk/src/browser.d.ts +38 -0
- package/dist/packages/sdk/src/browser.js +203 -0
- package/dist/packages/sdk/src/capabilities.d.ts +13 -0
- package/dist/packages/sdk/src/capabilities.js +68 -0
- package/dist/packages/sdk/src/classification-client.d.ts +4 -0
- package/dist/packages/sdk/src/classification-client.js +27 -0
- package/dist/packages/sdk/src/cloud.d.ts +23 -0
- package/dist/packages/sdk/src/cloud.js +43 -0
- package/dist/packages/sdk/src/computer-settings.d.ts +28 -0
- package/dist/packages/sdk/src/computer-settings.js +57 -0
- package/dist/packages/sdk/src/connect.d.ts +47 -0
- package/dist/packages/sdk/src/connect.js +203 -0
- package/dist/packages/sdk/src/current-inspection.d.ts +3 -0
- package/dist/packages/sdk/src/current-inspection.js +146 -0
- package/dist/packages/sdk/src/current-runtime.d.ts +14 -0
- package/dist/packages/sdk/src/current-runtime.js +167 -0
- package/dist/packages/sdk/src/doctor.d.ts +17 -0
- package/dist/packages/sdk/src/doctor.js +68 -0
- package/dist/packages/sdk/src/executable.d.ts +2 -0
- package/dist/packages/sdk/src/executable.js +22 -0
- package/dist/packages/sdk/src/explain-effects.d.ts +32 -0
- package/dist/packages/sdk/src/explain-effects.js +192 -0
- package/dist/packages/sdk/src/explain.d.ts +115 -0
- package/dist/packages/sdk/src/explain.js +441 -0
- package/dist/packages/sdk/src/files.d.ts +9 -0
- package/dist/packages/sdk/src/files.js +50 -0
- package/dist/packages/sdk/src/guard-keys.d.ts +5 -0
- package/dist/packages/sdk/src/guard-keys.js +42 -0
- package/dist/packages/sdk/src/hosted-models.d.ts +49 -0
- package/dist/packages/sdk/src/hosted-models.js +81 -0
- package/dist/packages/sdk/src/improve.d.ts +55 -0
- package/dist/packages/sdk/src/improve.js +159 -0
- package/dist/packages/sdk/src/index.d.ts +13 -0
- package/dist/packages/sdk/src/index.js +13 -0
- package/dist/packages/sdk/src/inspect.d.ts +6 -0
- package/dist/packages/sdk/src/inspect.js +17 -0
- package/dist/packages/sdk/src/link.d.ts +12 -0
- package/dist/packages/sdk/src/link.js +53 -0
- package/dist/packages/sdk/src/local-cli.d.ts +24 -0
- package/dist/packages/sdk/src/local-cli.js +146 -0
- package/dist/packages/sdk/src/local-setup.d.ts +15 -0
- package/dist/packages/sdk/src/local-setup.js +42 -0
- package/dist/packages/sdk/src/method-client.d.ts +30 -0
- package/dist/packages/sdk/src/method-client.js +250 -0
- package/dist/packages/sdk/src/method-files.d.ts +29 -0
- package/dist/packages/sdk/src/method-files.js +93 -0
- package/dist/packages/sdk/src/method-help.d.ts +19 -0
- package/dist/packages/sdk/src/method-help.js +404 -0
- package/dist/packages/sdk/src/method-issues.d.ts +86 -0
- package/dist/packages/sdk/src/method-issues.js +192 -0
- package/dist/packages/sdk/src/method-sync.d.ts +46 -0
- package/dist/packages/sdk/src/method-sync.js +293 -0
- package/dist/packages/sdk/src/method.d.ts +5 -0
- package/dist/packages/sdk/src/method.js +359 -0
- package/dist/packages/sdk/src/model-checks.d.ts +96 -0
- package/dist/packages/sdk/src/model-checks.js +181 -0
- package/dist/packages/sdk/src/outbox.d.ts +120 -0
- package/dist/packages/sdk/src/outbox.js +297 -0
- package/dist/packages/sdk/src/own-model-key.d.ts +22 -0
- package/dist/packages/sdk/src/own-model-key.js +76 -0
- package/dist/packages/sdk/src/prepare.d.ts +24 -0
- package/dist/packages/sdk/src/prepare.js +245 -0
- package/dist/packages/sdk/src/process.d.ts +15 -0
- package/dist/packages/sdk/src/process.js +107 -0
- package/dist/packages/sdk/src/production.d.ts +182 -0
- package/dist/packages/sdk/src/production.js +284 -0
- package/dist/packages/sdk/src/progress.d.ts +12 -0
- package/dist/packages/sdk/src/progress.js +48 -0
- package/dist/packages/sdk/src/proposals.d.ts +73 -0
- package/dist/packages/sdk/src/proposals.js +284 -0
- package/dist/packages/sdk/src/quality.d.ts +82 -0
- package/dist/packages/sdk/src/quality.js +294 -0
- package/dist/packages/sdk/src/result-files.d.ts +5 -0
- package/dist/packages/sdk/src/result-files.js +149 -0
- package/dist/packages/sdk/src/result-transfer.d.ts +21 -0
- package/dist/packages/sdk/src/result-transfer.js +37 -0
- package/dist/packages/sdk/src/run-data.d.ts +11 -0
- package/dist/packages/sdk/src/run-data.js +80 -0
- package/dist/packages/sdk/src/run-method.d.ts +2 -0
- package/dist/packages/sdk/src/run-method.js +2 -0
- package/dist/packages/sdk/src/run-saved.d.ts +5 -0
- package/dist/packages/sdk/src/run-saved.js +138 -0
- package/dist/packages/sdk/src/run-worker.d.ts +6 -0
- package/dist/packages/sdk/src/run-worker.js +131 -0
- package/dist/packages/sdk/src/secrets.d.ts +37 -0
- package/dist/packages/sdk/src/secrets.js +196 -0
- package/dist/packages/sdk/src/update.d.ts +5 -0
- package/dist/packages/sdk/src/update.js +39 -0
- package/dist/packages/sdk/src/versions.d.ts +58 -0
- package/dist/packages/sdk/src/versions.js +144 -0
- package/dist/packages/sdk/src/worker.d.ts +120 -0
- package/dist/packages/sdk/src/worker.js +443 -0
- package/dist/packages/workflow-language/src/execution.d.ts +1 -0
- package/dist/packages/workflow-language/src/execution.js +1 -0
- package/dist/packages/workflow-language/src/inspection.d.ts +990 -0
- package/dist/packages/workflow-language/src/inspection.js +130 -0
- package/dist/packages/workflow-language/src/result-files.d.ts +160 -0
- package/dist/packages/workflow-language/src/result-files.js +67 -0
- package/dist/packages/workflow-language/src/schema.d.ts +207 -0
- package/dist/packages/workflow-language/src/schema.js +56 -0
- package/dist/packages/workflow-language/src/validate.d.ts +11 -0
- package/dist/packages/workflow-language/src/validate.js +77 -0
- package/package.json +230 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Method
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @method-ai-hq/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MIT-licensed JavaScript API and the `method` CLI. Source and releases: https://github.com/method-ai-hq/method-sdk
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install https://github.com/method-ai-hq/method-sdk/releases/download/v0.14.2/method-ai-hq-sdk-0.14.2.tgz
|
|
7
|
+
npx method --version
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
import {readFileSync} from 'node:fs';
|
|
12
|
+
import {loadMethod, runMethod, inspectRun} from '@method-ai-hq/sdk';
|
|
13
|
+
const method = loadMethod(readFileSync('task.method', 'utf8'));
|
|
14
|
+
const result = await runMethod('task.method', {allow_local_processes: true}, {inputs: {}, runDir: 'runs/first'});
|
|
15
|
+
console.log(result.status, inspectRun('runs/first'));
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
New Methods use method/3.4: models, limits, tools, secret names, and the Method ID are in the Method file. Documents in method/3.1 to 3.3 load and run unchanged. `runMethod` is the bare runtime: it does not sign in, save versions, or use hosted models; `method run` does. The executor is the pinned @withmethod/runtime dependency. Python uses method-bridge to call the same runtime.
|
|
19
|
+
|
|
20
|
+
To run a published Method from an app, use `new Method().run({method: 'wf_…', inputs})`. See https://docs.withmethod.ai/guides/production.
|
|
21
|
+
|
|
22
|
+
Browser-safe document modules are available at `@method-ai-hq/sdk/schema`, `/validate`, `/execution`, `/inspection`, and `/result-files`. Node tools use `/identity`, `/method-package`, `/method-client`, `/method-sync`, and `/process`. Do not import the Node package root into a browser bundle.
|
|
23
|
+
|
|
24
|
+
Before creating, editing, or proposing a Method, run `method authoring` and read its guidance. Do this before choosing an existing Method as a reference. The package includes reviewed examples. Saving versions, hosted models, and production runs need a Method account; local validation and script runs do not.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const StableIdSchema: z.ZodString;
|
|
3
|
+
export declare const Sha256Schema: z.ZodString;
|
|
4
|
+
export declare const ConfidenceSchema: z.ZodNumber;
|
|
5
|
+
export declare function canonicalJson(value: unknown): string;
|
|
6
|
+
export declare function sha256(value: string): string;
|
|
7
|
+
export declare function semanticDigest(value: unknown): string;
|
|
8
|
+
/**
|
|
9
|
+
* Document identity preserves authored step and classifier option order. The Method ID (`id:`) names the account
|
|
10
|
+
* Method and is not content: a copy with another ID has the same digest.
|
|
11
|
+
*/
|
|
12
|
+
export declare function workflowDocumentDigest(value: {
|
|
13
|
+
steps: Record<string, unknown>;
|
|
14
|
+
}): string;
|
|
15
|
+
/** A version ID: the same content (package digest) of a Method is always the same version. */
|
|
16
|
+
export declare function versionIdFor(methodId: string, packageDigest: string): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { documentForDigest } from "@withmethod/runtime/document.js";
|
|
4
|
+
export const StableIdSchema = z.string().regex(/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/, "stable IDs use lowercase letters, numbers, dots, underscores, and hyphens");
|
|
5
|
+
export const Sha256Schema = z.string().regex(/^[a-f0-9]{64}$/);
|
|
6
|
+
export const ConfidenceSchema = z.number().min(0).max(1);
|
|
7
|
+
export function canonicalJson(value) {
|
|
8
|
+
return JSON.stringify(canonicalize(value));
|
|
9
|
+
}
|
|
10
|
+
export function sha256(value) {
|
|
11
|
+
return createHash("sha256").update(value, "utf8").digest("hex");
|
|
12
|
+
}
|
|
13
|
+
export function semanticDigest(value) {
|
|
14
|
+
return sha256(canonicalJson(value));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Document identity preserves authored step and classifier option order. The Method ID (`id:`) names the account
|
|
18
|
+
* Method and is not content: a copy with another ID has the same digest.
|
|
19
|
+
*/
|
|
20
|
+
export function workflowDocumentDigest(value) {
|
|
21
|
+
const content = documentForDigest(value);
|
|
22
|
+
return semanticDigest({ ...content, steps: Object.entries(value.steps).map(([id, raw]) => {
|
|
23
|
+
const step = raw;
|
|
24
|
+
return [id, step?.do?.kind === 'classify'
|
|
25
|
+
? { ...step, do: { ...step.do, options: Object.entries(step.do.options ?? {}) } }
|
|
26
|
+
: raw];
|
|
27
|
+
}) });
|
|
28
|
+
}
|
|
29
|
+
/** A version ID: the same content (package digest) of a Method is always the same version. */
|
|
30
|
+
export function versionIdFor(methodId, packageDigest) {
|
|
31
|
+
return `v_${sha256(`${methodId}:${packageDigest}`).slice(0, 32)}`;
|
|
32
|
+
}
|
|
33
|
+
function canonicalize(value) {
|
|
34
|
+
if (Array.isArray(value))
|
|
35
|
+
return value.map(canonicalize);
|
|
36
|
+
if (value === null || typeof value !== "object")
|
|
37
|
+
return value;
|
|
38
|
+
return Object.fromEntries(Object.entries(value)
|
|
39
|
+
.sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)
|
|
40
|
+
.map(([key, child]) => [key, canonicalize(child)]));
|
|
41
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const packagePath: (path: string) => string;
|
|
3
|
+
export declare const PackageFileSchema: z.ZodObject<{
|
|
4
|
+
path: z.ZodEffects<z.ZodString, string, string>;
|
|
5
|
+
sha256: z.ZodString;
|
|
6
|
+
size: z.ZodNumber;
|
|
7
|
+
}, "strict", z.ZodTypeAny, {
|
|
8
|
+
sha256: string;
|
|
9
|
+
path: string;
|
|
10
|
+
size: number;
|
|
11
|
+
}, {
|
|
12
|
+
sha256: string;
|
|
13
|
+
path: string;
|
|
14
|
+
size: number;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const MethodPackageSchema: z.ZodEffects<z.ZodObject<{
|
|
17
|
+
schema: z.ZodLiteral<"method-package/1">;
|
|
18
|
+
runtime: z.ZodString;
|
|
19
|
+
files: z.ZodArray<z.ZodObject<{
|
|
20
|
+
path: z.ZodEffects<z.ZodString, string, string>;
|
|
21
|
+
sha256: z.ZodString;
|
|
22
|
+
size: z.ZodNumber;
|
|
23
|
+
}, "strict", z.ZodTypeAny, {
|
|
24
|
+
sha256: string;
|
|
25
|
+
path: string;
|
|
26
|
+
size: number;
|
|
27
|
+
}, {
|
|
28
|
+
sha256: string;
|
|
29
|
+
path: string;
|
|
30
|
+
size: number;
|
|
31
|
+
}>, "many">;
|
|
32
|
+
digest: z.ZodString;
|
|
33
|
+
}, "strict", z.ZodTypeAny, {
|
|
34
|
+
files: {
|
|
35
|
+
sha256: string;
|
|
36
|
+
path: string;
|
|
37
|
+
size: number;
|
|
38
|
+
}[];
|
|
39
|
+
schema: "method-package/1";
|
|
40
|
+
runtime: string;
|
|
41
|
+
digest: string;
|
|
42
|
+
}, {
|
|
43
|
+
files: {
|
|
44
|
+
sha256: string;
|
|
45
|
+
path: string;
|
|
46
|
+
size: number;
|
|
47
|
+
}[];
|
|
48
|
+
schema: "method-package/1";
|
|
49
|
+
runtime: string;
|
|
50
|
+
digest: string;
|
|
51
|
+
}>, {
|
|
52
|
+
files: {
|
|
53
|
+
sha256: string;
|
|
54
|
+
path: string;
|
|
55
|
+
size: number;
|
|
56
|
+
}[];
|
|
57
|
+
schema: "method-package/1";
|
|
58
|
+
runtime: string;
|
|
59
|
+
digest: string;
|
|
60
|
+
}, {
|
|
61
|
+
files: {
|
|
62
|
+
sha256: string;
|
|
63
|
+
path: string;
|
|
64
|
+
size: number;
|
|
65
|
+
}[];
|
|
66
|
+
schema: "method-package/1";
|
|
67
|
+
runtime: string;
|
|
68
|
+
digest: string;
|
|
69
|
+
}>;
|
|
70
|
+
export type MethodPackage = z.infer<typeof MethodPackageSchema>;
|
|
71
|
+
export declare function packageDigest(workflow: unknown, value: Pick<MethodPackage, 'runtime' | 'files'>): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { canonicalJson, sha256, workflowDocumentDigest } from './identity.js';
|
|
3
|
+
export const packagePath = (path) => {
|
|
4
|
+
if (!path || path.length > 500 || path.startsWith('/') || path.includes('\\') || /^[A-Za-z]:/.test(path) || path.split('/').some(p => !p || ['.', '..', '.git', 'node_modules', '.venv', '.codex', '.claude'].includes(p) || p.startsWith('.env') || p === 'secrets.env'))
|
|
5
|
+
throw Error(`Invalid package path: ${path}`);
|
|
6
|
+
return path;
|
|
7
|
+
};
|
|
8
|
+
export const PackageFileSchema = z.strictObject({ path: z.string().refine(p => { try {
|
|
9
|
+
packagePath(p);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
} }), sha256: z.string().regex(/^[a-f0-9]{64}$/), size: z.number().int().min(0).max(20_000_000) });
|
|
15
|
+
export const MethodPackageSchema = z.strictObject({
|
|
16
|
+
schema: z.literal('method-package/1'), runtime: z.string().regex(/^\d+\.\d+\.\d+$/),
|
|
17
|
+
files: z.array(PackageFileSchema).max(10000), digest: z.string().regex(/^[a-f0-9]{64}$/),
|
|
18
|
+
}).superRefine((p, ctx) => { if (new Set(p.files.map(f => f.path)).size !== p.files.length)
|
|
19
|
+
ctx.addIssue({ code: 'custom', message: 'Duplicate package paths' }); });
|
|
20
|
+
export function packageDigest(workflow, value) {
|
|
21
|
+
return sha256(canonicalJson({ document: workflowDocumentDigest(workflow), runtime: value.runtime, files: [...value.files].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type Workflow } from "../../workflow-language/src/schema.js";
|
|
3
|
+
export declare const ConversionReportSchema: z.ZodObject<{
|
|
4
|
+
schema: z.ZodLiteral<"workflow-conversion/1">;
|
|
5
|
+
source_sha256: z.ZodString;
|
|
6
|
+
workflow_sha256: z.ZodString;
|
|
7
|
+
references: z.ZodArray<z.ZodObject<{
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
sha256: z.ZodString;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
sha256: string;
|
|
12
|
+
name: string;
|
|
13
|
+
}, {
|
|
14
|
+
sha256: string;
|
|
15
|
+
name: string;
|
|
16
|
+
}>, "many">;
|
|
17
|
+
status: z.ZodEnum<["ready", "needs_review"]>;
|
|
18
|
+
attempts: z.ZodNumber;
|
|
19
|
+
selected_attempt: z.ZodNumber;
|
|
20
|
+
coverage: z.ZodArray<z.ZodObject<{
|
|
21
|
+
source_id: z.ZodString;
|
|
22
|
+
result: z.ZodEnum<["covered", "missing", "ambiguous"]>;
|
|
23
|
+
locations: z.ZodArray<z.ZodString, "many">;
|
|
24
|
+
explanation: z.ZodString;
|
|
25
|
+
}, "strict", z.ZodTypeAny, {
|
|
26
|
+
result: "missing" | "ambiguous" | "covered";
|
|
27
|
+
source_id: string;
|
|
28
|
+
locations: string[];
|
|
29
|
+
explanation: string;
|
|
30
|
+
}, {
|
|
31
|
+
result: "missing" | "ambiguous" | "covered";
|
|
32
|
+
source_id: string;
|
|
33
|
+
locations: string[];
|
|
34
|
+
explanation: string;
|
|
35
|
+
}>, "many">;
|
|
36
|
+
concerns: z.ZodArray<z.ZodString, "many">;
|
|
37
|
+
review_method: z.ZodLiteral<"format_validation">;
|
|
38
|
+
editor: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
agent: z.ZodLiteral<"Method Editing Agent">;
|
|
40
|
+
summary: z.ZodString;
|
|
41
|
+
elapsed_ms: z.ZodNumber;
|
|
42
|
+
changed_paths: z.ZodArray<z.ZodString, "many">;
|
|
43
|
+
}, "strict", z.ZodTypeAny, {
|
|
44
|
+
agent: "Method Editing Agent";
|
|
45
|
+
summary: string;
|
|
46
|
+
elapsed_ms: number;
|
|
47
|
+
changed_paths: string[];
|
|
48
|
+
}, {
|
|
49
|
+
agent: "Method Editing Agent";
|
|
50
|
+
summary: string;
|
|
51
|
+
elapsed_ms: number;
|
|
52
|
+
changed_paths: string[];
|
|
53
|
+
}>>;
|
|
54
|
+
requirement_coverage: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
55
|
+
source_id: z.ZodString;
|
|
56
|
+
result: z.ZodEnum<["covered", "missing", "ambiguous"]>;
|
|
57
|
+
locations: z.ZodArray<z.ZodString, "many">;
|
|
58
|
+
explanation: z.ZodString;
|
|
59
|
+
}, "strict", z.ZodTypeAny, {
|
|
60
|
+
result: "missing" | "ambiguous" | "covered";
|
|
61
|
+
source_id: string;
|
|
62
|
+
locations: string[];
|
|
63
|
+
explanation: string;
|
|
64
|
+
}, {
|
|
65
|
+
result: "missing" | "ambiguous" | "covered";
|
|
66
|
+
source_id: string;
|
|
67
|
+
locations: string[];
|
|
68
|
+
explanation: string;
|
|
69
|
+
}>, "many">>;
|
|
70
|
+
}, "strict", z.ZodTypeAny, {
|
|
71
|
+
status: "ready" | "needs_review";
|
|
72
|
+
schema: "workflow-conversion/1";
|
|
73
|
+
references: {
|
|
74
|
+
sha256: string;
|
|
75
|
+
name: string;
|
|
76
|
+
}[];
|
|
77
|
+
attempts: number;
|
|
78
|
+
source_sha256: string;
|
|
79
|
+
workflow_sha256: string;
|
|
80
|
+
selected_attempt: number;
|
|
81
|
+
coverage: {
|
|
82
|
+
result: "missing" | "ambiguous" | "covered";
|
|
83
|
+
source_id: string;
|
|
84
|
+
locations: string[];
|
|
85
|
+
explanation: string;
|
|
86
|
+
}[];
|
|
87
|
+
concerns: string[];
|
|
88
|
+
review_method: "format_validation";
|
|
89
|
+
editor?: {
|
|
90
|
+
agent: "Method Editing Agent";
|
|
91
|
+
summary: string;
|
|
92
|
+
elapsed_ms: number;
|
|
93
|
+
changed_paths: string[];
|
|
94
|
+
} | undefined;
|
|
95
|
+
requirement_coverage?: {
|
|
96
|
+
result: "missing" | "ambiguous" | "covered";
|
|
97
|
+
source_id: string;
|
|
98
|
+
locations: string[];
|
|
99
|
+
explanation: string;
|
|
100
|
+
}[] | undefined;
|
|
101
|
+
}, {
|
|
102
|
+
status: "ready" | "needs_review";
|
|
103
|
+
schema: "workflow-conversion/1";
|
|
104
|
+
references: {
|
|
105
|
+
sha256: string;
|
|
106
|
+
name: string;
|
|
107
|
+
}[];
|
|
108
|
+
attempts: number;
|
|
109
|
+
source_sha256: string;
|
|
110
|
+
workflow_sha256: string;
|
|
111
|
+
selected_attempt: number;
|
|
112
|
+
coverage: {
|
|
113
|
+
result: "missing" | "ambiguous" | "covered";
|
|
114
|
+
source_id: string;
|
|
115
|
+
locations: string[];
|
|
116
|
+
explanation: string;
|
|
117
|
+
}[];
|
|
118
|
+
concerns: string[];
|
|
119
|
+
review_method: "format_validation";
|
|
120
|
+
editor?: {
|
|
121
|
+
agent: "Method Editing Agent";
|
|
122
|
+
summary: string;
|
|
123
|
+
elapsed_ms: number;
|
|
124
|
+
changed_paths: string[];
|
|
125
|
+
} | undefined;
|
|
126
|
+
requirement_coverage?: {
|
|
127
|
+
result: "missing" | "ambiguous" | "covered";
|
|
128
|
+
source_id: string;
|
|
129
|
+
locations: string[];
|
|
130
|
+
explanation: string;
|
|
131
|
+
}[] | undefined;
|
|
132
|
+
}>;
|
|
133
|
+
export type ConversionReport = z.infer<typeof ConversionReportSchema>;
|
|
134
|
+
export declare function sourceSegments(source: string): Array<{
|
|
135
|
+
id: string;
|
|
136
|
+
text: string;
|
|
137
|
+
}>;
|
|
138
|
+
export declare function renderPrompt(workflow: Workflow): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { loadWorkflow, serializeWorkflow } from "../../workflow-language/src/validate.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const ReportItemSchema = z.strictObject({
|
|
4
|
+
source_id: z.string(), result: z.enum(["covered", "missing", "ambiguous"]),
|
|
5
|
+
locations: z.array(z.string()), explanation: z.string().min(1)
|
|
6
|
+
});
|
|
7
|
+
export const ConversionReportSchema = z.strictObject({
|
|
8
|
+
schema: z.literal("workflow-conversion/1"), source_sha256: z.string(), workflow_sha256: z.string(),
|
|
9
|
+
references: z.array(z.strictObject({ name: z.string(), sha256: z.string() })),
|
|
10
|
+
status: z.enum(["ready", "needs_review"]), attempts: z.number().int().positive(),
|
|
11
|
+
selected_attempt: z.number().int().positive(),
|
|
12
|
+
coverage: z.array(ReportItemSchema), concerns: z.array(z.string()),
|
|
13
|
+
review_method: z.literal("format_validation"),
|
|
14
|
+
editor: z.strictObject({ agent: z.literal("Method Editing Agent"), summary: z.string(), elapsed_ms: z.number().nonnegative(), changed_paths: z.array(z.string()) }).optional(),
|
|
15
|
+
requirement_coverage: z.array(ReportItemSchema).optional(),
|
|
16
|
+
});
|
|
17
|
+
export function sourceSegments(source) {
|
|
18
|
+
return source.split(/\n\s*\n/).filter(text => text.trim()).map((text, index) => ({ id: `source_${index + 1}`, text }));
|
|
19
|
+
}
|
|
20
|
+
export function renderPrompt(workflow) {
|
|
21
|
+
loadWorkflow(workflow);
|
|
22
|
+
return serializeWorkflow(workflow);
|
|
23
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Write a daily briefing
|
|
2
|
+
|
|
3
|
+
TASK.md contains the task recorded in the Method's goal. daily-briefing.method implements it. approved-report.md contains the complete approved report that the writing step follows.
|
|
4
|
+
|
|
5
|
+
All people, places, and conversations in this example are fictional. Wren Talbot runs a pottery studio, Larkfield Ceramics, in the invented town of Millbrook.
|
|
6
|
+
|
|
7
|
+
## Run
|
|
8
|
+
|
|
9
|
+
Copy this folder to a working folder, then run:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
cp -R sample prepared_day # a folder named after the connection needs no binding
|
|
13
|
+
method validate daily-briefing.method
|
|
14
|
+
method run daily-briefing.method --inputs inputs.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The run saves a version and prints the dashboard link. Method prepares the Python and Node dependencies. For another day, put that day's prepared records in `prepared_day/`, or bind another folder with `method bind daily-briefing.method prepared_day --file FOLDER`.
|
|
18
|
+
|
|
19
|
+
sample/ contains one complete conversation: 28 messages from the morning of May 11, in which Wren plans a glaze workshop. inputs.json selects that date and timezone. The approved report covers Wren's full day; the sample covers only this conversation.
|
|
20
|
+
|
|
21
|
+
Open the website returned by the run. Source links open the saved records and selected passages. The Markdown and supporting files are included with the website.
|
|
22
|
+
|
|
23
|
+
## Files
|
|
24
|
+
|
|
25
|
+
- daily-briefing.method: input checks, writing with a source check, and website rendering.
|
|
26
|
+
- daily-briefing.method `tools:`: the time calculation tool.
|
|
27
|
+
- briefing_*.py, reader/, vendor/: helpers and website assets.
|
|
28
|
+
- pyproject.toml, uv.lock, package.json, package-lock.json: dependencies.
|
|
29
|
+
- sample/, inputs.json: inputs for a sample run, kept outside the Method's saved files.
|
|
30
|
+
- approved-report.md: complete writing reference.
|
|
31
|
+
- sample-report.md, sample-output.zip: a briefing of the sample conversation, and the website that the Method's own scripts built from it. The draft was written for this example; the time tool, the source check, and the render step ran on it. checks.json records how, with the hashes.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
date: 2026-05-11
|
|
3
|
+
timezone: America/Chicago
|
|
4
|
+
title: May 11 — proposed briefing
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Monday, May 11
|
|
8
|
+
|
|
9
|
+
_A day in Millbrook_
|
|
10
|
+
|
|
11
|
+
## TL;DR
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
**You planned the Spring Glaze Workshop, fired a bisque load, and agreed to a demo night at the Millbrook Public Library.** In ChatGPT you set the four-week kiln schedule, chose a price of $195, and rewrote the class description until it was plain. You sent the announcement to your mailing list in the afternoon. Nine people had replied by the evening, one more than the class can hold. [Sources](source:chatgpt-0001,chatgpt-0013,gmail-0007,gmail-0012,gmail-0019)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
Between these tasks, you drove to Fennimore Clay Supply for two bags of stoneware, browsed glaze recipes on Instagram, and ate dinner with Theo at the Orchard Street Diner. Your notes asked whether the studio should take commissions this summer or keep the time for classes. [Sources](source:google_timeline-0002,google_timeline-0004,instagram-0011,google_timeline-0007,apple_notes-0001)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
**Time estimates:** about 3 h 40 min in the studio, 1 h 10 min of workshop planning in ChatGPT and email, 45 min on Instagram, 1 h 30 min at dinner, 50 min driving, and 1 h 5 min of Spotify playback. These periods overlap. [Sources](source:time-estimates)
|
|
24
|
+
|
|
25
|
+
## Morning
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
At 7:52, Fennimore Clay Supply emailed that your order of glaze materials was ready to pick up. At 8:05, your calendar showed “Bisque load — empty by Thursday.” [Sources](source:gmail-0002,calendar-0001)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Google Maps places you at the studio on Orchard Street from 8:20. You loaded the kiln and started the bisque firing at 8:41; the kiln controller’s email confirmed the start. A photo from 8:46 shows the full kiln before you closed the lid. [Sources](source:google_timeline-0001,gmail-0004,photos-0001)
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
At 9:30, you were on Instagram. A post you saved said, “Test tiles are the cheapest lesson in the studio.” You opened two glaze-recipe posts after it and saved one for a celadon. [Sources](source:instagram-0004,instagram-0006,instagram-0011)
|
|
40
|
+
|
|
41
|
+
[Saved social session](sessions.html#social-2b6e41c09d1a)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
At 10:05, Dana Ruiz at the library texted: “Would you do a free pottery demo here this spring? Our community room is open most Thursdays.” You answered, “Yes! Let me plan the class first and I’ll send dates.” [Sources](source:imessage-0003,imessage-0004)
|
|
46
|
+
|
|
47
|
+
## Planning the workshop
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
At 10:42, you asked ChatGPT how to plan a four-week evening glaze workshop for eight people with one kiln. It proposed one bisque firing after week 2 and one glaze firing after week 3. After you gave the kiln size and the 22 hours of firing and cooling, it fixed a Tuesday schedule with almost five days of margin. [Sources](source:chatgpt-0001,chatgpt-0003,chatgpt-0004,chatgpt-0005)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
You asked about clay and price. ChatGPT estimated 32 lb of clay for eight people and a cost of $109 per person, including your time. It suggested a price from $185 to $220. You pointed out that the other studio in Millbrook charges $160 without the glaze firing, and asked whether $195 was too much. Its comparison showed that the other class comes to about $180 once two pieces are glaze-fired. You chose $195. [Sources](source:chatgpt-0007,chatgpt-0009,chatgpt-0010,chatgpt-0012,chatgpt-0013)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
The first class description began “Discover the magic of glaze!” You called it “too salesy” and asked for a plain text that says why the class has only eight places. The second version said: “The class is limited to 8 people so that everyone's pieces fit in one kiln load.” [Sources](source:chatgpt-0015,chatgpt-0016,chatgpt-0017)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
You asked for a supply list and a short email to your mailing list. At 11:12, you came back to the conversation with Dana’s invitation. ChatGPT wrote the text of a sign-up form, and at 11:27 confirmed that six demo bowls can go into the workshop’s glaze load if they are bisqued in time. [Sources](source:chatgpt-0019,chatgpt-0021,chatgpt-0022,chatgpt-0025,chatgpt-0028)
|
|
64
|
+
|
|
65
|
+
## Midday
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
At 12:10, Google Maps records a drive to Fennimore Clay Supply. You bought two 25 lb bags of mid-fire stoneware and a set of wooden ribs; the receipt arrived at 12:31. You were back at the studio at 12:58. [Sources](source:google_timeline-0002,gmail-0009,google_timeline-0003)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
From 1:00 to 3:15, you were at the studio. Spotify played most of an album by The Quiet Kilns, then a podcast about running a craft business. At 2:40, you texted Theo a photo of a cracked test tile: “This is why we test.” [Sources](source:google_timeline-0003,spotify-0001,spotify-0009,imessage-0008,photos-0002)
|
|
74
|
+
|
|
75
|
+

|
|
76
|
+
|
|
77
|
+
## Afternoon
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
At 3:20, you sent the announcement to your mailing list with the subject “Spring Glaze Workshop — 8 places”. The text was the draft from the morning, with the dates added. [Sources](source:gmail-0012,chatgpt-0021)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
Replies started at 3:34. By 6:00, seven people had asked for a place. One asked whether children could come: “My daughter is 12 and loves clay — is she too young?” You did not answer that email on May 11. [Sources](source:gmail-0013,gmail-0014,gmail-0016)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
At 4:15, you texted Dana three possible Thursdays for the demo night. She chose Thursday, May 28, and said the library would put down a floor cover. [Sources](source:imessage-0011,imessage-0012)
|
|
90
|
+
|
|
91
|
+
[Saved social session](sessions.html#social-8f02cd5e7a44)
|
|
92
|
+
|
|
93
|
+
## Dinner with Theo
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
You left the studio at 6:20. Google Maps places you at the Orchard Street Diner from 6:31 to 8:02. Theo texted at 6:28, “Got us the booth by the window.” [Sources](source:google_timeline-0006,google_timeline-0007,imessage-0015)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
At 7:40, two more replies arrived. The class now had nine requests for eight places. [Sources](source:gmail-0018,gmail-0019)
|
|
102
|
+
|
|
103
|
+
## Evening
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
You were home at 8:14. At 8:30, the kiln controller emailed that the bisque firing had finished and the kiln was cooling. [Sources](source:google_timeline-0008,gmail-0021)
|
|
108
|
+
|
|
109
|
+
## Your May 11 notes
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
In a note at 9:12, you wrote: “Nine people for eight places. Start a waiting list, or open a second Tuesday?” Further down: “Commissions pay more per hour, but classes fill the summer calendar and bring people back.” The note ends with a question that you did not answer: “What do I want the studio to be known for?” [Read passage](source:apple_notes-0001#L1-L6)
|
|
114
|
+
|
|
115
|
+
## Other records
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
Spotify saved 12 plays, including repeats and partial plays. [Show all](source:spotify-0001,spotify-0002,spotify-0003,spotify-0004,spotify-0005,spotify-0006,spotify-0007,spotify-0008,spotify-0009,spotify-0010,spotify-0011,spotify-0012)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## Supporting document: time-estimates
|
|
123
|
+
|
|
124
|
+
# May 11 time estimates
|
|
125
|
+
|
|
126
|
+
**Studio:** [8:20–10:00 AM and 1:00–3:15 PM](source:google_timeline-0001), from Google Maps, minus the time at Fennimore Clay Supply.
|
|
127
|
+
|
|
128
|
+
**Workshop planning:** First-to-last [ChatGPT messages](documents.html) and the email you sent, split at gaps over 15 minutes.
|
|
129
|
+
|
|
130
|
+
**Instagram:** First-to-last visits in each [session](sessions.html), split at gaps over five minutes.
|
|
131
|
+
|
|
132
|
+
**Dinner:** [6:31–8:02 PM](source:google_timeline-0007), from Google Maps.
|
|
133
|
+
|
|
134
|
+
**Driving:** About 34 minutes [to and from the supply store](source:google_timeline-0002) and 16 minutes [to dinner and home](source:google_timeline-0006), including stops.
|
|
135
|
+
|
|
136
|
+
**Spotify:** Sum of the [12 saved playback durations](source:spotify-0001), including partial plays.
|
|
137
|
+
|
|
138
|
+
Studio, planning, and browsing periods can include breaks and overlap. They do not measure continuous attention.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Read and write the files produced by a briefing run."""
|
|
2
|
+
import hashlib
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from briefing_files import folder
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def digest(path):
|
|
11
|
+
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def tree(root):
|
|
15
|
+
return {str(p.relative_to(root)): digest(p) for p in sorted(root.rglob('*')) if p.is_file()}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def source_digest():
|
|
19
|
+
return hashlib.sha256(json.dumps(tree(folder('selected_day')),sort_keys=True).encode()).hexdigest()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def local(name):
|
|
23
|
+
root=Path(os.environ['METHOD_OUTPUT_DIR']).resolve()
|
|
24
|
+
path=(root/name).resolve()
|
|
25
|
+
if not path.is_relative_to(root):raise ValueError('Path leaves the run folder')
|
|
26
|
+
return path
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def put(path, data):
|
|
30
|
+
path=local(path)
|
|
31
|
+
path.parent.mkdir(parents=True,exist_ok=True)
|
|
32
|
+
path.write_text(json.dumps(data,ensure_ascii=False,indent=2)+'\n');path.chmod(0o600)
|
|
33
|
+
return {'path':str(path.relative_to(local('.'))),'sha256':digest(path)}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def load(ref):
|
|
37
|
+
path=local(ref['path'])
|
|
38
|
+
if digest(path)!=ref['sha256']:raise ValueError('The saved file changed')
|
|
39
|
+
return json.loads(path.read_text())
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Check the prepared folder, approved example, date, and timezone."""
|
|
2
|
+
import datetime as dt
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from zoneinfo import ZoneInfo
|
|
7
|
+
|
|
8
|
+
from briefing_artifacts import source_digest
|
|
9
|
+
from briefing_files import folder, local_path
|
|
10
|
+
from briefing_sessions import social_sessions
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def inputs(a):
|
|
14
|
+
date = dt.date.fromisoformat(a['day']).isoformat()
|
|
15
|
+
zone = ZoneInfo(a['timezone'])
|
|
16
|
+
prepared = folder('selected_day')
|
|
17
|
+
if prepared != Path(a['prepared_day']).resolve():
|
|
18
|
+
raise ValueError('Method folders do not match the runtime tool bindings')
|
|
19
|
+
required = {
|
|
20
|
+
'selected_day': ['timeline.jsonl', 'untimed.jsonl', 'records/',
|
|
21
|
+
'metadata/documents.json'],
|
|
22
|
+
}
|
|
23
|
+
for which, names in required.items():
|
|
24
|
+
for name in names:
|
|
25
|
+
try:
|
|
26
|
+
path = local_path(which, name)
|
|
27
|
+
except FileNotFoundError:
|
|
28
|
+
raise ValueError(f'Missing required input: {which}/{name}') from None
|
|
29
|
+
if not (path.is_dir() if name.endswith('/') else path.is_file()):
|
|
30
|
+
raise ValueError(f'Expected a {"folder" if name.endswith("/") else "file"}: {which}/{name}')
|
|
31
|
+
for name in ['timeline.jsonl', 'untimed.jsonl']:
|
|
32
|
+
for row in map(json.loads, (prepared/name).read_text().splitlines()):
|
|
33
|
+
if row['date'] != date:
|
|
34
|
+
raise ValueError('Selected date does not match the prepared day')
|
|
35
|
+
if row.get('time'):
|
|
36
|
+
saved = dt.datetime.fromisoformat(row['time'])
|
|
37
|
+
local = saved.astimezone(zone)
|
|
38
|
+
if local.date().isoformat() != date or local.utcoffset() != saved.utcoffset():
|
|
39
|
+
raise ValueError('Selected timezone does not match the prepared times')
|
|
40
|
+
report = (Path(__file__).parent/'approved-report.md').read_text()
|
|
41
|
+
return {'selected_day': {'source_digest': source_digest(), 'folder': str(prepared), 'day': date, 'timezone': a['timezone'], 'start': 'timeline.jsonl'},
|
|
42
|
+
'session_links': '\n'.join('['+g['platform']+' '+g['start']+'–'+g['end']+'](sessions.html#'+g['id']+')' for g in social_sessions(prepared)),
|
|
43
|
+
'example': {'report': report}}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if __name__ == '__main__':
|
|
47
|
+
print(json.dumps(inputs(json.load(sys.stdin)), ensure_ascii=False))
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Read the example and selected day's files."""
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
ROOTS = {'selected_day', 'run'}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def folder(which):
|
|
11
|
+
if which not in ROOTS:
|
|
12
|
+
raise ValueError('Choose selected_day or run')
|
|
13
|
+
if which == 'run':
|
|
14
|
+
return Path(os.environ['METHOD_OUTPUT_DIR']).resolve(strict=True)
|
|
15
|
+
return Path(json.loads(os.environ['METHOD_ENVIRONMENT'])['prepared_day']).resolve(strict=True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def local_path(which, name):
|
|
19
|
+
root = folder(which)
|
|
20
|
+
path = (root / name).resolve(strict=True)
|
|
21
|
+
if not path.is_relative_to(root):
|
|
22
|
+
raise ValueError('Path is outside the selected folder')
|
|
23
|
+
return path
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def page(text, offset):
|
|
27
|
+
if not isinstance(offset, int) or not 0 <= offset <= len(text):
|
|
28
|
+
raise ValueError('Invalid character offset')
|
|
29
|
+
end = min(len(text), offset + 20000)
|
|
30
|
+
return {'content': text[offset:end], 'next_offset': end if end < len(text) else -1,
|
|
31
|
+
'total_chars': len(text)}
|